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有內容了,也沒亂碼了