CSDN是个开放交流的地方,我遇到这个问题的时候我第一时间就来看看有没有老哥已经解决了并且给出了详细的步骤。然而,让我比较失望的是,相关的文章比较多,但是大家都说的很模糊,或者只是解释了部分问题,还有很多对新手来说比较重要的步骤都一笔带过了。很僵~ 所以笔者花了几个小时,从头到尾,把所有的坑都踩了一遍,记录在这里,供后来的萌新们学习借鉴。
我的场景是这样的,我们的业务会有用户上传word文档到服务器,服务器需要将word转为pdf,然后使用CA签名,我们的服务端主要使用php语言,服务器是CentOS7.2的阿里云ESC,所以我打算使用php的系统调用来调起java服务模块进行文档转换工作。
下面介绍我操作的详细步骤:
1,安装java环境
控制台输入命令(需要sudo -s): yum install jre java-devel
2,下载安装ApacheOpenOffice
官网地址:http://www.openoffice.org/
点击 download标签,选择合适的包,RH和CentOS的系统选择我图上的版本就ok了,我用的是简体中文版,怕装逼下了英文版结果自己看不懂,那就很打脸了。
我是在mac上下载的,拿到他的下载路径之后,去服务器上,用wget命令直接下载到服务器,可以在指定目录下输入下面的命令下载
下载完后解压,我是在/home/app/目录下执行的,解压后得到了zn-CN
解压命令:tar -zxvf 文件名
官方给的安装指引如下:
大致的意思就是,进入文件夹(zh-CN),执行rpm -Uvih *rpm就可以完成全部的依赖安装,默认安装在/opt目录下,里面有个desktop-integration是桌面可视化的GUI,因为我需要在代码中调用,就没装这个了,感兴趣可以试试!
安装完成后可以通过如下命令来启动OpenOffice:
/opt/openoffice4/program/soffice -headless -accept="socket,host=127.0.0.1,port=8100;urp;" -nofirststartwizard
占用的是8100端口,如果冲突了可以改为其他端口执行,可以通过下面的命令来查询指定端口占用情况:
netstat -lnp | grep 8100
可以通过下面的命令来看看是否有OpenOffice的进程在执行
ps -ef |grep office
3,编写java脚本来调用OpenOffice
JodConvert 官网地址 https://sourceforge.net/projects/jodconverter/files/JODConverter/
同样的套路,我拿到了下载地址,在服务器上下载了该包:
wget https://nchc.dl.sourceforge.net/project/jodconverter/JODConverter/2.2.2/jodconverter-2.2.2.zip
解压命令: unzip 文件名(如果没有unzip的话可以使用 yum install unzip直接安装)
解压之后进入目录,有用的包都在lib里面,直接拷贝去java的工作目录下的src文件夹,我的java工作目录为/home/app/office,所以我拷贝的命令为:cp -r lib/ /home/app/office/src/
进入我的java工作目录,准备搞事,新建个OfficeHandler.java,所有要用到的jar包都在src中
src中的内容如下,cli是不用引入的
jodConvert是一个jar包,就是专门用来调用OpenOffice的,本人不是一个专职的javaer,在OfficeHandler.java中简单写了下面的代码来测试一下,功能很简单,从console接受两个参数,一个是输入的doc文件,一个是输出的指定的pdf文件名,成功返回ok,失败返回错误信息,注意文件读写的目录要赋予相应的权限
import com.artofsolving.jodconverter.DocumentConverter; import com.artofsolving.jodconverter.openoffice.connection.OpenOfficeConnection; import com.artofsolving.jodconverter.openoffice.connection.SocketOpenOfficeConnection; import com.artofsolving.jodconverter.openoffice.converter.OpenOfficeDocumentConverter; import java.io.File; public class OfficeHandler { public static void main(String[] args) { String input_file = args[0]; String output_file = args[1]; try { OpenOfficeConnection connection = new SocketOpenOfficeConnection("127.0.0.1", 8100); connection.connect(); DocumentConverter converter = new OpenOfficeDocumentConverter(connection); File in = new File("/server/php-server/public/office/in/"+input_file); File out = new File("/server/php-server/public/office/out/"+output_file); converter.convert(in,out); connection.disconnect(); System.out.println("ok"); }catch (Exception e) { System.out.println("error"+e.getMessage()); } } }
写完了记得保存退出
接下来就是要编译执行了,先编译,进入java工作目录/home/app/office/,命令如下:
javac -cp .:src/jodconverter-2.2.2.jar:src/jurt-3.0.1.jar:src/slf4j-jdk14-1.5.6.jar:src/commons-io-1.4.jar:src/ridl-3.0.1.jar:src/unoil-3.0.1.jar:src/juh-3.0.1.jar:src/slf4j-api-1.5.6.jar:src/xstream-1.3.1.jar OfficeHandler.java
配置过java环境变量的人应该对这些.:什么的不陌生,不再多解释,感兴趣可以专门找找java编译的文章看看,上面的命令大概意思就是,我build这个OfficeHandler.java,引入了一系列jar包。
编译完成在工作目录上会得到一个OfficeHandler.class,我之前图上大码的就是这个。
ok,编译完了要测试执行,我在输入目录里上传了一份文档叫123456.doc,希望输出654321.pdf,执行下面的命令:
java -cp .:/home/app/office/src/jodconverter-2.2.2.jar:/home/app/office/src/jurt-3.0.1.jar:/home/app/office/src/slf4j-jdk14-1.5.6.jar:/home/app/office/src/commons-io-1.4.jar:/home/app/office/src/ridl-3.0.1.jar:/home/app/office/src/unoil-3.0.1.jar:/home/app/office/src/juh-3.0.1.jar:/home/app/office/src/slf4j-api-1.5.6.jar:/home/app/office/src/xstream-1.3.1.jar:/home/app/office OfficeHandler 123456.doc 654321.pdf
因为执行命令可以在任何目录下,所以需要在引入的包中带上绝对路径,注意最后加了个:/home/app/office ,是为了让java可以找到OfficeHandler.class
执行成功,工作目录中已经看到了这个输出文件,但是问题来了,我文档是中文的,但是却没有内容,表格的框架都在,作为多年踩坑的码农,用脚都想出来是字体问题了!
4 解决pdf乱码和中文不显示问题
先看系统的字体库中有什么,命令行都在截图里。
系统自带的字体少的可怜,怎么能hold住强大的office呢?二话不说,网上找找有没有现成的字体包。
然而,很多都是exe文件,是压缩包的就很不全面,csdn的资源也是。没办法,我想到的我mac上的office2016是不是可以派上用场了,于是我打包了我的字体库,上传到服务器/user/share/fonts/目录下,新建了个back目录,把所有字体文件都扔进去了
我自己的cnd不方便公开,上传到csdn资源了,竟然不能选择免c币,有点坑:
字体库压缩包:http://download.csdn.net/download/liangxun0712/10247865
把之前的soffice进程使用ps -ef |grep office查找出来 根据id kill掉,然后新启动即可,现在转换出来的pdf有内容了,也没乱码了