POI 讲解

一、POI 是什么?

Apache POI 是 Apache 基金会提供的一套 Java 操作 Office 文档的开源库,主要支持:

  • Excel(.xls / .xlsx)
  • Word(.doc / .docx)
  • PowerPoint
  • Visio
  • Outlook

其中最常用的就是 Excel 操作

二、为什么要用 POI?

因为在企业开发中,Excel 是最常见的数据交换格式,比如:

  • 导出报表(订单报表、财务报表)
  • 导入数据(批量导入用户、批量导入商品)
  • 模板导出(固定模板 + 动态数据)
  • 数据备份
  • 批量生成合同、发票等文档

Java 本身没有提供操作 Excel 的能力,所以必须依赖 POI。

三、POI 支持的 Excel 格式

POI 支持两种 Excel 格式:

  1. HSSF ------ 操作 .xls(Excel 97-2003)

    • 最多 65536 行
    • 最多 256 列
  2. XSSF ------ 操作 .xlsx(Excel 2007+)

    • 最多 1,048,576 行
    • 最多 16,384 列
    • 推荐使用
  3. SXSSF ------ 大数据量导出(百万级)

    • 基于 XSSF,但使用 流式处理
    • 适合导出几十万、几百万行数据
    • 内存占用极低

四、POI 核心对象模型

POI 操作 Excel 的核心对象如下(非常重要):

  • Workbook(工作簿) → 对应整个 Excel 文件 ,创建 / 读取 Excel 的入口对象
    • XSSF 格式:XSSFWorkbook workbook = new XSSFWorkbook();
  • Sheet(工作表) → 对应 Excel 里的一个 sheet 页签 ,一个 Workbook 可以创建多个 Sheet
    • 创建:Sheet sheet = workbook.createSheet("用户报表");
    • 获取:Sheet sheet = workbook.getSheetAt(0); // 获取第一个 sheet
  • Row(行) → 对应 Sheet 中的一行数据 ,行索引从0开始(0 是表头行)
    • 创建:Row row = sheet.createRow(0); // 创建第 1 行
    • 获取:Row row = sheet.getRow(1); // 获取第 2 行
  • Cell(单元格) → 对应 Row 中的一个单元格 ,列索引从0开始
    • 创建:Cell cell = row.createCell(0); // 创建当前行的第 1 列单元格
    • 获取:Cell cell = row.getCell(1); // 获取当前行的第 2 列单元格
  • 辅助对象:CellStyle(单元格样式)、Font(字体样式)→ 用于设置单元格的字体、颜色、对齐方式、边框等
  • 核心层级关系:Workbook → Sheet → Row → Cell

五、POI 读写 Excel 实战

引入依赖:

java 复制代码
<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi-ooxml</artifactId>
    <version>4.1.2</version>
</dependency>

写入 Excel(导出)

java 复制代码
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

import java.io.FileOutputStream;
import java.io.IOException;

public class ExcelWriter {
    public static void main(String[] args) throws IOException {
        // 1. 创建 Workbook
        Workbook workbook = new XSSFWorkbook();

        // 2. 创建 Sheet
        Sheet sheet = workbook.createSheet("用户列表");

        // 3. 创建表头行
        Row headerRow = sheet.createRow(0);
        headerRow.createCell(0).setCellValue("ID");
        headerRow.createCell(1).setCellValue("姓名");
        headerRow.createCell(2).setCellValue("年龄");

        // 4. 写入数据
        Object[][] data = {
                {1, "张三", 20},
                {2, "李四", 22},
                {3, "王五", 25}
        };

        int rowIndex = 1;
        for (Object[] rowData : data) {
            Row row = sheet.createRow(rowIndex++);
            row.createCell(0).setCellValue((Integer) rowData[0]);
            row.createCell(1).setCellValue((String) rowData[1]);
            row.createCell(2).setCellValue((Integer) rowData[2]);
        }

        // 5. 输出到文件
        try (FileOutputStream outputStream = new FileOutputStream("users.xlsx")) {
            workbook.write(outputStream);
        }

        System.out.println("Excel 生成成功!");
    }
}

读取 Excel(导入)

java 复制代码
import org.apache.poi.ss.usermodel.*;

import java.io.FileInputStream;
import java.io.IOException;

public class ExcelReader {
    public static void main(String[] args) throws IOException {
        // 1. 读取文件
        try (FileInputStream inputStream = new FileInputStream("users.xlsx");
             Workbook workbook = new XSSFWorkbook(inputStream)) {

            // 2. 获取 Sheet
            Sheet sheet = workbook.getSheetAt(0);

            // 3. 遍历行
            for (Row row : sheet) {
                // 4. 遍历单元格
                for (Cell cell : row) {
                    // 根据单元格类型读取数据
                    switch (cell.getCellType()) {
                        case STRING:
                            System.out.print(cell.getStringCellValue() + "\t");
                            break;
                        case NUMERIC:
                            System.out.print(cell.getNumericCellValue() + "\t");
                            break;
                        case BOOLEAN:
                            System.out.print(cell.getBooleanCellValue() + "\t");
                            break;
                        default:
                            System.out.print("\t");
                    }
                }
                System.out.println();
            }
        }
    }
}
相关推荐
海鸥812 小时前
ArgoCD App of Apps 模式详解
java·elasticsearch·argocd
二哈喇子!2 小时前
面向对象经典题整理
java·面向对象·
二哈喇子!2 小时前
模仿淘宝购物系统的Java Web前端项目(开源项目)
java·javaweb
二哈喇子!2 小时前
Java Web项目怎么创建 & 没有出现web.xml的解决方法
java·web·web.xml
一起养小猫2 小时前
LeetCode100天Day13-移除元素与多数元素
java·算法·leetcode
小北方城市网3 小时前
Spring Security 认证授权实战(JWT 版):从基础配置到权限精细化控制
java·运维·python·微服务·排序算法·数据库架构
青槿吖3 小时前
Java 集合操作:HashSet、LinkedHashSet 和 TreeSet
java·开发语言·jvm
刘联其3 小时前
Prism Region注册父子区域 子区域初始化导航没生效解决
java·开发语言
二哈喇子!3 小时前
controller & service & dao之间的关系
java·eclipse·intellij-idea