解决了docx4j 在服务器进行word转pdf时,因为服务器环境的字体缺失导致中文出现###问题.网上有其他资料显示需要自行下载linux字体,然后进行安装也能解决.但是博主目前服务器环境是阿里云的ACK模式,权限有限.目前本地环境是可以执行转换,文件不会出现乱码的情况.因为本地C:\Windows\Fonts 已经存在了字体转换的需要字体
1.环境准备
SpringBoot 2.7.3
Jdk 11
maven 3.6.2
2.导入项目依赖
<dependency>
<groupId>org.docx4j</groupId>
<artifactId>docx4j-export-fo</artifactId>
<version>8.1.1</version>
</dependency>
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.3.1</version>
</dependency>
<dependency>
<groupId>org.glassfish.jaxb</groupId>
<artifactId>jaxb-runtime</artifactId>
<version>2.3.1</version>
</dependency>
<dependency>
<groupId>org.docx4j</groupId>
<artifactId>docx4j-JAXB-ReferenceImpl</artifactId>
<version>8.3.3</version> <!-- 使用最新版本 -->
</dependency>
因为是JDK11原生的jdk 底层尝试使用 JAXB 但无法实例化 JAXB Reference Implementation。这个问题通常发生在 Java 9+ 环境中,因为 JAXB 默认不再包含在 JDK 中。所以添加了下面3项额外的依赖
3.导入字体文件
将docx4j 进行字体转换的文件导入到项目文件中,需要那种进行网上搜索即可
4.核心代码部分
- 进行导入文件的读取
public static void convertDocxToPdf(String docxPath, String pdfPath) throws Exception {
FileOutputStream fileOutputStream = null;
try {
File file = new File(docxPath);
fileOutputStream = new FileOutputStream(new File(pdfPath));
WordprocessingMLPackage mlPackage = WordprocessingMLPackage.load(file);
setFontMapper(mlPackage);
Docx4J.toPDF(mlPackage, new FileOutputStream(new File(pdfPath)));
} catch (Exception e) {
e.printStackTrace();
log.error("docx文档转换为PDF失败");
} finally {
IOUtils.closeQuietly(fileOutputStream);
}
}
private static void setFontMapper(WordprocessingMLPackage mlPackage) throws Exception {
URL fontUrl = WordUtils.class.getClassLoader().getResource("fonts/SimSun.ttf");
if (fontUrl == null) {
throw new FileNotFoundException("字体文件未找到,请检查 resources/fonts/SimSun.ttf 是否存在");
}
PhysicalFonts.addPhysicalFonts("SimSun", fontUrl);
// 设置字体映射
Mapper fontMapper = new IdentityPlusMapper();
log.info("获取到字体:{}", PhysicalFonts.get("SimSun"));
fontMapper.put("宋体", PhysicalFonts.get("SimSun")); // Word文档中的字体名
fontMapper.put("微软雅黑", PhysicalFonts.get("SimSun"));
fontMapper.put("黑体", PhysicalFonts.get("SimSun"));
fontMapper.put("楷体", PhysicalFonts.get("SimSun"));
fontMapper.put("仿宋", PhysicalFonts.get("SimSun"));
fontMapper.put("幼圆", PhysicalFonts.get("SimSun"));
fontMapper.put("Arial", PhysicalFonts.get("SimSun"));
mlPackage.setFontMapper(fontMapper);
}