Java 生成 Word 的几种方案
主要有这么一些工具可以使用 Jacob、Apache POI、Java2word、iText,还有一种方法是使用XML作为模板。
使用 XML 的思路:先用 office 编辑好word的样式,然后另存为xml,将xml翻译为FreeMarker模板,最后用java来解析 FreeMarker模板 并输出 Word 文档。经测试这样方式生成的word文档完全符合 office 标准,样式、内容控制非常便利,打印也不会变形,生成的文档和office中编辑文档完全一样。
- Jacob 和 Java2word需要服务器端支持 office,相对麻烦。
- Apache POI 功能较少。
这里推荐一个刚刚发现的产品,由成都冰蓝科技开发的产品 Spire,可以用于操作各种文档,目前我只体验过 Spire.Doc for Java,个人认为使用简单,功能强大,对样式的支持非常好(虽然Spire主要面向企业提供产品,但是也提供了免费使用的产品)。
使用 Spire.Doc 替换 Word 模板中占位符
这里使用 Maven 下载 Spire.Doc 也可以直接下载 jar 包 ==> 参考
1️⃣:首先引入 Maven 依赖
在 Maven 的官方仓库或者阿里云镜像仓库中是没有 Spire 依赖的,所以需要配置 Spire 自己的一个仓库源。
<repositories>
<repository>
<id>com.e-iceblue</id>
<url>https://repo.e-iceblue.cn/repository/maven-public/</url>
</repository>
</repositories>
以下就是 Spire.Doc for Java 的依赖
<!--spire.doc 操作word文档-->
<dependency>
<groupId>e-iceblue</groupId>
<artifactId>spire.doc.free</artifactId>
<version>3.9.0</version>
</dependency>
2️⃣:设计一个Word模板,此文档中存在占位符
3️⃣:编码
public class TestSpireWord {
@Test
public void generateAndReplaceText() {
Document doc = new Document();
doc.loadFromFile("F:\\yourlocation\\template.docx", FileFormat.Docx);
Map<String, String> map = new HashMap<>();
map.put("${name}", "张山");
map.put("${birthday}", "2021-10-18");
map.put("${result}", "成功");
map.put("${col}", "第一列");
map.put("${col1}", "第二列");
map.put("${col2}", "第三列");
replaceSpecialWord(doc, map);
// 保存为文件
doc.saveToFile("F:\\yourlocation\\result.docx",FileFormat.Docx);
// 或者保存至输出流中
//ByteArrayOutputStream os = new ByteArrayOutputStream();
//doc.saveToStream(os, FileFormat.Docx);
}
/**
* 替换Word文件中 ${} 标识的特殊字符
* <br>
* <strong>注意:如果存在部分特殊表示无法替换,请尝试将 ${} 的整个字符串复制到word中,有可能word没有将${}识别为一个整体</strong>
* @param doc: Sprire Document
* @param map: 占位符${} 与 需要替换的为字符串的对应关系
*/
public void replaceSpecialWord(Document doc, Map<String, String> map) {
// 正则表达式,匹配所有的占位符 ${}
Pattern pattern = Pattern.compile("\\$\\{.*?}");
// 根据正则表达式获取所有文本
TextSelection[] allPattern = doc.findAllPattern(pattern);
// 逐个替换占位符
for (TextSelection textSelection : allPattern) {
String tmp = map.get(textSelection.getSelectedText());
System.out.print(textSelection.getSelectedText());
int res = doc.replace(textSelection.getSelectedText(), tmp, true, true);
System.out.println(": " + res);
}
}
}
最终结果:
// 控制台输出
${name}: 1
${birthday}: 1
${result}: 1
${col}: 1
${col1}: 1
${col2}: 1
可以看到使用 Spire.Doc for Java 替换占位符十分简单,并且不会破坏模板的原有样 式。
如果需要了解 Spire.Doc for Java 的更多操作,参考 ===> 官方文档