java

关注公众号 jb51net

关闭
首页 > 软件编程 > java > SpringBoot EasyExcel数据报表导出

SpringBoot后台使用EasyExcel实现数据报表导出(含模板、样式、美化)

作者:冼紫菜

在企业级系统中,数据导出 Excel 是非常常见的需求,本文基于实际项目经验,分享如何使用 EasyExcel 实现复杂报表导出,包含支持按天/按小时导出数据、支持多 Sheet、多段写入等,下面小编给大家详细说说,需要的朋友可以参考下

引言

在企业级系统中,数据导出 Excel 是非常常见的需求。本文基于实际项目经验,分享如何使用 EasyExcel 实现复杂报表导出,包含:

一、数据报表导出常见场景

二、常用 Excel 导出方案对比

技术方案特点优缺点说明
Apache POI功能强大,支持复杂格式复杂笨重、内存占用高
JXL轻量级不支持 Excel 2007+(.xlsx)
EasyExcel(推荐)阿里开源,流式处理,速度快对模板语法有一定学习成本
CSV 导出简单快速不支持样式、格式、合并单元格等

三、为什么选择 EasyExcel?

四、EasyExcel 使用详解

1、基本写法

EasyExcel.write(outputStream, MyData.class)
         .sheet("报表")
         .doWrite(dataList);

2、使用模板导出(推荐)

ExcelWriter writer = EasyExcel
        .write(outputStream, MyData.class)
        .withTemplate(templateInputStream)
        .build();
 
WriteSheet sheet = EasyExcel.writerSheet().build();
writer.fill(variableMap, sheet);      // 填充 {{变量}}
writer.write(dataList, sheet);        // 填充数据区域 {}
writer.finish();

五、样式注解介绍

EasyExcel 提供了丰富的注解用于设置单元格样式,无需写 handler:

@ColumnWidth(15)
@ContentStyle(
    fillPatternType = FillPatternTypeEnum.SOLID_FOREGROUND,
    fillForegroundColor = 42,
    verticalAlignment = VerticalAlignmentEnum.CENTER,
    horizontalAlignment = HorizontalAlignmentEnum.CENTER
)
@ContentFontStyle(
    fontName = "宋体",
    fontHeightInPoints = 12,
    bold = BooleanEnum.TRUE
)
@Data
public class StatisticsData {
    private String statTime;
    private String regionName;
    private Integer userCount;
    private BigDecimal amount;
}

解释:

六、Excel 模板导出详解

为什么使用模板?

使用模板导出可以:

模板示例结构

A列B列C列
统计时间:{{startTime}} ~ {{endTime}}
当前时间:{{currentTime}}
月份:{{month}}
日期用户数销售额
{data}
月汇总:{monthAggregation}

Java 填充代码

ExcelWriter excelWriter = EasyExcel
    .write(response.getOutputStream(), StatisticsData.class)
    .withTemplate(getClass().getClassLoader().getResourceAsStream("static/day_statistics_template.xlsx"))
    .autoCloseStream(false)
    .registerWriteHandler(easyExcelUtil)
    .build();
 
Map<String, Object> map = new HashMap<>();
map.put("startTime", "2025-01-01");
map.put("endTime", "2025-01-31");
map.put("currentTime", "2025/05/04 10:00:00");
excelWriter.fill(map, writeSheet);
 
excelWriter.write(dataList, writeSheet); // 支持多段填充
excelWriter.finish();

七、项目实战关键代码讲解

数据导出主入口

@Override
public void downloadStatistics(LocalDateTime minTime, LocalDateTime maxTime) throws IOException {
    // 校验时间范围
    if (LocalDateTimeUtil.between(minTime, maxTime, ChronoUnit.DAYS) > 365) {
        throw new ForbiddenOperationException("查询时间区间不能超过一年");
    }
 
    HttpServletResponse response = ResponseUtils.getResponse();
    response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
    response.setCharacterEncoding("utf-8");
    response.setHeader(BODY_PROCESSED, "1");
 
    try {
        if (LocalDateTimeUtil.beginOfDay(maxTime).equals(minTime)) {
            downloadHourStatisticsData(response, minTime); // 按小时导出
        } else {
            downloadDayStatisticsData(response, minTime, maxTime); // 按天导出
        }
    } catch (Exception e) {
        response.reset();
        response.setContentType("application/json");
        response.getWriter().println(JSON.toJSONString(Map.of(
            "status", "failure",
            "message", "下载失败: " + e.getMessage()
        )));
    }
}

按月分组聚合逻辑

private List<ExcelMonthData> cutDataListByMonth(List<StatisticsData> statisticsDataList) {
    LocalDateTime minTime = LocalDateTimeUtil.parse(statisticsDataList.get(0).getStatTime(), DatePattern.PURE_DATE_PATTERN);
    LocalDateTime maxTime = LocalDateTimeUtil.parse(statisticsDataList.get(statisticsDataList.size() - 1).getStatTime(), DatePattern.PURE_DATE_PATTERN);
 
    Map<String, List<StatisticsData>> collect = statisticsDataList.stream()
        .collect(Collectors.groupingBy(s -> s.getStatTime().substring(0, 6)));
 
    List<ExcelMonthData> result = new ArrayList<>();
    while (!minTime.isAfter(maxTime)) {
        String monthKey = LocalDateTimeUtil.format(minTime, "yyyyMM");
        List<StatisticsData> monthList = collect.getOrDefault(monthKey, new ArrayList<>());
 
        monthList.forEach(s -> s.setStatTime(excelDateFormatter(s.getStatTime())));
        AggregationStatisticsData monthSummary = getAggregationStatisticsData(monthList, "月统计");
 
        ExcelMonthData data = new ExcelMonthData();
        data.setMonth(minTime.getMonthValue() + "月");
        data.setStatisticsDataList(monthList);
        data.setMonthAggregation(monthSummary);
        result.add(data);
 
        minTime = minTime.plusMonths(1);
    }
    return result;
}

八、总结与建议

优势建议
EasyExcel 写入快、内存占用低强烈建议使用模板填充,提升开发效率
支持注解设置样式、美化单元格可结合注解 + WriteHandler 灵活使用
模板导出适合企业复杂格式报表模板和样式提前设计好,开发更轻松

以上就是SpringBoot后台使用EasyExcel实现数据报表导出(含模板、样式、美化)的详细内容,更多关于SpringBoot EasyExcel数据报表导出的资料请关注脚本之家其它相关文章!

您可能感兴趣的文章:
阅读全文