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
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; } }