调研后发现网上有很多解决办法,Windows平台上word和PDF可以完美的转换,但大部分业务是要求在Linux上运行的,基于Windows的方法无法移植到Linux上运行,现有的Linux上的Word文档转换为PDF的方法验证后大多数存在PDF和Word格式不一致的问题(比如PDF与Word排版页数不一致,文字排列更紧凑等),所以本文的主要目标是解决Linux平台上Word转为PDF之后的格式版面不一致的问题,先放结论,对于大部分测试用例文档格式在转换后基本一致,存在少部分不一致的问题。并且将java项目打包成jar包并在linux平台上调用命令行测试通过。

Windows平台Word转PDF

import win32com  # python -m pip install pypiwin32
from win32com.client import Dispatch
import sys
def word2pdf(file_path='/documents/4-科园商务会议服务协议_20191105广州.doc'):
	word = Dispatch('Word.Application')
	word.Visible = 0 # 后台运行,不显示
	word.DisplayAlerts = 0  #不警告
	path = sys.path[0] + file_path
	doc = word.Documents.Open(FileName=path, Encoding='gbk')
	doc.SaveAs(path[:-5]+'_pdfed.pdf', 17) #  txt=4, html=10, docx=16, pdf=17
	doc.Close()
	word.Quit()
	print("Word2Pdf 转换完成,PDF文件和Word在同级目录中。")
if __name__ == '__main__':
	# word2pdf('/documents/1-技术服务合同.docx')
	file_path = sys.argv[1]
	print(file_path)
	word2pdf(file_path)

win32com只能在windows平台上运行,linux上没有类似的依赖包。

Linux平台Word转PDF

1.基于unoconv工具实现word转为PDF
安装:yum install unoconv
使用:unoconv -f pdf XXX.docx

2.使用cups-pdf工具实现word转PDF
安装:sudo apt-get install cups-pdf
使用:oowriter -convert-to pdf:writer_pdf_Export XXX.docx

3.使用libreoffice测试:
soffice --headless --invisible --convert-to pdf XXX.docx

4.使用apose-words-15.8.0工具hacked(pojie)版,java编程实现word转PDF。(推荐,目前验证该方法Word转为PDF后格式变化最小)

Eclipse项目目录结构:(文末有完整项目源代码和打包的jar包,jar包测试可以直接调用)
在这里插入图片描述

【出现的问题记录】打成jar包后只能把jar包和待转换的word文档放在同一个目录下,并且生成的目录也只能放在同一个目录下,这和Java中getResourceAsStream的用法有关系:

getResourceAsStream读取的文件路径只局限与工程的源文件夹中,包括在工程src根目录下,以及类包里面任何位置,但是如果配置文件路径是在除了源文件夹之外的其他文件夹中时,该方法是用不了的。
引用自:https://www.iteye.com/blog/riddickbryant-436693

【已解决,封装jar包后读取项目目录外的文件】
之前打开word的文件的方法是利用getResourceAsStream:
file_path = "C:\\Users\\16616\\Desktop\\XXX.docx";
word = TestWord.class.getClassLoader().getResourceAsStream(file_path);
Document doc = new Document(word);
现在直接用new Document打开:
Document doc = new Document(file_path);

最后是源代码:

package com.demo;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.util.stream.Stream;
import com.aspose.words.Document;
import com.aspose.words.FileFormatUtil;
import com.aspose.words.License;
import com.aspose.words.SaveFormat;
 * 由于ASPOSE比较吃内存,操作大一点的文件就会堆溢出,所以请先设置好java虚拟机参数:-Xms512m -Xmx512m(参考值)<br>
 * 如有疑问,请在CSDN下载界面留言,或者联系QQ569925980<br>
 * @author Spark
public class TestWord {
    private static InputStream license;
    private static InputStream word;
     * 获取license
     * @return
    public static boolean getLicense() {
        boolean result = false;
        try {
            license = TestWord.class.getClassLoader().getResourceAsStream("license.xml");// license路径
//            word = TestWord.class.getClassLoader().getResourceAsStream("\\4-广州.doc");
            License aposeLic = new License();
            aposeLic.setLicense(license);
            result = true;
        } catch (Exception e) {
            e.printStackTrace();
        return result;
    public static void word2pdf(String file_path,String save_path) {
//    	word = TestWord.class.getClassLoader().getResourceAsStream("\\XXX.doc");// 原始word路径
    	word = TestWord.class.getClassLoader().getResourceAsStream(file_path);
    	// 验证License
        if (!getLicense()) {
            return;
        try {
            long old = System.currentTimeMillis();
//            Document doc = new Document(word);
            Document doc = new Document(file_path);
//            File file = new File("C:\\Users\\16616\\Desktop\\AsposeWord\\src\\test.pdf");// 输出路径
            //存为新PDF文件,文件名需要从file_path中提取出来
            File tempFile =new File(file_path.trim());
            String fileName = tempFile.getName();
            System.out.println("fileName = " + fileName);
            String[] tmp = fileName.split("\\.");
            String pdf_name = tmp[0]+".pdf";
            System.out.println("pdfName = "+ pdf_name);
            File file = new File(save_path+"/"+pdf_name);
            FileOutputStream fileOS = new FileOutputStream(file);
            doc.save(fileOS, SaveFormat.PDF);
            long now = System.currentTimeMillis();
            System.out.println("共耗时:" + ((now - old) / 1000.0) + "秒\n\n" + "文件保存在:" + file.getPath());
        } catch (Exception e) {
            e.printStackTrace();
     * @param args
    public static void main(String[] args) {
    	String file_path = args[0];
    	String save_path = args[1];
    	word2pdf(file_path,save_path);
//    	word2pdf("C:\\Users\\16616\\Desktop\\XXX.docx","C:/Users/16616/Desktop");

将含有第三方jar包的Java项目打包,并且使用命令行进行jar包的传参调用:
1.首先,Eclipse将已经含有第三方jar包的项目打包的方法:
File/Export…然后Java/Runnable JAR file,然后选要运行的有main()的类,选extract required libraries into generated JAR
在这里插入图片描述在这里插入图片描述

2.找到打包后的文件,将待转换的word文件放到jar包的同级目录下,如果想要将转换后的PDF文件放到word文件的同级:

命令行调用jar包方法:
java -jar word2pdf.jar [路径下的word文件名][PDF目标路径]
在这里插入图片描述最后会在该文件夹下生成一个pdfed.pdf文件。

:如何命令行传参调用java项目(或在bat文件中调用)

  1、无参
   打开jar包所在目录,输入 java -jar xxx.jar
  2、有参
  打开jar包所在目录   输入  java -jar xxx.jar 参数1 参数2 ……(参数间用空格隔开)
  对应main函数中的:
	public static void main(String[] args) {	    
	    String sourcePath = args[0];// 参数1 
	    String targetPath = args[1];// 参数2 

项目的源代码jar包以及使用方法已经放在了公众号下,后台回复关键词【word2pdf】即可获取。

[1] how-to-convert-word-doc-to-pdf-in-linux
[2] 将java项目导出为jar包+导出第三方jar包+使用命令行调用+传参
[3] aspose-words-15.8.0 完美解决word转pdf
[4] 怎样把引用的jar包和本项目一起导出成jar文件

最近在做word报表的自动生成,甲方要求要有pdf格式,且对样式要求特别严格。 上网搜了很多,发现在对word样式要求特别高的情况下,用libreoffice是特别好的选择。 基本上几秒钟10多页就出来。如果对样式要求不高,可以尝试其他的方法。 步骤...... server代码: window上的服务器代码不变,但是需要注意一点:linux上的client连接服务器上的server时服务器的防火墙必须关闭才能连接成功。 #define WIN32_LEAN_AND_MEAN #define _WINSOCK_DEPRECATED_NO_WARNINGS #include<windows.h> #include<WinSock2.h> #include<stdio.h> #include <vector> 将win10电脑上的字体上传至服务器,打包 c:\windows\Fonts 为Fonts.zip 一定要是zip格式哦,rar在linux一般是解不了的。将下载的文件解压上传至网站目录,如果放到网站目录之外的,要注意将防跨站的.user.ini里的配置目录修改。Unoconv.binaries为你的unoconv的路径,注意这里需要有可执行权限,否则无法运行。如果你过的PDF发现字体不对或乱码,有变形说明你的服务器上没有相应的字体。注意将代码中的路径换成自己的即可。至此就可以将word换为图片。... 下载并安装unoconv: wget http://pkgs.repoforge.org/unoconv/unoconv-0.4-1.el5.rf.noarch.rpm rpm -ivh unoconv-0.4-1.el5.rf.noarch.rpm 在短信猫的开发过程中遇到了很多问题,在此进行记录,以供大家作为参考。一、Error 0x5 at ..\src\termios.c(892): 拒绝访问原因:1.串口被占用2.串口不存在解决办法:1.系统的管理器中,查看串口是否存在,不存在进行更换。2.如果串口存在,查看是否有其他的程序正在打开,占用了该串口(例如串口测试工具等,我就是这个问 题)。二、... 其中soffice为libreoffice下的soffice.exe,控制台指令中路径不能存在空格,文件的路径和输出路径均不能存在空格,出现空格则会失效。“inputFile”和“pdfFile”分别为输入文件和导出的pdf文件。 目前常见的实现wordpdf的方式有两种,第一种是使用第三方插件安装调用;第二种是使用免费的jar包。但两种方式均有利有弊。安装第三方插件很明显需要安装插件,然后还要收费。第二种免费的jar包,一来比较难以寻找,二来免费的一般都是比较鸡肋,对机器环境、jdk都要求比较高。毕竟好多在线换网站支持wordpdf的(https://app.xunjiepdf.com/word2pdf/)其换效果都很粗糙,错行格式变异也是日常结果。那么对于要实现wordpdf的需求,如何采用最小的代价来实现呢? 一、PHP使用openoffice实现office在线PDF介绍 最近需要在网页上实现预览上传的word文档,之前没有实现过相关功能,搜索了一下网上的资料,完整的教程较少,因此将自己实现的步骤和遇到的问题记录下来,希望能帮到有需要的人 1.目前前端只能实现在线预览pdf格式的文件,可以用pdf.js或者jquery.media.js来实现。 2.要实现其他格式的文件预览,需要在后端进行格式换。 3.目前我了解到的后端对office文档格式的换方法有: a、先换成swf格式->在换成pdf