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

核心概念
-
.docvs.docx:.doc: 是旧版的二进制格式,POI 对它的支持有限,主要通过HWPF(Horrible Word Processor Format) 模块,功能相对较弱,且容易出错。.docx: 是基于 Office Open XML 的新版格式,POI 对它的支持非常完善和强大,通过XWPF(XML Word Processor Format) 模块。强烈建议使用.docx格式。
-
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 的文件,并提取其中的文本、段落、表格和图片信息。

示例 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());
}
}
}
代码详解
-
try-with-resources:try (FileInputStream fis = ...)是一种推荐的方式,它会自动在代码块执行完毕后关闭FileInputStream,即使发生异常也能保证资源被释放。 -
XWPFDocument document = new XWPFDocument(fis);这一步是核心,它根据输入流创建了一个代表整个 Word 文档的对象。 -
读取段落:
document.getParagraphs()返回一个List<XWPFParagraph>,包含了文档中所有的段落。paragraph.getText()是最简单直接获取段落文本的方法。 -
读取表格:
document.getTables()返回一个List<XWPFTable>,遍历表格的行 (table.getRows()),再遍历行的单元格 (row.getTableCells()),最后用cell.getText()获取单元格内容。
(图片来源网络,侵删) -
读取图片: 读取图片比读取文本稍微复杂一点,图片被嵌入到段落或表格的
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 文档!
