1. 概述
Apache POI 是一个 Java 库,用于处理基于 Office Open XML 标准(OOXML)和 Microsoft OLE 2 复合文档格式(OLE2)的各种文件格式。
本教程重点介绍 Apache POI 对最常用的 Office 文件格式——Microsoft Word 的支持。我们将逐步讲解格式化和生成 MS Word 文档所需的步骤,以及如何解析此类文档。
2. Maven 依赖
Apache POI 处理 MS Word 文件只需一个依赖:
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>5.2.5</version>
</dependency>
最新版本可点击此处查看。
3. 准备工作
我们先了解生成 MS Word 文档所需的核心元素。
3.1 资源文件
我们将收集三个文本文件的内容,写入名为 rest-with-spring.docx 的 MS Word 文档。
此外,使用 logo-leaf.png 文件向新文档插入图片。所有文件均位于类路径下,通过静态变量表示:
public static String logo = "logo-leaf.png";
public static String paragraph1 = "poi-word-para1.txt";
public static String paragraph2 = "poi-word-para2.txt";
public static String paragraph3 = "poi-word-para3.txt";
public static String output = "rest-with-spring.docx";
这些资源文件的内容来自本站课程页面(仓库链接见文末)。
3.2 辅助方法
生成文档的主逻辑会使用以下辅助方法:
public String convertTextFileToString(String fileName) {
try (Stream<String> stream
= Files.lines(Paths.get(ClassLoader.getSystemResource(fileName).toURI()))) {
return stream.collect(Collectors.joining(" "));
} catch (IOException | URISyntaxException e) {
return null;
}
}
此方法提取类路径中指定文本文件的内容,合并所有行后返回字符串。
4. 生成 MS Word 文档
本节介绍如何格式化和生成 Microsoft Word 文档。操作前需先创建 XWPFDocument 实例:
XWPFDocument document = new XWPFDocument();
4.1 格式化标题和副标题
创建标题需先实例化 XWPFParagraph 并设置对齐方式:
XWPFParagraph title = document.createParagraph();
title.setAlignment(ParagraphAlignment.CENTER);
段落内容需包装在 XWPFRun 对象中,可设置文本值和样式:
XWPFRun titleRun = title.createRun();
titleRun.setText("Build Your REST API with Spring");
titleRun.setColor("009933");
titleRun.setBold(true);
titleRun.setFontFamily("Courier");
titleRun.setFontSize(20);
各 set 方法名已明确其用途。
类似地创建副标题段落:
XWPFParagraph subTitle = document.createParagraph();
subTitle.setAlignment(ParagraphAlignment.CENTER);
格式化副标题:
XWPFRun subTitleRun = subTitle.createRun();
subTitleRun.setText("from HTTP fundamentals to API Mastery");
subTitleRun.setColor("00CC44");
subTitleRun.setFontFamily("Courier");
subTitleRun.setFontSize(16);
subTitleRun.setTextPosition(20);
subTitleRun.setUnderline(UnderlinePatterns.DOT_DOT_DASH);
setTextPosition 设置副标题与后续图片的间距,setUnderline 定义下划线样式。
由于标题和副标题内容简短,直接硬编码更高效。
4.2 插入图片
图片也需包装在 XWPFParagraph 中。为使图片水平居中并位于副标题下方,添加以下代码:
XWPFParagraph image = document.createParagraph();
image.setAlignment(ParagraphAlignment.CENTER);
设置图片与下方文本的间距:
XWPFRun imageRun = image.createRun();
imageRun.setTextPosition(20);
从类路径读取图片并插入文档,指定尺寸:
Path imagePath = Paths.get(ClassLoader.getSystemResource(logo).toURI());
imageRun.addPicture(Files.newInputStream(imagePath),
XWPFDocument.PICTURE_TYPE_PNG, imagePath.getFileName().toString(),
Units.toEMU(50), Units.toEMU(50));
4.3 格式化段落
使用 poi-word-para1.txt 创建第一个段落:
XWPFParagraph para1 = document.createParagraph();
para1.setAlignment(ParagraphAlignment.BOTH);
String string1 = convertTextFileToString(paragraph1);
XWPFRun para1Run = para1.createRun();
para1Run.setText(string1);
段落创建方式与标题/副标题类似,区别在于使用辅助方法读取内容。
类似地,用 poi-word-para2.txt 和 poi-word-para3.txt 创建其他段落:
XWPFParagraph para2 = document.createParagraph();
para2.setAlignment(ParagraphAlignment.RIGHT);
String string2 = convertTextFileToString(paragraph2);
XWPFRun para2Run = para2.createRun();
para2Run.setText(string2);
para2Run.setItalic(true);
XWPFParagraph para3 = document.createParagraph();
para3.setAlignment(ParagraphAlignment.LEFT);
String string3 = convertTextFileToString(paragraph3);
XWPFRun para3Run = para3.createRun();
para3Run.setText(string3);
三个段落的创建逻辑基本一致,仅样式(如对齐方式、斜体)不同。
4.4 生成 MS Word 文件
将 document 对象写入文件:
FileOutputStream out = new FileOutputStream(output);
document.write(out);
out.close();
document.close();
本节所有代码封装在 handleSimpleDoc 方法中。
5. 解析与测试
本节介绍 MS Word 文档的解析及结果验证。
5.1 准备工作
在测试类中声明静态字段:
static WordDocument wordDocument;
该字段用于引用包含第 3、4 节代码的类实例。
解析测试前需初始化变量并生成文档:
@BeforeClass
public static void generateMSWordFile() throws Exception {
WordTest.wordDocument = new WordDocument();
wordDocument.handleSimpleDoc();
}
5.2 解析文档与验证
首先从项目目录读取文档内容,存储为 XWPFParagraph 列表:
Path msWordPath = Paths.get(WordDocument.output);
XWPFDocument document = new XWPFDocument(Files.newInputStream(msWordPath));
List<XWPFParagraph> paragraphs = document.getParagraphs();
document.close();
验证标题内容和样式:
XWPFParagraph title = paragraphs.get(0);
XWPFRun titleRun = title.getRuns().get(0);
assertEquals("Build Your REST API with Spring", title.getText());
assertEquals("009933", titleRun.getColor());
assertTrue(titleRun.isBold());
assertEquals("Courier", titleRun.getFontFamily());
assertEquals(20, titleRun.getFontSize());
为简化,仅验证其他部分内容(样式验证逻辑类似):
assertEquals("from HTTP fundamentals to API Mastery",
paragraphs.get(1).getText());
assertEquals("What makes a good API?", paragraphs.get(3).getText());
assertEquals(wordDocument.convertTextFileToString
(WordDocument.paragraph1), paragraphs.get(4).getText());
assertEquals(wordDocument.convertTextFileToString
(WordDocument.paragraph2), paragraphs.get(5).getText());
assertEquals(wordDocument.convertTextFileToString
(WordDocument.paragraph3), paragraphs.get(6).getText());
至此可确认 rest-with-spring.docx 生成成功。
6. 总结
本教程介绍了 Apache POI 对 Microsoft Word 格式的支持,详细讲解了生成文档及验证内容的步骤。
所有示例代码可在 GitHub 项目 中找到。