杰瑞科技汇

Java如何导出Excel2007?

为什么选择 Apache POI?

  • 成熟稳定:Apache POI 是一个老牌的开源项目,经过大量项目验证,非常稳定。
  • 功能全面:支持读写 Excel (.xls, .xlsx)、Word (.doc, .docx)、PowerPoint (.ppt, .pptx) 等多种 Office 格式。
  • 社区活跃:遇到问题很容易找到解决方案。
  • .xlsx 支持:使用其 XSSF (XML SpreadSheet Format) API 来专门处理 .xlsx 格式。

环境搭建 (Maven 依赖)

你需要在你的项目中添加 Apache POI 的依赖,对于 .xlsx 格式,我们主要需要 poi-ooxml 这个依赖。

Java如何导出Excel2007?-图1
(图片来源网络,侵删)

在你的 pom.xml 文件中添加以下内容:

<dependencies>
    <!-- 核心依赖 -->
    <dependency>
        <groupId>org.apache.poi</groupId>
        <artifactId>poi</artifactId>
        <version>5.2.5</version> <!-- 建议使用较新版本 -->
    </dependency>
    <!-- 用于处理 .xlsx 格式的核心依赖 -->
    <dependency>
        <groupId>org.apache.poi</groupId>
        <artifactId>poi-ooxml</artifactId>
        <version>5.2.5</version>
    </dependency>
    <!-- 用于处理 XML 的依赖,poi-ooxml 会自动引入,但明确写上更清晰 -->
    <dependency>
        <groupId>org.apache.poi</groupId>
        <artifactId>ooxml-schemas</artifactId>
        <version>1.4</version>
    </dependency>
    <!-- (可选) 如果涉及到日期格式化等,可能需要 commons-lang3 -->
    <dependency>
        <groupId>org.apache.commons</groupId>
        <artifactId>commons-lang3</artifactId>
        <version>3.12.0</version>
    </dependency>
</dependencies>

基础代码示例:导出简单的 Excel 表格

下面是一个最基础的示例,创建一个 .xlsx 文件,写入一些数据,并下载到浏览器。

1 核心类说明

  • XSSFWorkbook: 代表一个 .xlsx 格式的 Excel 工作簿。
  • XSSFSheet: 代表工作簿中的一张工作表。
  • XSSFRow: 代表工作表中的一行。
  • XSSFCell: 代表一行中的一个单元格。
  • XSSFCellStyle: 定义单元格的样式(如字体、颜色、边框、对齐方式等)。

2 完整代码示例

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

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 ExcelExportDemo {
    public static void main(String[] args) {
        // 1. 创建一个 Excel 工作簿
        Workbook workbook = new XSSFWorkbook();
        // 2. 创建一个工作表,名为 "用户数据"
        Sheet sheet = workbook.createSheet("用户数据");
        // 3. 创建标题行 (第一行)
        Row headerRow = sheet.createRow(0);
        // 4. 创建单元格并设置标题
        String[] headers = {"ID", "姓名", "年龄", "邮箱", "创建日期"};
        for (int i = 0; i < headers.length; i++) {
            Cell cell = headerRow.createCell(i);
            cell.setCellValue(headers[i]);
        }
        // 5. 准备一些数据
        List<Object[]> data = new ArrayList<>();
        data.add(new Object[]{1, "张三", 28, "zhangsan@example.com", "2025-10-27"});
        data.add(new Object[]{2, "李四", 32, "lisi@example.com", "2025-10-26"});
        data.add(new Object[]{3, "王五", 24, "wangwu@example.com", "2025-10-25"});
        data.add(new Object[]{4, "赵六", 45, "zhaoliu@example.com", "2025-10-24"});
        // 6. 写入数据行
        for (int i = 0; i < data.size(); i++) {
            Row dataRow = sheet.createRow(i + 1); // 从第二行开始
            Object[] rowData = data.get(i);
            for (int j = 0; j < rowData.length; j++) {
                Cell cell = dataRow.createCell(j);
                // 设置单元格值,可以根据类型优化
                cell.setCellValue(rowData[j].toString());
            }
        }
        // 7. 自动调整列宽,使内容显示完整
        for (int i = 0; i < headers.length; i++) {
            sheet.autoSizeColumn(i);
        }
        // 8. 将工作簿写入文件
        try (FileOutputStream fileOut = new FileOutputStream("users.xlsx")) {
            workbook.write(fileOut);
            System.out.println("Excel 文件 'users.xlsx' 已成功生成!");
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            // 9. 关闭工作簿,释放资源
            try {
                if (workbook != null) {
                    workbook.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

运行这段代码后,你会在项目根目录下生成一个 users.xlsx 文件,内容如下:

Java如何导出Excel2007?-图2
(图片来源网络,侵删)
ID 姓名 年龄 邮箱 创建日期
1 张三 28 zhangsan@example.com 2025-10-27
2 李四 32 lisi@example.com 2025-10-26
3 王五 24 wangwu@example.com 2025-10-25
4 赵六 45 zhaoliu@example.com 2025-10-24

进阶功能与最佳实践

1 设置单元格样式(字体、颜色、边框)

// 创建一个样式对象
CellStyle style = workbook.createCellStyle();
// 1. 设置字体
Font font = workbook.createFont();
font.setFontName("Arial");
font.setFontHeightInPoints((short) 12); // 字号
font.setBold(true); // 加粗
style.setFont(font);
// 2. 设置背景色
style.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex());
style.setFillPattern(FillPatternType.SOLID_FOREGROUND);
// 3. 设置边框
style.setBorderTop(BorderStyle.THIN);
style.setBorderBottom(BorderStyle.THIN);
style.setBorderLeft(BorderStyle.THIN);
style.setBorderRight(BorderStyle.THIN);
// 4. 设置对齐方式
style.setAlignment(HorizontalAlignment.CENTER); // 水平居中
style.setVerticalAlignment(VerticalAlignment.CENTER); // 垂直居中
// 将样式应用到单元格
Cell cell = headerRow.createCell(0);
cell.setCellValue("ID");
cell.setCellStyle(style);

2 处理日期格式

日期在 Excel 中需要特殊处理,否则会显示成一串数字。

// 创建日期格式
CreationHelper createHelper = workbook.getCreationHelper();
CellStyle dateStyle = workbook.createCellStyle();
dateStyle.setDataFormat(createHelper.createDataFormat().getFormat("yyyy-MM-dd HH:mm:ss"));
// 写入日期数据
Cell dateCell = dataRow.createCell(4);
// 假设 date 是一个 java.util.Date 对象
dateCell.setCellValue(new java.util.Date()); 
dateCell.setCellStyle(dateStyle);

3 在 Web 应用中下载(Spring Boot 示例)

这是最常见的应用场景,当用户点击“导出”按钮时,浏览器直接下载 Excel 文件,而不是在服务器上生成文件。

import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
@Controller
public class ExcelDownloadController {
    @GetMapping("/download")
    public void downloadExcel(HttpServletResponse response) throws IOException {
        // 1. 创建工作簿和数据 (同上)
        Workbook workbook = new XSSFWorkbook();
        Sheet sheet = workbook.createSheet("用户数据");
        // ... (填充表头和数据,可以复用上面的代码逻辑)
        // 2. 设置响应头
        String fileName = "用户列表_" + System.currentTimeMillis() + ".xlsx";
        // 处理中文文件名,防止乱码
        String encodedFileName = URLEncoder.encode(fileName, StandardCharsets.UTF_8);
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        response.setHeader("Content-Disposition", "attachment; filename=\"" + encodedFileName + "\"; filename*=utf-8''" + encodedFileName);
        // 3. 将 Excel 写入响应输出流
        try (ServletOutputStream outputStream = response.getOutputStream()) {
            workbook.write(outputStream);
            workbook.close();
        }
    }
}

大数据量导出优化(SXSSF)

如果需要导出的数据量非常大(比如几十万行),使用 XSSFWorkbook 会导致内存溢出(OOM),因为它会将所有数据都加载到内存中。

这时,你应该使用 SXSSF (Streaming Usermodel for XSSF),它的核心思想是将数据写入临时文件,只保留一部分在内存中,从而极大地降低内存消耗。

Java如何导出Excel2007?-图3
(图片来源网络,侵删)

1 SXSSF 与 XSSF 的主要区别

  • 内存友好SXSSFWorkbook 会创建一个临时的磁盘文件(poi-sxssf-sheet.xml),当内存中的行数超过一个阈值(rowAccessWindowSize)时,最旧的一行就会被“刷”到磁盘上,释放内存。
  • 只读SXSSF 是一个流式 API,一旦数据被写入磁盘并刷新,就不能再修改它。
  • API 兼容SXSSF 的 API 与 XSSF 高度兼容,大部分代码可以无缝切换。

2 SXSSF 示例

import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import java.io.FileOutputStream;
import java.io.IOException;
public class LargeDataExportDemo {
    public static void main(String[] args) throws IOException {
        // 1. 创建 SXSSFWorkbook,参数是内存中保留的行数,超过的会写入磁盘
        // 如果设置为 -1,则等同于 XSSFWorkbook,所有数据都在内存中
        Workbook workbook = new SXSSFWorkbook(100); // 内存中只保留100行
        Sheet sheet = workbook.createSheet("大数据表");
        // 2. 写入大量数据 (10 万行)
        for (int rownum = 0; rownum < 100000; rownum++) {
            Row row = sheet.createRow(rownum);
            for (int cellnum = 0; cellnum < 10; cellnum++) {
                Cell cell = row.createCell(cellnum);
                cell.setCellValue("Row " + rownum + ", Cell " + cellnum);
            }
            // 每 1000 行打印一次进度
            if (rownum % 1000 == 0) {
                System.out.println("已处理 " + rownum + " 行");
            }
        }
        // 3. 清理临时文件 (非常重要!)
        ((SXSSFWorkbook) workbook).dispose();
        // 4. 写入最终文件
        try (FileOutputStream out = new FileOutputStream("large_data.xlsx")) {
            workbook.write(out);
        }
        System.out.println("大数据 Excel 文件已生成!");
    }
}

注意:使用 SXSSFWorkbook 后,一定要在最后调用 dispose() 方法来删除所有临时文件,否则磁盘空间会被占满。


场景 推荐库 特点
导出 .xlsx 文件 XSSFWorkbook 功能全面,可读可写,适合中小数据量(万行以内)。
Web 下载 XSSFWorkbook + HttpServletResponse 标准做法,将内存中的 Excel 流式输出到浏览器。
大数据量导出 SXSSFWorkbook 内存友好,避免 OOM,适合几十万甚至上百万行数据。
读取 .xlsx 文件 XSSFWorkbook / SXSSFWorkbook 读取时,如果文件不大用 XSSFWorkbook;如果文件很大且需要快速读取,可以用 SXSSF 的只读模式。

希望这份详细的指南能帮助你掌握在 Java 中导出 Excel 2007 文件!

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