杰瑞科技汇

Java导出Excel,哪个JAR好用?

下面我将为你详细介绍这两个主流库,并提供详细的代码示例、优缺点对比以及 Maven/Gradle 依赖。

Java导出Excel,哪个JAR好用?-图1
(图片来源网络,侵删)

Apache POI (老牌、功能强大)

Apache POI 是 Apache 软件基金会的一个开源项目,它提供了 API 用于操作 Microsoft Office 格式的文件,如 .xls (Excel 97-2003) 和 .xlsx (Excel 2007+)。

优点:

  • 功能全面:几乎支持所有 Excel 的功能,包括单元格样式(字体、颜色、边框、对齐方式)、合并单元格、图表、图片、公式、数据验证等。
  • 历史悠久:社区庞大,文档和教程非常丰富,遇到问题容易找到解决方案。
  • 兼容性好:对旧版 .xls 格式支持良好。

缺点:

  • 内存消耗大:在处理大数据量(例如超过 1 万行)的 Excel 文件时,如果将整个文件读入内存,会导致 OutOfMemoryError(OOM),POI 提供了 SXSSF (Streaming Usermodel) 来解决此问题,但 API 会相对复杂一些。
  • API 相对繁琐:设置样式等操作代码量较多,代码不够简洁。

Maven 依赖

你需要根据你生成的 Excel 版本选择不同的依赖:

  • 生成 .xlsx (推荐)

    <dependency>
        <groupId>org.apache.poi</groupId>
        <artifactId>poi-ooxml</artifactId>
        <version>5.2.5</version> <!-- 建议使用较新版本 -->
    </dependency>
    <!-- 如果需要处理 XML,可能还需要这个 -->
    <dependency>
        <groupId>org.apache.poi</groupId>
        <artifactId>ooxml-lite</artifactId>
        <version>1.4</version>
    </dependency>
  • 生成 .xls (旧版格式)

    Java导出Excel,哪个JAR好用?-图2
    (图片来源网络,侵删)
    <dependency>
        <groupId>org.apache.poi</groupId>
        <artifactId>poi</artifactId>
        <version>5.2.5</version>
    </dependency>

代码示例 (生成 .xlsx 文件)

这个例子演示了如何创建一个工作簿,设置表头,填充数据,并应用一些基本样式。

import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
public class PoiExportExample {
    public static void main(String[] args) {
        // 1. 创建一个新的 Excel 工作簿 (XSSFWorkbook for .xlsx)
        Workbook workbook = new XSSFWorkbook();
        // 2. 创建一个工作表
        Sheet sheet = workbook.createSheet("员工信息");
        // 3. 创建表头样式
        CellStyle headerStyle = workbook.createCellStyle();
        Font headerFont = workbook.createFont();
        headerFont.setBold(true);
        headerFont.setColor(IndexedColors.WHITE.getIndex());
        headerStyle.setFont(headerFont);
        headerStyle.setFillForegroundColor(IndexedColors.GREY_50_PERCENT.getIndex());
        headerStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
        headerStyle.setAlignment(HorizontalAlignment.CENTER);
        // 4. 创建数据行样式
        CellStyle dataStyle = workbook.createCellStyle();
        dataStyle.setAlignment(HorizontalAlignment.CENTER);
        // 5. 创建表头行
        Row headerRow = sheet.createRow(0);
        String[] headers = {"ID", "姓名", "年龄", "部门", "入职日期"};
        for (int i = 0; i < headers.length; i++) {
            Cell cell = headerRow.createCell(i);
            cell.setCellValue(headers[i]);
            cell.setCellStyle(headerStyle);
        }
        // 6. 准备数据
        List<Object[]> dataList = new ArrayList<>();
        dataList.add(new Object[]{1, "张三", 28, "技术部", "2025-05-20"});
        dataList.add(new Object[]{2, "李四", 32, "市场部", "2025-08-15"});
        dataList.add(new Object[]{3, "王五", 25, "人事部", "2025-03-10"});
        dataList.add(new Object[]{4, "赵六", 30, "财务部", "2025-11-01"});
        // 7. 填充数据
        for (int i = 0; i < dataList.size(); i++) {
            Row dataRow = sheet.createRow(i + 1);
            Object[] rowData = dataList.get(i);
            for (int j = 0; j < rowData.length; j++) {
                Cell cell = dataRow.createCell(j);
                cell.setCellValue(String.valueOf(rowData[j]));
                cell.setCellStyle(dataStyle);
            }
        }
        // 8. 自动调整列宽
        for (int i = 0; i < headers.length; i++) {
            sheet.autoSizeColumn(i);
        }
        // 9. 写入文件
        try (FileOutputStream fileOut = new FileOutputStream("D:/temp/employees_poi.xlsx")) {
            workbook.write(fileOut);
            System.out.println("Excel 文件生成成功!");
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                workbook.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

EasyExcel (阿里巴巴出品,简单高效)

EasyExcel 是阿里巴巴开源的一个基于 Java 的、简单、省内存的 Excel 处理工具,它解决了 POI 在处理大数据量时的内存问题,API 更加简洁易用。

优点:

  • 节省内存:通过 SAX (Simple API for XML) 模式读取和写入,可以极大的降低内存占用,处理大数据量(百万行)时依然流畅。
  • API 简洁:注解式的 API,非常易于上手,代码量少。
  • 性能优秀:读写性能都非常好。
  • 功能丰富:支持 Excel 的常用功能,如头尾、合并单元格、数据转换、事件监听等。

缺点:

  • 功能相对 POI 稍弱:对于一些非常复杂的 Excel 布局和样式,可能不如 POI 灵活。
  • 社区相对较小:虽然发展很快,但遇到非常偏门的问题时,解决方案可能不如 POI 多。

Maven 依赖

<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>easyexcel</artifactId>
    <version>3.3.2</version> <!-- 建议使用较新版本 -->
</dependency>

代码示例 (生成 .xlsx 文件)

EasyExcel 的核心思想是 模型映射,你需要创建一个与 Excel 行对应的 Java 实体类,并使用 @ExcelProperty 注解来映射列。

步骤 1: 创建数据实体类

Java导出Excel,哪个JAR好用?-图3
(图片来源网络,侵删)
import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.annotation.write.style.ContentStyle;
import com.alibaba.excel.annotation.write.style.HeadStyle;
import com.alibaba.excel.enums.poi.HorizontalAlignmentEnum;
// 使用 HeadStyle 定义表头样式
@HeadStyle(fillForegroundColor = 13, horizontalAlignment = HorizontalAlignmentEnum.CENTER)
// 使用 ContentStyle 定义内容样式
@ContentStyle(horizontalAlignment = HorizontalAlignmentEnum.CENTER)
public class EmployeeData {
    // value 映射 Excel 中的列名,index 指定列的顺序
    @ExcelProperty(value = "ID", index = 0)
    private Integer id;
    @ExcelProperty(value = "姓名", index = 1)
    private String name;
    @ExcelProperty(value = "年龄", index = 2)
    private Integer age;
    @ExcelProperty(value = "部门", index = 3)
    private String department;
    @ExcelProperty(value = "入职日期", index = 4)
    private String joinDate;
    // 必须要有无参构造函数
    public EmployeeData() {
    }
    // getter 和 setter 方法
    public Integer getId() { return id; }
    public void setId(Integer id) { this.id = id; }
    public String getName() { return name; }
    public void setName(String name) { this.name = name; }
    public Integer getAge() { return age; }
    public void setAge(Integer age) { this.age = age; }
    public String getDepartment() { return department; }
    public void setDepartment(String department) { this.department = department; }
    public String getJoinDate() { return joinDate; }
    public void setJoinDate(String joinDate) { this.joinDate = joinDate; }
}

步骤 2: 编写导出逻辑

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.alibaba.excel.write.metadata.WriteTable;
import com.alibaba.excel.write.metadata.style.WriteCellStyle;
import com.alibaba.excel.write.metadata.style.WriteFont;
import com.alibaba.excel.write.style.HorizontalCellStyleStrategy;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.apache.poi.ss.usermodel.IndexedColors;
import java.util.ArrayList;
import java.util.List;
public class EasyExcelExportExample {
    public static void main(String[] args) {
        // 1. 准备数据
        List<EmployeeData> dataList = new ArrayList<>();
        dataList.add(new EmployeeData(1, "张三", 28, "技术部", "2025-05-20"));
        dataList.add(new EmployeeData(2, "李四", 32, "市场部", "2025-08-15"));
        dataList.add(new EmployeeData(3, "王五", 25, "人事部", "2025-03-10"));
        dataList.add(new EmployeeData(4, "赵六", 30, "财务部", "2025-11-01"));
        // 2. 设置样式策略 (可选,这里演示如何手动设置样式)
        WriteCellStyle headWriteCellStyle = new WriteCellStyle();
        headWriteCellStyle.setFillForegroundColor(IndexedColors.GREY_50_PERCENT.getIndex());
        WriteFont headWriteFont = new WriteFont();
        headWriteFont.setFontHeightInPoints((short)11);
        headWriteFont.setColor(IndexedColors.WHITE.getIndex());
        headWriteCellStyle.setWriteFont(headWriteFont);
        headWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);
        WriteCellStyle contentWriteCellStyle = new WriteCellStyle();
        contentWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);
        HorizontalCellStyleStrategy horizontalCellStyleStrategy = new HorizontalCellStyleStrategy(headWriteCellStyle, contentWriteCellStyle);
        // 3. 写入 Excel
        // fileName: 文件路径
        // sheet: 工作表名称
        // dataList: 数据列表
        String fileName = "D:/temp/employees_easy.xlsx";
        EasyExcel.write(fileName, EmployeeData.class)
                  .registerWriteHandler(horizontalCellStyleStrategy) // 注册样式处理器
                  .sheet("员工信息")
                  .doWrite(dataList);
        System.out.println("Excel 文件生成成功!");
    }
}

注意:EasyExcel 的注解式样式(如 @HeadStyle)和手动注册的样式处理器 registerWriteHandler 可以同时使用,后者优先级更高。


如何选择?

特性 Apache POI EasyExcel
内存占用 高 (大数据量易OOM) 极低 (大数据量优势明显)
API 复杂度 相对繁琐,代码量多 简洁,注解驱动,代码量少
功能全面性 非常全面,支持所有复杂功能 覆盖大部分常用功能,复杂场景可能力不从心
性能 一般 优秀
适用场景 - 需要处理复杂样式和布局
- 需要兼容旧版 .xls
- 项目已深度集成 POI
- 大数据量导出 (核心优势)
- 快速开发,追求简洁代码
- 新项目推荐首选

总结建议:

  • 新项目,特别是需要导出大数据量 Excel 的场景,强烈推荐使用 EasyExcel,它能让你用更少的代码,更低的内存消耗,完成导出任务。
  • 如果你的项目已经有历史包袱,或者需要实现一些非常复杂的、不常见的 Excel 样式和功能,Apache POI 是一个更可靠的选择。

除了这两个,还有一些其他的库,JXL (已经停止更新),但基本已经被 POI 和 EasyExcel 所取代,对于绝大多数 Java 掌握 POIEasyExcel 已经足够应对所有 Excel 导出需求了。

分享:
扫描分享到社交APP
上一篇
下一篇