当前位置: 首页 > java >正文

Java 中导出 Excel 文件的方法

在 Java 中导出 Excel 文件的方法有多种,主要依赖不同的类库或工具,每种方法适用于不同的场景(如数据量大小、格式复杂度、易用性等)。以下是常见的几种实现方式:

选择建议
简单格式 + 小数据量:Apache POI(XSSF/HSSF)EasyExcel
复杂格式 + 中大数据量:EasyExcel(优先)或 POI + 自定义样式。
超大数据量(百万级):EasyExcel(默认优化)或 POISXSSF
固定模板报表:Freemarker/Thymeleaf 模板引擎。
纯数据导出(无格式):CSV 格式。

其中,EasyExcel 因易用性和性能优势,成为目前 Java 导出 Excel 的主流选择,尤其在业务系统中广泛应用。

一、基于 Apache POI(最常用)

Apache POI 是 Apache 基金会的开源项目,是 Java 处理 Microsoft Office 文档(包括 Excel)的主流工具,支持.xls(Excel 97-2003)和.xlsx(Excel 2007+)格式。

核心类
HSSF:处理 .xls 格式(最多 65536 行,适合小数据量)。
核心类:HSSFWorkbook(文档)、HSSFSheet(工作表)、HSSFRow(行)、HSSFCell(单元格)。

XSSF:处理 .xlsx 格式(支持百万级行,适合中大数据量)。
核心类:XSSFWorkbook、XSSFSheet、XSSFRow、XSSFCell。

SXSSF:XSSF的扩展,支持大数据量导出(通过内存优化,适合十万级以上数据,避免 OOM)。

优点
功能全面,支持复杂格式(单元格样式、合并单元格、公式、图表等)。
兼容性好,支持所有 Excel 版本。

缺点
代码相对繁琐,需要手动创建行、单元格并设置样式。
处理大数据时(如十万级以上),XSSF 可能占用较多内存(需用 SXSSF 优化)。

示例代码片段(XSSF)

// 创建.xlsx文档
XSSFWorkbook workbook = new XSSFWorkbook();
XSSFSheet sheet = workbook.createSheet("Sheet1");// 创建标题行
XSSFRow row = sheet.createRow(0);
row.createCell(0).setCellValue("姓名");
row.createCell(1).setCellValue("年龄");// 填充数据
XSSFRow dataRow = sheet.createRow(1);
dataRow.createCell(0).setCellValue("张三");
dataRow.createCell(1).setCellValue(25);// 输出到文件或响应流
FileOutputStream fos = new FileOutputStream("test.xlsx");
workbook.write(fos);
fos.close();
workbook.close();

二、基于 Alibaba EasyExcel

EasyExcel 是阿里巴巴开源的 Excel 处理工具,基于 POI 封装,专注于简化代码和优化大数据量性能,避免 POI 的内存占用问题。

核心特点
注解驱动:通过@ExcelProperty等注解映射 Java 对象与 Excel 列,无需手动创建单元格。
低内存:默认采用 SXSSF 的内存优化机制,支持百万级数据导出。
支持复杂格式:合并单元格、表头样式、自定义转换器等。

优点
代码简洁,无需手动处理行和单元格,降低开发成本。
性能优异,适合大数据量导出(如报表、日志数据)。

缺点
高级格式(如公式、图表)支持较弱,复杂场景仍需结合 POI。

示例代码片段

// 定义数据模型(通过注解映射Excel列)
@Data
public class User {@ExcelProperty("姓名")private String name;@ExcelProperty("年龄")private Integer age;
}// 导出逻辑
List<User> data = new ArrayList<>();
data.add(new User("卡布大帝", 25));// 输出到文件
EasyExcel.write("test_easy.xlsx", User.class).sheet("Sheet1").doWrite(data);

三、基于 JXL(仅支持.xls)

JXL(Java Excel API) 是早期的 Excel 处理工具,仅支持 .xls 格式(不支持.xlsx),目前已停止维护,逐渐被 POI 替代。

优点
轻量级,API 简单,适合简单的.xls 文件导出。

缺点
不支持.xlsx 格式,功能有限(如不支持公式、图表),且不再更新。

示例代码片段

// 创建.xls文档
WritableWorkbook workbook = Workbook.createWorkbook(new File("test_jxl.xls"));
WritableSheet sheet = workbook.createSheet("Sheet1", 0);// 标题行
Label nameLabel = new Label(0, 0, "姓名");
Label ageLabel = new Label(1, 0, "年龄");
sheet.addCell(nameLabel);
sheet.addCell(ageLabel);// 数据行
Label name = new Label(0, 1, "张三");
Number age = new Number(1, 1, 25);
sheet.addCell(name);
sheet.addCell(age);workbook.write();
workbook.close();

四、基于模板引擎(如 Freemarker、Thymeleaf)

通过Excel 模板(如.xlsx模板)结合模板引擎,动态填充数据后导出。适用于格式固定、样式复杂的报表(如财务报表、合同模板)。

原理
准备 Excel 模板,用占位符(如${name})标记需要填充的位置。
用模板引擎解析模板,替换占位符为实际数据。
生成最终 Excel 文件。

优点
样式与逻辑分离,模板可由非开发人员(如运营)维护。
适合复杂格式报表,无需代码中手动设置样式。

缺点
灵活性较低,模板变更需同步更新占位符。
大数据量场景性能较差。

示例(Freemarker)
模板文件(template.xlsx.ftl)中单元格设置为 ${user.name}。
代码填充数据:

Configuration cfg = new Configuration(Configuration.VERSION_2_3_31);
cfg.setDirectoryForTemplateLoading(new File("templates"));
Template template = cfg.getTemplate("template.xlsx.ftl");Map<String, Object> data = new HashMap<>();
data.put("user", new User("张三", 25));FileOutputStream fos = new FileOutputStream("report.xlsx");
template.process(data, new OutputStreamWriter(fos));
fos.close();

五、基于 CSV 格式(伪 Excel)

CSV(逗号分隔值)是一种简单的文本格式,可被 Excel 直接打开,适合纯数据导出(无格式要求)。

优点
实现简单,无需依赖任何 Excel 类库。
生成速度快,适合超大数据量(如千万级)。

缺点
不支持任何样式(如单元格合并、颜色、公式),仅能存储纯文本数据。

示例代码片段

FileWriter writer = new FileWriter("data.csv");
// 标题行
writer.write("姓名,年龄\n");
// 数据行
writer.write("张三,25\n");
writer.write("李四,30\n");
writer.close();

六、其他工具

Alibaba EasyExcel:如前文所述,是 POI 的优化封装,推荐优先使用。
Aspose.Cells:商业工具,功能强大(支持所有 Excel 特性),但需要付费授权,适合企业级复杂场景。
JXLS:结合 POI 和模板引擎,通过标签(如jx:each)在 Excel 模板中循环填充数据,适合动态报表。

http://www.xdnf.cn/news/17846.html

相关文章:

  • 本地jar导入到本地仓科和远程仓库
  • [ HTML 前端 ] 语法介绍和HBuilderX安装
  • Spring Boot 3中JWT密钥安全存储方案
  • 图灵测试:人工智能的“行为主义判据”与哲学争议
  • 论,物联网日志系统架构如何设计?
  • 使用colmap自制3DGaussian_Splatting数据集
  • Java进阶学习之Stream流的基本概念以及使用技巧
  • 第四天~在CANFD或CAN2.0的ARXML文件中实现Multiplexor多路复用信号实战
  • 3D-R1、Scene-R1、SpaceR论文解读
  • Codeforces Round 1042 (Div. 3)
  • Ansys FreeFlow入门:对搅拌罐进行建模
  • vector 认识及使用
  • 【论文阅读-Part1】PIKE-RAG: sPecIalized KnowledgE and Rationale Augmented Generation
  • 如何通过WiFi将文件从安卓设备传输到电脑
  • Scrapy 基础框架搭建教程:从环境配置到爬虫实现(附实例)
  • Pytorch在FSDP模型中使用EMA
  • 考研408《计算机组成原理》复习笔记,第四章(3)——指令集、汇编语言
  • 14、C 语言联合体和枚举知识点总结
  • Linux系统Namespace隔离实战:dd/mkfs/mount/unshare命令组合应用
  • 报数游戏(我将每文更新tips)
  • 2022 年全国硕士研究生招生考试真题笔记
  • 杂记 01
  • elasticsearch基础概念与集群部署
  • Blender模拟结构光3D Scanner(一)外参数匹配
  • ARM芯片架构之CoreSight Channel Interface 介绍
  • 20250813测试开发岗(凉)面
  • Spring Security 前后端分离场景下的会话并发管理
  • 商品分类拖拽排序设计
  • 数据结构:队列(Queue)与循环队列(Circular Queue)
  • 【SpringBoot系列-01】Spring Boot 启动原理深度解析