Java使用documents4j在linux环境实现word转pdf,并解决中文乱码

本文主要分享使用documents4j将word转换成pdf,并解决中文乱码的问题。

一开始使用的是poi进行word转换pdf,但是当word中有图片,转换就会报错。

于是对比了各种转换方式,又选择了documents4j,通过网上的教程,很快就成功的将word转换成了pdf,还很好的保留了格式。但当部署到linux服务器运行时,又出现了报错,于是又寻找解决方案,最终在千篇一律的搬运文中终于找到了解决方法。当程序正常运行转换成功时,高兴的打开文档一看,又让人懵逼了,全是乱码。好吧,又继续解决乱码问题吧。最终花了将近两天的时间才完美的实现了linux环境下word转换成pdf的功能。

接下来分享具体的操作。

 linux系统安装LibreOffice

CentOS:使用以下命令安装

sudo yum install libreoffice

Ubuntu:使用以下命令安装

sudo apt-get install libreoffice

linxu系统添加字体

如果linux系统下缺失中文字体库,那么使用LibreOffice将word转换成pdf后,就会出现乱码,这时我们就得将word中使用到的字体添加到linux系统中。

要查看系统中已经安装的字体,我们可以使用fc-list命令进行查看。如果系统中没有该命令的话,我们需要先安装相关的软件包。

在centos上,使用如下命令进行安装:

yum install -y fontconfig mkfontscale

在ubuntu上,使用如下命令进行安装:

sudo apt-get -y install fontconfig xfonts-utils

查看linux已安装字体

fc-list

查看linux已安装中文字体

fc-list :lang=zh

接下来我们先在字体文件夹下创建一个文件夹,将需要的字体文件放入进去

mkdir -p /usr/share/fonts/win_fonts

然后建立字体索引信息,更新字体缓存 进入目录 cd /usr/share/fonts/win_fonts,执行索引字体生成

mkfontscale && mkfontdir && fc-cache -fv

查看黑体常规字体是否安装成功

fc-list :lang=zh

这样我们就将需要的字体安装好了

Java代码

maven依赖:

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

windows环境下,我们可以直接通过LocalConverter调用本地office进行转换,但是linux环境下我们就得借助LibreOffice,使用命令来完成转换功能。

java代码实现:

首先根据环境选择相应的实现方法

// 待转换的word文件
File wordFile = new File("/home/document/word/11.word");
// 转换后的pdf文件
File pdfFile = new File("/home/document/pdf/11.pdf)";
// 获取当前系统名称
String osName = System.getProperty("os.name").toLowerCase();
// 根据系统选择执行方法
if (osName.contains("win")) { PdfUtil.winWordToPdf(pdfFile, wordFile); } else if (osName.contains("nux") || osName.contains("nix")) { PdfUtil.linuxWordToPdf(pdfFile, wordFile); }

pdf工具类

public class PdfUtil {

    private static final Logger log = LoggerFactory.getLogger(PdfUtil.class);

    /**
     * windows系统word转pdf
     * @param pdfFile 转换后的pdf文件
     * @param wordFile word源文件
     */
    public static void winWordToPdf(File pdfFile, File wordFile) {
        try {
            IConverter converter = LocalConverter.builder().build();
            converter.convert(new FileInputStream(wordFile))
                    .as(DocumentType.DOCX)
                    .to(new FileOutputStream(pdfFile))
                    .as(DocumentType.PDF).execute();
        } catch (FileNotFoundException e) {
            log.erorr("word转换pdf失败", e);
        }
    }

    /**
     * linux系统word转pdf
   * 使用LibreOffice转换。系统需安装LibreOffice
   * 转换命令 libreoffice --invisible --convert-to pdf --outdir output_dir source_path
   * 转换后的pdf文件名使用的是源文件的名称,所以如果要指定输出文件名称,就需把源文件名称改成想要输出的名称 *
@param pdfFile 转换后的pdf文件 * @param wordFile word源文件 */ public static void linuxWordToPdf(File pdfFile, File wordFile) { // 获取word文件的绝对路径 String sourcePath = wordFile.getAbsolutePath();
     // 获取pdf文件存放文件夹的绝对路径 String outDir
= pdfFile.getAbsolutePath().substring(0, pdfFile.getAbsolutePath().lastIndexOf(File.separator)); // 构建LibreOffice的命令行工具命令 String command = "libreoffice --invisible --convert-to pdf --outdir " + outDir + " " + sourcePath; log.info(command); // 执行转换命令 try { executeLinuxCmd(command); } catch (Exception e) { log.error("linuxWordToPdf linux环境word转换为pdf时出现异常:", e); } } /** * 执行命令行 * * @param cmd 命令行 * @return */ private static boolean executeLinuxCmd(String cmd) { try { Process process = Runtime.getRuntime().exec(cmd); process.waitFor(); } catch (InterruptedException e) { log.error("executeLinuxCmd 执行Linux命令异常:", e); Thread.currentThread().interrupt(); return false; } catch (IOException e) { log.error("获取系统命令执行环境异常", e); } return true; } }

 

posted @ 2024-08-06 15:26  hello龙兄  阅读(1682)  评论(0编辑  收藏  举报