You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

使用docx4j将.docx转换为.pdf时生成空PDF并抛出NoSuchMethodError错误的解决方案求助

解决docx4j转PDF时的NoSuchMethodError问题

从你的栈跟踪信息java.lang.NoSuchMethodError: org.docx4j.jaxb.Context.getFopConfigContext()可以直接定位到核心问题:你混用了不同版本的docx4j依赖组件,导致API不兼容,最终触发错误并生成空PDF文件。

问题根源

你的依赖配置里,docx4j-JAXB-Internal是8.3.4版本,而其他核心转换组件(比如docx4j-export-fo)都是11.4.6版本。版本差异使得高版本组件试图调用低版本中不存在的方法,直接引发了NoSuchMethodError。另外,你同时引入了三个JAXB实现(Internal、ReferenceImpl、MOXy),这会导致依赖冲突,进一步加重问题。

解决方案步骤

1. 统一依赖版本并清理冲突的JAXB依赖

把所有docx4j组件的版本统一为11.4.6,并且只保留一个JAXB实现(避免冲突)。推荐使用docx4j-JAXB-ReferenceImpl,修正后的Maven依赖如下:

<dependency>
    <groupId>org.docx4j</groupId>
    <artifactId>docx4j-JAXB-ReferenceImpl</artifactId>
    <version>11.4.6</version>
</dependency>
<dependency>
    <groupId>org.docx4j</groupId>
    <artifactId>docx4j-export-fo</artifactId>
    <version>11.4.6</version>
</dependency>

注意:移除docx4j-JAXB-Internaldocx4j-JAXB-MOXy,如果需要使用MOXy作为JAXB实现,只保留docx4j-JAXB-MOXy即可。

2. 优化Kotlin代码的资源管理

你的代码手动调用flush()close()存在风险——如果转换过程中抛出异常,流可能无法正确关闭。Kotlin的use块可以自动管理资源,确保流始终被正确处理:

class DocxToPdf {
    fun convert(inputFile: File, outputFile: File) {
        inputFile.inputStream().use { inputStream ->
            outputFile.outputStream().use { outputStream ->
                val wordMLPackage = WordprocessingMLPackage.load(inputStream)
                Docx4J.toPDF(wordMLPackage, outputStream)
            }
        }
    }
}

这里直接用File作为参数比FileInputStream更灵活,use块会自动处理流的打开和关闭,无需手动操作,代码也更简洁健壮。

3. 补充缺失的依赖(可选)

如果仍然遇到问题,检查是否缺少Apache FOP的依赖(docx4j-export-fo依赖它来生成PDF),可以显式添加以下依赖确保完整性:

<dependency>
    <groupId>org.apache.xmlgraphics</groupId>
    <artifactId>fop</artifactId>
    <version>2.9</version>
</dependency>

为什么这样能解决问题

  • 统一版本后,所有docx4j组件的API保持一致,不会出现方法找不到的情况。
  • 清理多余的JAXB实现避免了类加载冲突,确保使用的JAXB上下文与docx4j版本完全匹配。
  • use块提升了代码的健壮性,彻底避免资源泄漏的可能。

内容的提问来源于stack exchange,提问作者Ricardo de Vries

火山引擎 最新活动