1. 概述

本文将介绍如何使用 Apache POI 库在 Kotlin 中读写 Excel 文件。这是一个非常常见的需求,比如导出报表、解析上传的表格数据等场景。掌握这套技术栈,能帮你少踩不少坑。

Apache POI 是 Java 生态中处理 Microsoft Office 文档的事实标准库,对 .xls.xlsx 格式都提供了良好支持。Kotlin 作为 JVM 语言,可以直接无缝集成。

2. Maven 依赖

Kotlin 本身不提供操作 Excel 的能力,必须借助第三方库。我们选择 Apache POI,它稳定、功能全、社区活跃。

需要引入以下两个核心依赖:

<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi</artifactId>
    <version>${apache.poi.version}</version>
</dependency>

<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi-ooxml</artifactId>
    <version>${apache.poi.version}</version>
</dependency>

📌 关键点说明:

  • poi:支持旧版二进制格式(.xls),基于 HSSF 模型。
  • poi-ooxml:支持新版 Office Open XML 格式(.xlsx),基于 XSSF 模型。
  • ⚠️ 要处理 .xlsx 文件,必须同时引入这两个依赖,否则会抛异常。
  • 🔗 最新版本可从 Maven Central 获取。

对应的核心类命名也体现了模型差异:

格式 工作簿 表单 单元格
.xls HSSFWorkbook HSSFSheet HSSFRow HSSFCell
.xlsx XSSFWorkbook XSSFSheet XSSFRow XSSFCell

实际开发中推荐优先使用 XSSF 系列类,毕竟 .xlsx 已成为主流。

3. 使用 Kotlin 读取 Excel 文件

读取 Excel 是常见需求,比如批量导入用户数据。下面是一个典型示例:

@Test
fun `when file is read then content is correct`() {
    val inputStream = this::class.java.getResourceAsStream("test_input.xlsx")
    val workbook = WorkbookFactory.create(inputStream)

    val workSheet = workbook.getSheetAt(0)
    assertThat(workSheet.getRow(0).getCell(0).stringCellValue).isEqualTo("TEST VALUE")
}

📌 流程拆解:

  1. ✅ 通过 getResourceAsStream 加载 classpath 下的测试文件(也可替换为 FileInputStream 读取磁盘路径)。
  2. ✅ 使用 WorkbookFactory.create() 自动识别文件类型并创建对应的工作簿实例 —— 这是推荐做法,无需手动判断格式。
  3. ✅ 获取第一个表单(Sheet),然后定位到第 0 行第 0 列单元格,验证其字符串值。

优点:API 直观,结构清晰,和 Java 几乎一致,迁移成本低。
注意:如果单元格为空或类型不匹配(如数字却调用 stringCellValue),可能抛异常,生产环境需做好类型判断和容错。

4. 使用 Kotlin 写入 Excel 文件

生成 Excel 报表也是高频场景。下面我们演示如何创建一个带样式的新文件:

@Test
fun `when file is created then content is correct`() {
    val workbook = XSSFWorkbook()
    val workSheet = workbook.createSheet()
    val cellStyle = workbook.createCellStyle()
    cellStyle.fillForegroundColor = IndexedColors.RED.getIndex()
    cellStyle.fillPattern = FillPatternType.SOLID_FOREGROUND
    val firstCell = workSheet
        .createRow(0)
        .createCell(0)
    firstCell.setCellValue("SAVED VALUE")
    firstCell.cellStyle = cellStyle

    val tempFile = createTempFile("test_output_", ".xlsx")
    workbook.write(tempFile.outputStream())
    workbook.close()

    val inputWorkbook = WorkbookFactory.create(tempFile.toFile().inputStream())
    val firstSheet = inputWorkbook.getSheetAt(0)
    assertThat(firstSheet.getRow(0).getCell(0).stringCellValue).isEqualTo("SAVED VALUE")
}

📌 关键步骤解析:

  • ✅ 创建 XSSFWorkbook 实例,表示一个全新的 .xlsx 文件。
  • ✅ 调用 createSheet() 添加默认表单。
  • ✅ 使用 createCellStyle() 定义单元格样式,并设置填充颜色为红色。
  • ✅ 构建行与单元格,赋值并绑定样式。
  • ✅ 将内容写入临时文件输出流。
  • ⚠️ **务必调用 workbook.close()**,否则资源无法释放,可能导致内存泄漏或文件写入不完整。
  • ✅ 最后通过重新读取验证内容正确性,适合测试场景。

💡 扩展建议:

  • 列级别样式可通过 XSSFSheet.setDefaultColumnStyle(colIndex, style) 统一设置。
  • 行级别样式可通过 XSSFRow.rowStyle 批量应用。
  • 复杂样式(字体、边框、对齐等)均可通过 CellStyle 配置。

这套 API 设计非常接近 Java 原生风格,Kotlin 开发者几乎零学习成本即可上手。

5. 总结

本文演示了如何在 Kotlin 项目中利用 Apache POI 实现 Excel 的读写操作:

  • ✅ 依赖清晰:poi + poi-ooxml 是处理 .xlsx 的黄金组合。
  • ✅ 读取简单:通过 WorkbookFactory.create() 统一入口,自动适配格式。
  • ✅ 写入灵活:支持丰富样式控制,满足报表美化需求。
  • ⚠️ 必须记得关闭 Workbook 资源,避免踩坑。
  • ✅ 整体实现简洁,与 Java 生态高度兼容,适合企业级应用集成。

对于需要处理 Excel 的 Kotlin 服务端项目,Apache POI 依然是首选方案。后续可以结合 Spring Boot 做自动化导出,提升开发效率。


原始标题:Read and Write to Excel With Kotlin