Ubuntu 22.04 安装 Apache POI 5.5.1 指南

Ubuntu 22.04 上安装 Apache POI 5.5.1 开发环境(OpenJDK 17 + Maven 3.6.3),建立 Maven 工程引入 poi-ooxml 依赖并完成 xlsx 写读编译验证,附 JVM 堆内存配置与常见问题排障。

Apache POIApache POI2026/10/11

Ubuntu 22.04 安装 Apache POI 5.5.1 指南

目标:在 Ubuntu 22.04 服务器上安装 Apache POI 5.5.1(Java 操作 OLE2/OOXML 文档库)的完整开发环境,建立 Maven 工程引入 poi-ooxml:5.5.1 依赖并完成 Excel(.xlsx) 写读的编译与运行验证。已在 Ubuntu 22.04.5、OpenJDK 17.0.20.1、Maven 3.6.3 环境实测通过。

一、环境信息

  • 操作系统:Ubuntu 22.04.5 LTS
  • 架构:x86_64
  • Java:OpenJDK 17.0.20.1(headless,仅命令行运行,无需图形界面)
  • 构建工具:Apache Maven 3.6.3(Maven home: /usr/share/maven)
  • 辅助工具:wget(/usr/bin/wget)
  • 运行账号:root
  • 目标库:Apache POI 5.5.1(Java SDK,Maven 引入,无独立守护进程)
  • 工程位置:/opt/data/poi-demo/
  • 输出文件:/tmp/demo.xlsx

💡 说明:Apache POI 是一个 Java 类库(SDK),不是常驻服务进程,因此不存在"启动/停止服务"概念;其"安装"等价于把 JDK + Maven + POI 依赖准备就绪并能被 Java 程序引用编译运行。

二、前置条件

2.1 网络与软件源

  • 服务器可访问 apt 软件源(Ubuntu 官方源)用于安装 JDK / Maven / wget。
  • 编译与下载依赖需要访问 Maven Central(repo1.maven.org)或公司内网 Maven 镜像仓库。

2.2 系统更新

安装前先刷新软件包索引,并确认已具备编译所需工具链:

apt-get update -qq

⚠️ 若需安装 openjdk-17-jdk、maven 之外的编译辅助工具,可一并 apt-get install。

三、版本选型说明

3.1 当前最新稳定版

Apache POI 官方发布线 https://dlcdn.apache.org/poi/release/RELEASE-NOTES.txt 明确当前最新稳定版为 5.5.1(属于 5.5.x 系列,为 bug fix 版本)。

The Apache POI project is pleased to announce the release of POI 5.5.1.
This is primarily a bug fix release.
...
Pre-built versions of all POI components are also available in the central Maven repository
under Group ID "org.apache.poi" and Version "5.5.1"

3.2 Maven Central 全量稳定版清单

Maven Central 目录 https://repo1.maven.org/maven2/org/apache/poi/poi-ooxml/ 下共 19 个稳定版:

3.10.1, 4.0.0, 4.0.1, 4.1.0, 4.1.1, 4.1.2,
5.0.0, 5.1.0, 5.2.0, 5.2.1, 5.2.2, 5.2.3, 5.2.4, 5.2.5,
5.3.0, 5.4.0, 5.4.1, 5.5.0, 5.5.1

3.3 版本选择结论

  • 推荐版本:5.5.1(当前最新稳定版,dlcdn 与 Maven Central 双重确认)。
  • 截至 2026-10-11 无 6.x 系列,5.5.x 即当前最新稳定线。
  • JDK 要求:POI 5.5.x 需 JDK 8+(官网 RELEASE-NOTES 载明 "build all POI components with JDK 1.8 or higher");本指南采用 JDK 17。

四、部署步骤

4.1 安装 JDK、Maven 与 wget

一次装入编译所需组件(均来自 apt,实测成功):

apt-get install -y -qq openjdk-17-jdk-headless maven wget

验证 Java 版本:

java -version

真实回显:

openjdk version "17.0.20.1" 2026-08-18
OpenJDK Runtime Environment (build 17.0.20.1+1-1-22.04-Ubuntu)
OpenJDK 64-Bit Server VM (build 17.0.20.1+1-1-22.04-Ubuntu, mixed mode, sharing)

验证 Maven 版本:

mvn -version

真实回显:

Apache Maven 3.6.3
Maven home: /usr/share/maven
Java version: 17.0.20.1, vendor: Ubuntu, runtime: /usr/lib/jvm/java-17-openjdk-amd64
Default locale: en_US, platform encoding: ANSI_X3.4-1968

4.2 建立 Maven 工程并引入 POI 依赖

创建工程目录:

mkdir -p /opt/data/poi-demo/src/main/java

编写 /opt/data/poi-demo/pom.xml,仅引入唯一依赖 poi-ooxml:5.5.1(POI 的 .xlsx/.xlsm/Word/Doc 等 OOXML 支持均由该构件提供,其余第三方依赖由 Maven 自动传递引入):

<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.example</groupId>
  <artifactId>poi-demo</artifactId>
  <version>1.0</version>
  <packaging>jar</packaging>
  <properties>
    <maven.compiler.source>17</maven.compiler.source>
    <maven.compiler.target>17</maven.compiler.target>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>
  <dependencies>
    <dependency>
      <groupId>org.apache.poi</groupId>
      <artifactId>poi-ooxml</artifactId>
      <version>5.5.1</version>
    </dependency>
  </dependencies>
</project>

💡 说明:POI 5.x 不再依赖旧的 poi-ooxml-schemas 构件,改由 poi-ooxml-lite 承载精简 schema 类,Maven 自动传递引入,无需手工声明。

4.3 编写最小写读验证类

编写 /opt/data/poi-demo/src/main/java/PoiXlsxDemo.java:

import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;

/** 演示: XSSFWorkbook 在内存中创建 .xlsx 写入, 再用 FileInputStream 读回打印 */
public class PoiXlsxDemo {
    public static void main(String[] args) throws Exception {
        String path = "/tmp/demo.xlsx";

        // ===== 写 =====
        try (Workbook wb = new XSSFWorkbook()) {
            Sheet sheet = wb.createSheet("Demo");
            Row header = sheet.createRow(0);
            header.createCell(0).setCellValue("Name");
            header.createCell(1).setCellValue("Value");
            Row row = sheet.createRow(1);
            row.createCell(0).setCellValue("Hello POI");
            row.createCell(1).setCellValue(42);
            Row row2 = sheet.createRow(2);
            row2.createCell(0).setCellValue("中国-测试");
            row2.createCell(1).setCellValue(3.14);

            try (FileOutputStream fos = new FileOutputStream(path)) {
                wb.write(fos);
            }
        }
        System.out.println("[WRITE] 已写出文件: " + path +
            ", 大小=" + new File(path).length() + " bytes" +
            " (=" + String.format("%.1f", new File(path).length() / 1024.0) + " KB)");

        // ===== 读 =====
        try (FileInputStream fis = new FileInputStream(path);
             Workbook wb = new XSSFWorkbook(fis)) {
            Sheet sheet = wb.getSheetAt(0);
            System.out.println("[READ] Sheet count=" + wb.getNumberOfSheets() +
                ", first sheet name=\"" + sheet.getSheetName() + "\"");
            for (Row r : sheet) {
                for (Cell c : r) {
                    DataFormatter fmt = new DataFormatter();
                    String val = fmt.formatCellValue(c);
                    System.out.printf("[READ] R%dC%d = %s%n",
                        r.getRowNum(), c.getColumnIndex(), val);
                }
            }
        }
        System.out.println("[DONE] 写读演示完成");
    }
}

4.4 编译并构建运行 classpath

编译打包(-q 静默,exit 0 即成功):

cd /opt/data/poi-demo && mvn -q package

生成运行 classpath 文件:

cd /opt/data/poi-demo && mvn -q dependency:build-classpath -Dmdep.outputFile=/opt/data/poi-demo/cp.txt

4.5 运行并验证 xlsx 写读

说明:系统 locale 非 UTF-8 时,Java 程序需加 -Dfile.encoding=UTF-8 才能正常输出中文,否则 System.out 中文显示为 ?(乱码);写入文件内容本身不受影响。

cd /opt/data/poi-demo && java -Dfile.encoding=UTF-8 -cp "target/classes:$(cat cp.txt)" PoiXlsxDemo

真实回显(RUN_EXIT=0):

2026-10-11T11:27:04.652091124Z main ERROR Log4j API could not find a logging provider.
[WRITE] 已写出文件: /tmp/demo.xlsx, 大小=3379 bytes (=3.3 KB)
[READ] Sheet count=1, first sheet name="Demo"
[READ] R0C0 = Name
[READ] R0C1 = Value
[READ] R1C0 = Hello POI
[READ] R1C1 = 42
[READ] R2C0 = 中国-测试
[READ] R2C1 = 3.14
[DONE] 写读演示完成

验证输出文件及其 ZIP 内部结构:

ls -l /tmp/demo.xlsx
unzip -l /tmp/demo.xlsx

真实回显:

-rw-r--r-- 1 root root 3379 Oct 11 11:27 /tmp/demo.xlsx   # 3379 bytes ≈ 3.3 KB

Archive:  /tmp/demo.xlsx
  Length      Date    Time    Name
---------  ---------- -----   ----
     1053  2026-10-11 11:27   [Content_Types].xml
      586  2026-10-11 11:27   _rels/.rels
      183  2026-10-11 11:27   docProps/app.xml
      433  2026-10-11 11:27   docProps/core.xml
      237  2026-10-11 11:27   xl/sharedStrings.xml
      674  2026-10-11 11:27   xl/styles.xml
      347  2026-10-11 11:27   xl/workbook.xml
      564  2026-10-11 11:27   xl/_rels/workbook.xml.rels
      639  2026-10-11 11:27   xl/worksheets/sheet1.xml
---------                     -------
     4716                     9 files

工程编译成功、xlsx 写读数据(含中文"中国-测试")全部正确、输出文件结构正常,即视为 Apache POI 5.5.1 已安装成功。

五、配置说明

5.1 Maven 构建 JVM 堆内存(MAVEN_OPTS)

POI 处理大文件时内存占用较高,构建期建议将 Maven 进程堆限制在 256–512MB,避免占用过多宿主内存。在 root 家目录 Shell 启动文件中写入系统级 MAVEN_OPTS:

编辑 /root/.bashrc(或 /etc/environment、/etc/mavenrc),追加一行:

export MAVEN_OPTS="-Xms256m -Xmx512m -Xmn128m"

重新加载环境变量:

source /root/.bashrc

验证实际生效的堆参数(mvn 为 Java 进程,可用 jps -v 与 ps -ef 核对):

jps -v
ps -ef | grep [c]lasspath

💡 说明:jps -v 会列出所有 Java 进程及其 JVM 参数;确认 MAVEN_OPTS 中的 -Xms256m -Xmx512m 出现在 Maven descriptor 进程参数中即生效。

5.2 中文输出编码

非 UTF-8 locale 环境(如 ANSI_X3.4-1968)运行 POI 示例时,System.out 打印中文会显示为 ?。两种解决方式任选其一:

  • 运行命令加 -Dfile.encoding=UTF-8(本指南第 4.5 节采用方式);
  • 设置环境变量 JAVA_TOOL_OPTIONS="-Dfile.encoding=UTF-8"。

5.3 依赖清单(compile classpath,13 个 jar)

最小工程构建后,~/.m2/repository 下共 13 个 jar 进入编译 classpath:

jar版本大小
poi5.5.12.9M
poi-ooxml5.5.12.0M
poi-ooxml-lite5.5.15.8M
xmlbeans5.3.02.2M
commons-compress1.28.01.1M
commons-lang33.18.0688K
commons-io2.21.0572K
commons-codec1.20.0392K
log4j-api2.24.3344K
curvesapi1.08116K
commons-math33.6.12.2M
commons-collections44.5.0见 ~/.m2
SparseBitSet1.328K

六、注意事项

  1. JDK 要求:POI 5.5.x 需 JDK 8+;本实测使用 JDK 17 + Maven 3.6.3 编译运行正常。
  2. 依赖链:核心第三方依赖为 commons-codec / commons-math3 / SparseBitSet / xmlbeans / commons-compress(+commons-lang3) / commons-io / curvesapi / log4j-api / commons-collections4,Maven 自动传递引入,无需手工添加。
  3. 日志警告:仅 log4j-api 无实现时,运行会打印 Log4j API could not find a logging provider 警告,不影响功能;引入 log4j-core 或 slf4j 实现可消除。
  4. 旧 schema 包:POI 5.x 无 poi-ooxml-schemas,其职责由 poi-ooxml-lite 承担。
  5. 读文件方式:小文件可用 FileInputStream + XSSFWorkbook;大文件推荐 XSSFWorkbook(OPCPackage) / SAX 事件解析,避免整本载入内存。
  6. 版本探测:dlcdn 只保留最近发布,完整版本列表查 Maven Central 目录;archive.apache.org 目录页为 JS 渲染,直接 wget 无法 grep 到文件列表。

七、常见问题

7.1 编译报"程序包 org.apache.poi 不存在"

原因:poi-ooxml 依赖未正确下载或构件版本错误。检查 ~/.m2/repository/org/apache/poi/ 下是否有 poi-5.5.1.jar、poi-ooxml-5.5.1.jar、poi-ooxml-lite-5.5.1.jar;确认 pom.xml 中 <version>5.5.1</version> 拼写正确,并清理后重新构建:

cd /opt/data/poi-demo && mvn -q clean package

7.2 中文输出为问号乱码

原因:系统 locale 非 UTF-8(如 ANSI_X3.4-1968)。加 -Dfile.encoding=UTF-8 或设 JAVA_TOOL_OPTIONS 后重跑即可(见 5.2 节),写入文件内容本身不受影响。

7.3 首行出现 Log4j 警告

原因:classpath 中只有 log4j-api 没有实现。该警告不影响功能;如需消除,在 pom.xml 中额外引入任一日志实现(如 log4j-core 或 slf4j)。

八、卸载方式

Apache POI 为 Maven 依赖类库,无系统级安装;"卸载"即删除本地缓存与该工程:

# 删除 Maven 本地缓存的 POI 构件
rm -rf /root/.m2/repository/org/apache/poi

# 删除示例工程目录
rm -rf /opt/data/poi-demo

如需同时移除 JDK / Maven / wget:

apt-get purge -y openjdk-17-jdk-headless maven wget

九、参考链接

  • Apache POI 官方发布说明:https://dlcdn.apache.org/poi/release/RELEASE-NOTES.txt
  • Apache POI 官网:https://poi.apache.org/
  • Maven Central poi-ooxml 版本目录:https://repo1.maven.org/maven2/org/apache/poi/poi-ooxml/