使用 Documents4j 处理 Word 转 PDF


使用 Documents4j 处理 Word 转 PDF

能实现这个功能的框架有很多,在满足免费开源并且效果不错的前提下,决定采用 Documents4j 进行转换。

Documents4j 策略

Documents4j 有两个策略,一个是本地策略,一个是远程策略,分别对应的架包是:

  • 本地策略
<dependency>
    <groupId>com.documents4j</groupId>
    <artifactId>documents4j-local</artifactId>
    <version>1.0.3</version>
</dependency>
  • 远程策略
<dependency>
    <groupId>com.documents4j</groupId>
    <artifactId>documents4j-client</artifactId>
    <version>1.0.3</version>
</dependency>

Documents4j 的转换,可以理解为需要依托于微软的:MicrosoftWord / Excel。在本地机器上开发时(Win 电脑),使用本地策略,是可以完成转换的。但部署到 Linux 服务器上后就不能。

问题分析:

  1. Win 电脑系统,默认已经有 MicrosoftWord / Excel 了。而服务器上的 Linux 系统并没有对应的服务,因此需要安装对应的插件。这里安装:LibreOffice。(安装教程这里省略不做详述)安装成功后使用命令测试验证:libreoffice7.1 --invisible --convert-to pdf:writer_pdf_Export /home/demo.docx --outdir /home/ 可以成功,但代码运行还是失败。
  2. 使用命令 /usr/bin/libreoffice7.1 --headless --accept=”socket,host=127.0.0.1,port=8100;urp;”- -nofirststartwizard & 启动 LibreOffice。启动成功后,代码运行还是失败。
  3. 使用远程策略,在 Win 电脑上安装 LibreOffice,然后代码里指向对应的地址。

官网说明:

  • JVM 在 MS Windows 平台上运行,该平台附带 Microsoft Scripting Host for VBS(对于所有现代版本的 MS Windows 都是如此)。
  • 安装的 MS Word 版本为 2007 或更高版本。仅当安装 PDF 插件时才支持 PDF 转换。该插件包含在 Word 2010 及更高版本的 MS Word 中。
  • 启动时 MS Word 尚未运行LocalConverter。对于由另一个 .NET 实例运行的 MS Word 实例尤其如此LocalConverter。 (如前所述,请注意,对于在不同 JVM 上运行或由不同类加载器加载的实例也是如此。)
  • MS Word 已为运行 JVM 的用户正确激活和配置。因此,MS Word 不需要在程序启动或任何其他向导时进行任何配置。
  • 当使用 JVM 应用程序LocalConverter作为服务运行时,请注意下面的 MS Windows 服务配置文件中有关使用 MS Word 的信息。

引入架包

<!--word转pdf-->
<dependency>
    <groupId>com.documents4j</groupId>
    <artifactId>documents4j-client</artifactId>
    <version>1.0.3</version>
</dependency>

<dependency>
    <groupId>com.documents4j</groupId>
    <artifactId>documents4j-transformer-msoffice-word</artifactId>
    <version>1.0.3</version>
</dependency>

<!--远程调用需要的架包-->
<dependency>
    <groupId>org.glassfish.jersey.inject</groupId>
    <artifactId>jersey-hk2</artifactId>
</dependency>

核心代码

// 转换后的文件信息, PDF 文件
File fileOut = new File(path);
// 临时文件
File tempPath = new File(temp);

// 远程地址
@Value("${spring.documents4j.url}")
private String documents4jUrl;

// 完成转换的代码,远程转换使用代码 RemoteConverter
IConverter converter = RemoteConverter.builder().baseFolder(tempPath).baseUri(documents4jUrl).build();
converter.convert(file.getInputStream()).as(DocumentType.DOCX).to(new FileOutputStream(fileOut)).as(DocumentType.PDF).execute();

// 完整核心代码
try (InputStream inputStream = file.getInputStream(); FileOutputStream outputStream = new FileOutputStream(fileOut)) {
    IConverter converter = RemoteConverter.builder().baseFolder(tempPath).baseUri(documents4jUrl).build();
    converter.convert(inputStream).as(DocumentType.DOCX).to(outputStream).as(DocumentType.PDF).execute();
} catch (Exception e) {
    throw new Exception("文件转换时发生异常: " + e.getMessage());
} finally {
    // 删除临时文件
    Files.deleteIfExists(Paths.get(path + pdfName));
}

安装服务

  • 下载并安装:documents4j-server-standalone-1.1.8-shaded.jar。

https://repo1.maven.org/maven2/com/documents4j/documents4j-server-standalone/1.1.8/

documents4j-server-standalone-1.1.8-shaded.jar 的运行依赖 jdk,需要实现在 Win 电脑上安装 jdk。

  • 编写运行脚本,重命名为.bat 文件。
@echo off
%1 mshta vbscript:CreateObject("WScript.Shell").Run("%~s0 ::",0,FALSE)(window.close)&&exit
java -jar D:\documents4j\documents4j-server-standalone-1.1.8-shaded.jar http://192.168.xxxx:9998 > D:\documents4j\documents4j.log 2>&1 &
exit
  • 启动脚本,代码即可执行,后续代码部署到 Linux 也可以执行转换服务。(代码里需要配置好 documents4j-server-standalone 运行的地址和端口)

扩展思考

  1. 使用本地策略时,如果 Linux 上已经安装 LibreOffice,并成功运行,那么上述代码里的 spring.documents4j.url 换成 Linux 上已经启动的地址,是否可行。
  2. 把 Linux 上 LibreOffice 运行命令打包成 JAVA 代码,直接调用是否可行。

文章作者: L Q
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 L Q !
  目录