docx4j word转pdf出现中文乱码(####)问题

解决了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);
    }
<think>嗯,用户想用Docx4jWordPDF,我得先回想一下相关的步骤和代码。首先,Docx4j是一个处理Office文档的Java库,对吧?所以可能需要先导入相关的依赖。记得之前看过用Maven的话要添加docx4j的依赖,可能还有其他的比如PDF相关的换模块。 然后,用户可能需要一个示例代码。Docx4j换流程大致应该是加载Word文档,然后进行配置,比如设置字体映射,最后保存为PDF。不过具体的方法可能需要注意一些细节,比如处理中文字体,否则可能会乱码。记得需要用到FOP(Formatting Objects Processor)或者其他PDF渲染引擎,所以可能还要引入额外的依赖,比如docx4j-export-fo或者相关的库。 另外,用户提供的引用里提到了Documents4j,但用户明确问的是Docx4j,所以可能需要忽略引用中的部分,专注于Docx4j的解决方案。不过,有时候Docx4j可能需要结合其他工具,比如Microsoft Office本身或者第三方换服务,但这样的话可能会依赖Windows环境或者安装Office软件,这点需要说明清楚。 还要注意Docx4j的版本,不同版本可能有不同的API,所以示例代码需要兼容较新的版本。可能还需要处理异常,比如文件找不到或者换过程中的错误。另外,中文字体支持的问题,可能需要配置字体映射,否则生成的PDF可能显示不正确。 用户可能遇到的常见问题包括依赖配置错误、字体不显示、换失败等,所以在回答里应该提到这些注意事项。同时,是否需要使用到临时文件或者流处理,这些也是需要考虑的。最后,可能需要提供一个完整的代码示例,包括加载文档、配置选项、保存PDF的步骤,并指出可能的依赖项和配置要点。</think>### 使用Docx4j实现WordPDF的方法 #### 实现步骤及示例代码 1. **添加Maven依赖** Docx4j需要核心库和PDF导出扩展模块: ```xml <dependency> <groupId>org.docx4j</groupId> <artifactId>docx4j-JAXB-Internal</artifactId> <version>8.3.7</version> </dependency> <dependency> <groupId>org.docx4j</groupId> <artifactId>docx4j-export-fo</artifactId> <version>8.3.7</version> </dependency> ``` 2. **核心换代码** ```java import org.docx4j.Docx4J; import org.docx4j.openpackaging.packages.WordprocessingMLPackage; import java.io.FileOutputStream; public class WordToPdfConverter { public static void convert(String inputPath, String outputPath) throws Exception { WordprocessingMLPackage wordMLPackage = WordprocessingMLPackage.load(new File(inputPath)); FileOutputStream os = new FileOutputStream(outputPath); Docx4J.toPDF(wordMLPackage, os); os.close(); wordMLPackage.save(new File(outputPath.replace(".pdf", "_temp.docx"))); // 可选:保存中间文件 } } ``` #### 注意事项 1. **字体兼容性** 中文字体需显式配置,建议添加: ```java wordMLPackage.setFontMapper(new IdentityPlusMapper()); ``` 2. **运行环境要求** 需安装Apache FOP 2.8+并配置环境变量,或添加FOP依赖: ```xml <dependency> <groupId>org.apache.xmlgraphics</groupId> <artifactId>fop</artifactId> <version>2.8</version> </dependency> ``` 3. **代码优化方向** - 增加异常处理(`Docx4JException`, `IOException`) - 使用try-with-resources管理资源 - 配置日志输出换过程
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值