杰瑞科技汇

Java POI如何高效读取Word文档内容?

下面我将为你详细讲解如何使用 POI 读取 .docx 文件(推荐,因为 .doc 格式支持有限且复杂),并提供一个完整的、可运行的示例代码。

Java POI如何高效读取Word文档内容?-图1
(图片来源网络,侵删)

核心概念

  1. .doc vs .docx:

    • .doc: 是旧版的二进制格式,POI 对它的支持有限,主要通过 HWPF (Horrible Word Processor Format) 模块,功能相对较弱,且容易出错。
    • .docx: 是基于 Office Open XML 的新版格式,POI 对它的支持非常完善和强大,通过 XWPF (XML Word Processor Format) 模块。强烈建议使用 .docx 格式。
  2. POI OOXML 模块:

    • XWPFDocument: 代表一个 .docx 文档对象,这是你操作的入口点。
    • XWPFParagraph: 代表文档中的一个段落。
    • XWPFRun: 代表段落中具有相同格式(如字体、颜色、大小)的文本块,一个段落可以包含多个 Run
    • XWPFTable: 代表一个表格。
    • XWPFTableRow: 代表表格中的一行。
    • XWPFTableCell: 代表表格中的一个单元格。

添加 Maven 依赖

你需要在你的 Maven 项目的 pom.xml 文件中添加 POI 的依赖,为了处理 .docx,你需要 poi-ooxml

<dependencies>
    <!-- POI 核心库 -->
    <dependency>
        <groupId>org.apache.poi</groupId>
        <artifactId>poi</artifactId>
        <version>5.2.5</version> <!-- 建议使用较新版本 -->
    </dependency>
    <!-- POI OOXML 库,用于处理 .docx, .xlsx 等现代 Office 格式 -->
    <dependency>
        <groupId>org.apache.poi</groupId>
        <artifactId>poi-ooxml</artifactId>
        <version>5.2.5</version>
    </dependency>
    <!-- 为了处理一些 OOXML 特有的特性,可能需要这个依赖 -->
    <dependency>
        <groupId>org.apache.poi</groupId>
        <artifactId>ooxml-schemas</artifactId>
        <version>1.4</version>
    </dependency>
</dependencies>

编写 Java 代码读取 Word 文档

下面是一个完整的示例,展示如何读取一个名为 example.docx 的文件,并提取其中的文本、段落、表格和图片信息。

Java POI如何高效读取Word文档内容?-图2
(图片来源网络,侵删)

示例 Word 文档 (example.docx) 内容示例:


这是一个普通段落,包含一些文本。
这里有一个列表:
*   列表项 1
*   列表项 2
*   列表项 3
下面是一个表格:
| 姓名 | 年龄 | 城市 |
|------|------|------|
| 张三 | 28   | 北京 |
| 李四 | 32   | 上海 |
文档末尾。

Java 读取代码 (WordReader.java):

import org.apache.poi.xwpf.usermodel.*;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
public class WordReader {
    public static void main(String[] args) {
        // Word 文件的路径
        String filePath = "example.docx";
        try (FileInputStream fis = new FileInputStream(new File(filePath))) {
            // 1. 加载 Word 文档
            XWPFDocument document = new XWPFDocument(fis);
            System.out.println("========== 开始读取文档内容 ==========");
            // 2. 读取文档中的所有段落
            System.out.println("\n--- [段落] ---");
            for (XWPFParagraph paragraph : document.getParagraphs()) {
                // paragraph.getText() 会获取段落中所有 Run 的文本并拼接
                System.out.println(paragraph.getText());
            }
            // 3. 读取文档中的所有表格
            System.out.println("\n--- [表格] ---");
            for (XWPFTable table : document.getTables()) {
                // 遍历表格的每一行
                for (XWPFTableRow row : table.getRows()) {
                    // 遍历行中的每一个单元格
                    StringBuilder rowText = new StringBuilder();
                    for (XWPFTableCell cell : row.getTableCells()) {
                        // cell.getText() 获取单元格中的文本
                        rowText.append(cell.getText()).append("\t");
                    }
                    System.out.println(rowText.toString().trim());
                }
            }
            // 4. 读取文档中的所有图片
            // 注意:XWPFDocument 本身不直接提供图片列表,需要从所有段落和表格的 CT 对象中获取
            System.out.println("\n--- [图片] ---");
            int pictureIndex = 1;
            // 从正文中读取图片
            for (XWPFParagraph p : document.getParagraphs()) {
                for (XWPFPicture pic : p.getPictures()) {
                    System.out.println("找到图片 " + pictureIndex + ": " + pic.getPictureData().getData());
                    pictureIndex++;
                }
            }
            // 从表格中读取图片
            for (XWPFTable table : document.getTables()) {
                for (XWPFTableRow row : table.getRows()) {
                    for (XWPFTableCell cell : row.getTableCells()) {
                        for (XWPFParagraph p : cell.getParagraphs()) {
                            for (XWPFPicture pic : p.getPictures()) {
                                System.out.println("在表格中找到图片 " + pictureIndex + ": " + pic.getPictureData().getData());
                                pictureIndex++;
                            }
                        }
                    }
                }
            }
            System.out.println("\n========== 文档读取完毕 ==========");
        } catch (IOException e) {
            e.printStackTrace();
            System.err.println("读取 Word 文档时发生错误: " + e.getMessage());
        }
    }
}

代码详解

  1. try-with-resources: try (FileInputStream fis = ...) 是一种推荐的方式,它会自动在代码块执行完毕后关闭 FileInputStream,即使发生异常也能保证资源被释放。

  2. XWPFDocument document = new XWPFDocument(fis); 这一步是核心,它根据输入流创建了一个代表整个 Word 文档的对象。

  3. 读取段落: document.getParagraphs() 返回一个 List<XWPFParagraph>,包含了文档中所有的段落。paragraph.getText() 是最简单直接获取段落文本的方法。

  4. 读取表格: document.getTables() 返回一个 List<XWPFTable>,遍历表格的行 (table.getRows()),再遍历行的单元格 (row.getTableCells()),最后用 cell.getText() 获取单元格内容。

    Java POI如何高效读取Word文档内容?-图3
    (图片来源网络,侵删)
  5. 读取图片: 读取图片比读取文本稍微复杂一点,图片被嵌入到段落或表格的 Run 中,POI 提供了 XWPFParagraph.getPictures() 方法来获取段落中的图片,图片数据可以通过 XWPFPicture.getPictureData().getData() 获取,这是一个字节数组,在实际应用中,你可以将这个字节数组保存为 .png, .jpg 等文件。


高级用法:获取文本和格式信息

如果你不仅需要文本,还需要文本的格式(如字体、颜色、加粗等),你需要遍历 Run 对象。

// 在读取段落的循环内
for (XWPFParagraph paragraph : document.getParagraphs()) {
    System.out.println("\n--- 段落: " + paragraph.getText() + " ---");
    for (XWPFRun run : paragraph.getRuns()) {
        String runText = run.getText(0); // (0) 表示获取整个 Run 的文本
        System.out.println("  Run 文本: " + runText);
        System.out.println("  字体大小: " + run.getFontSize());
        System.out.println("  是否加粗: " + run.isBold());
        System.out.println("  是否斜体: " + run.isItalic());
        System.out.println("  字体名称: " + run.getFontFamily());
        // ... 更多格式属性
    }
}

任务 核心方法/对象 说明
加载文档 new XWPFDocument(new FileInputStream(file)) 创建文档对象,是所有操作的基础。
读取所有段落 document.getParagraphs() 返回 List<XWPFParagraph>
读取段落文本 paragraph.getText() 简单获取整个段落的文本。
读取表格 document.getTables() 返回 List<XWPFTable>
读取表格内容 row.getTableCells() + cell.getText() 嵌套遍历行和单元格。
读取图片 paragraph.getPictures() 返回 List<XWPFPicture>
获取图片数据 pic.getPictureData().getData() 获取图片的字节数组。
获取文本格式 paragraph.getRuns() 遍历 Run 对象获取详细的格式信息。

希望这个详细的指南能帮助你顺利地使用 POI 读取 Word 文档!

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