根据Excel 模板生成excel(java)

重阳,需求很常见:根据一个已设计好的 Excel 模板(含样式、公式、合并单元格、表头、页眉页脚等),往里面填充动态数据,然后生成新的 Excel 文件

2026 年主流的三种方案对比(基于当前社区使用情况):

方案推荐指数 (2026)内存占用模板支持度(样式/合并/公式/图片)学习曲线大文件友好度Maven 依赖大小
EasyExcel (阿里)★★★★★极低优秀(支持复杂模板填充)★★★★★
Apache POI★★★★☆最好(几乎全能)★★☆☆☆
JXLS (基于 POI)★★★☆☆很好(Jxls 模板语法)★★★☆☆
Fastexcel / Spire.XLS★★☆☆☆低/中中等低/高★★★★☆小/商业

2026 年最推荐:EasyExcel
理由:内存友好、API 简洁、模板填充功能成熟、社区活跃、Spring Boot 集成极好。

下面直接给你 三种主流实现方式的完整代码示例(都基于 Spring Boot 项目场景)。

方案一:EasyExcel 模板填充(最推荐)

Maven 依赖(最新稳定版 3.x 或 4.x 系列,根据 2026 年情况用最新)

<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>easyexcel</artifactId>
    <version>3.3.4</version>  <!-- 或更高版本 -->
</dependency>

模板准备(excel 模板文件 template.xlsx)
在模板中用 {} 或自定义占位符,例如:

  • 单值:{date}{totalAmount}
  • 列表竖向填充:{.list} 或用 {{. 开头(EasyExcel 推荐语法)

示例模板内容(A1 放标题,A2 开始表头,B3 开始放 {name}{age} 等):

ABC
报表标题{title}
姓名年龄得分
{.students}

代码实现(Controller 或 Service 中)

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.write.enums.poi.HorizontalAlignment;
import com.alibaba.excel.write.enums.poi.VerticalAlignment;
import com.alibaba.excel.write.style.column.LongestMatchColumnWidthStyleStrategy;
import javax.servlet.http.HttpServletResponse;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.*;

@RestController
@RequestMapping("/excel")
public class ExcelController {

    @GetMapping("/export-template-fill")
    public void exportWithTemplate(HttpServletResponse response) throws Exception {
        // 1. 准备数据(可以从数据库查)
        Map<String, Object> data = new HashMap<>();
        data.put("title", "2026年班级成绩汇总");
        data.put("date", "2026-02-03");
        data.put("total", 88);

        List<Map<String, Object>> students = new ArrayList<>();
        students.add(Map.of("name", "张三", "age", 18, "score", 95));
        students.add(Map.of("name", "李四", "age", 19, "score", 88));
        students.add(Map.of("name", "王五", "age", 17, "score", 92));
        data.put("students", students);

        // 2. 设置响应头(浏览器下载)
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        response.setCharacterEncoding("utf-8");
        String fileName = URLEncoder.encode("成绩报表.xlsx", StandardCharsets.UTF_8.toString()).replaceAll("\\+", "%20");
        response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName);

        // 3. 模板路径(放在 resources/templates/ 下)
        String templateFileName = "templates/成绩模板.xlsx";

        // 4. 核心:模板填充写出
        EasyExcel.write(response.getOutputStream())
                .withTemplate(templateFileName)
                .registerWriteHandler(new LongestMatchColumnWidthStyleStrategy()) // 自适应列宽,可选
                .sheet()
                .doFill(data);  // ← 核心方法!传入 map 或对象
    }
}

高级用法提示(EasyExcel 模板填充常见技巧):

  • 列表横向填充:用 {{. 或指定方向
  • 多列表:多个 .list 占位符
  • 复杂对象:{.user.name} 点语法
  • 保留样式/公式/合并单元格:EasyExcel 会尽量保留
  • 图片填充:支持 FillWrapper + Image 对象

方案二:Apache POI 基于模板填充(最灵活,但内存高)

依赖

<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi-ooxml</artifactId>
    <version>5.3.0</version> <!-- 或更高 -->
</dependency>

核心代码片段

import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import java.io.FileInputStream;
import java.io.OutputStream;

// 加载模板
try (FileInputStream fis = new FileInputStream("template.xlsx");
     XSSFWorkbook workbook = new XSSFWorkbook(fis)) {

    var sheet = workbook.getSheetAt(0);

    // 填充单值
    sheet.getRow(1).getCell(1).setCellValue("2026-02-03 重阳");

    // 填充列表(从第3行开始)
    int rowIndex = 3;
    for (var student : students) {
        var row = sheet.getRow(rowIndex) != null ? sheet.getRow(rowIndex) : sheet.createRow(rowIndex);
        row.createCell(0).setCellValue(student.getName());
        row.createCell(1).setCellValue(student.getAge());
        rowIndex++;
    }

    // 输出到 response 或文件
    workbook.write(response.getOutputStream());
}

优点:可以精确控制每个单元格的样式、公式、批注、条件格式等。
缺点:代码量大,内存占用高(大文件容易 OOM)。

方案三:快速选择建议

场景首选方案
大数据量(万行+)EasyExcel
复杂样式/公式/图表保留Apache POI
需要极致灵活控制单元格Apache POI
快速上手、内存敏感EasyExcel
想用模板语法(如 {var})EasyExcel / JXLS

小建议

  1. 先准备好模板文件,占位符用 {}{{}}(EasyExcel 推荐)
  2. 测试时把模板放 resources/templates/ 下,用 classpath 加载
  3. 生产环境建议把模板上传到文件服务器或放在 jar 外

重阳,你现在是想:

  • 用 EasyExcel 做列表多sheet 填充?
  • 处理合并单元格 / 图片 / 下拉框?
  • 导出后自动调整列宽 / 加水印?
  • 还是遇到具体报错想 debug?

告诉我你的具体需求或模板样子,我可以给你更精确的代码~

文章已创建 4357

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

相关文章

开始在上面输入您的搜索词,然后按回车进行搜索。按ESC取消。

返回顶部