Java 利用easypoi处理Excel导出固定模板

一、pom

<dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>easyexcel</artifactId>
            <version>3.0.5</version>
        </dependency>

二、excel模板

image

 三、demo

3.1 实体

import com.alibaba.excel.annotation.ExcelProperty;
import lombok.Data;

import java.math.BigDecimal;

/**
 * 订单数据模型(对应模板中循环列表的 item 属性)
 */
@Data
public class OrderDTO {
    // 订单编号(对应模板 {.orderNo})
    @ExcelProperty("orderNo")
    private String orderNo;

    // 商品名称(对应模板 {.productName})
    @ExcelProperty("productName")
    private String productName;

    // 购买数量(对应模板 {.quantity})
    @ExcelProperty("quantity")
    private Integer quantity;

    // 订单金额(对应模板 {.amount})
    @ExcelProperty("amount")
    private BigDecimal amount;
}

3.2、工具类

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.metadata.WriteSheet;

import java.io.InputStream;
import java.util.List;
import java.util.Map;

/**
 * EasyExcel 模板导出工具类(3.0.5 版本)
 */
public class ExcelTemplateExportUtil {

    /**
     * 模板导出(支持单条数据 + 列表数据)
     *
     * @param templatePath 模板路径(resources 下的路径,如 "templates/template.xlsx")
     * @param outputPath   导出文件路径(如 "D:/导出结果.xlsx")
     * @param singleData   单条数据(对应模板 ${变量名})
     * @param listKey      列表数据的 key(对应模板 #foreach($item in $listKey))
     * @param listData     列表数据(循环导出的数据集合)
     */
    public static <T> void exportWithTemplate(
            String templatePath,
            String outputPath,
            Map<String, Object> singleData,
            String listKey,
            List<T> listData
    ) {
        // 1. 获取模板输入流(从 resources 读取)
        InputStream templateInputStream = ExcelTemplateExportUtil.class.getClassLoader().getResourceAsStream(templatePath);
        if (templateInputStream == null) {
            throw new RuntimeException("模板文件不存在:" + templatePath);
        }

        // 2. 构建 ExcelWriter(模板模式)
        ExcelWriter excelWriter = EasyExcel.write(outputPath)
                .withTemplate(templateInputStream) // 绑定模板
                .build();

        try {
            // 3. 创建 WriteSheet(默认第 0 个工作表)
            WriteSheet writeSheet = EasyExcel.writerSheet().build();

            // 4. 填充单条数据(如导出时间、标题等)
            if (singleData != null && !singleData.isEmpty()) {
                excelWriter.fill(singleData, writeSheet);
            }

            // 5. 填充列表数据(循环数据)
            if (listData != null && !listData.isEmpty()) {
                excelWriter.fill(listData, writeSheet);
            }

        } finally {
            // 6. 关闭流(必须关闭,否则文件损坏)
            if (excelWriter != null) {
                excelWriter.finish();
            }
        }
    }
}

3.3、测试

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class ExcelExportTest {

    public static void main(String[] args) {
        // 1. 准备单条数据(对应模板 ${exportTime})
        Map<String, Object> singleData = new HashMap<>();
        singleData.put("exportTime", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));

        // 2. 准备列表数据(订单列表)
        List<OrderDTO> orderList = new ArrayList<>();
        OrderDTO order1 = new OrderDTO();
        order1.setOrderNo("ORDER_2025001");
        order1.setProductName("Java编程思想");
        order1.setQuantity(2);
        order1.setAmount(new BigDecimal("198.00"));

        OrderDTO order2 = new OrderDTO();
        order2.setOrderNo("ORDER_2025002");
        order2.setProductName("SpringBoot实战");
        order2.setQuantity(1);
        order2.setAmount(new BigDecimal("89.00"));

        orderList.add(order1);
        orderList.add(order2);

        // 3. 调用工具类导出
        try {
            ExcelTemplateExportUtil.exportWithTemplate(
                    "doubao.xlsx", // 模板路径(resources下)
                    "D:/订单报表.xlsx",         // 导出路径
                    singleData,                // 单条数据
                    "orderList",               // 列表key(对应模板 $orderList)
                    orderList                  // 列表数据
            );
            System.out.println("导出成功!");
        } catch (Exception e) {
            System.err.println("导出失败:" + e.getMessage());
            e.printStackTrace();
        }
    }
}

 

posted @ 2025-11-18 17:37  都是城市惹的祸  阅读(51)  评论(0)    收藏  举报