參考:https://v3u.cn/a_id_96
起因:看到一個需求是用java把word轉成pdf,在windows上使用Jacob可以實現,但linux上比較麻煩, 性能等綜合考慮使用OpenOffice比較好。
感覺可以用java調用python腳本實現,這里做個記錄。
在原博客中,作者在windows環境下使用了comtypes實現的轉換,我本地換成了pywin32實現,另,增加了一個輸出目錄的參數,用於指定生成pdf的路徑。
環境:本地:win10 + jdk1.8 + python3.7 linux服務器:centos7 + jdk1.8 + python3.6
jdk和python3的安裝可百度,這里不做記錄。
具體實現:
1)windows環境安裝comtypes,用於腳本中判斷是windows環境還是linux環境
2)windows環境安裝pywin32庫:pip install pywin32
3)linux中需要使用LibreOffice,安裝依賴:
yum remove libreoffice-*
從https://www.libreoffice.org/download/download/上下載最新版本的linux rpm版本的LibreOffice,上傳到自己的linux環境中,我這里下載的是LibreOffice_6.2.5_Linux_x86-64_ rpm.tar.gz
解壓:tar -zxvf LibreOffice_6.2.5_Linux_x86-64_ rpm.tar.gz
cd LibreOffice_6.2.5.2_Linux_x86-64_rpm/RPMS
yum localinstall *.rpm
4)安裝其他依賴:
yum install cairo cups-libs libSM
yum install ibus
yum install libreoffice-headless
5)查看是否安裝成功:libreoffice -help
6)將window環境字體拷貝至linux中
windows文件夾 C:\\windows\\Fonts文件夾中所有內容拷貝至 linux中/usr/share/fonts/chinese文件夾下,沒有就新建
7)修改字體緩存、權限
chmod -R 755 /usr/share/fonts/chinese
fc-cache -fv
fc-list | grep chinese //查看安裝的新字體
8)linux下測試Libreoffice是否可用
libreoffice6.2 --headless --convert-to pdf /root/xxx.docx ------直接生成在了docx文件同目錄下,有同名的文件會覆蓋掉
libreoffice6.2 --headless --convert-to pdf /root/xxx.docx --outdir /root -------指定了輸出路徑
一切都OK的話,就可以執行腳本了:
import subprocess import os import sys try: from comtypes import client except ImportError: client = None try: from win32com.client import constants, gencache except ImportError: constants = None gencache = None def doc2pdf(docPath, pdfPath): """ convert a doc/docx document to pdf format :param doc: path to document """ docPathTrue = os.path.abspath(docPath) # bugfix - searching files in windows/system32 if client is None:#判斷環境,linux環境這里肯定為None return doc2pdf_linux(docPathTrue, pdfPath) # name, ext = os.path.splitext(doc) # try: # word = client.DispatchEx("Word.Application") # worddoc = word.Documents.Open(doc) # worddoc.SaveAs(name + '.pdf', FileFormat=17) # except Exception: # raise # finally: # worddoc.Close() # word.Quit() word = gencache.EnsureDispatch('Word.Application') doc = word.Documents.Open(docPathTrue, ReadOnly=1) doc.ExportAsFixedFormat(pdfPath, constants.wdExportFormatPDF, Item=constants.wdExportDocumentWithMarkup, CreateBookmarks=constants.wdExportCreateHeadingBookmarks) word.Quit(constants.wdDoNotSaveChanges) def doc2pdf_linux(docPath, pdfPath): """ convert a doc/docx document to pdf format (linux only, requires libreoffice) :param doc: path to document """ cmd = 'libreoffice6.2 --headless --convert-to pdf'.split() + [docPath] + ['--outdir'] + [pdfPath] p = subprocess.Popen(cmd, stderr=subprocess.PIPE, stdout=subprocess.PIPE) p.wait(timeout=30) stdout, stderr = p.communicate() if stderr: raise subprocess.SubprocessError(stderr) if __name__ == '__main__': doc2pdf(sys.argv[1], sys.argv[2])
Java測試代碼如下: