Word 转 PDF,且需要能够在 Linux 上部署
1.docx
(0118)
|
实现方案
|
优点
|
缺点
|
软件占用空间
|
|
win32com
|
效果最好
|
不支持 Linux
|
1 GB 以上
|
|
comtypes
|
效果最好
|
不支持 Linux
|
1 GB 以上
|
|
docx2pdf
|
效果最好
|
不支持 Linux
|
1 GB 以上
|
|
AbiWord
|
占用空间小,安装方便
|
不支持 Windows,导出可能不完整
|
69.4 MB
|
|
LibreOffice
|
支持 Windows 和 Linux
|
效果一般,安装麻烦
|
585 MB
|
wvPDF
|
无
|
效果很差,兼容很差
|
247 MB
|
aspose-words
|
速度快
|
收费,有水印
|
50.6 MB
|
unoconv
|
无
|
效果较差,且有坑
|
306 MB
|
|
阿里云市场易源数据API
|
速度快
|
效果较差,收费
|
0
|
|
九云图API
|
效果好
|
文档需先上传为url,字体貌似需要不可多样化,收费
|
0
|
|
WPS+pywpsrpc
|
效果好
|
首次运行需要界面,安装麻烦
|
350 MB 以上
|
Linux 环境下建议使用 WPS+pywpsrpc
from pathlib import Path
from win32com.client import Dispatch, constants, gencache
docx_path = str(Path('1.docx').absolute())
pdf_path = str(Path('1.pdf').absolute())
gencache.EnsureModule('{00020905-0000-0000-C000-000000000046}', 0, 8, 4)
wd = Dispatch('Word.Application')
doc = wd.Documents.Open(docx_path, ReadOnly=1)
doc.ExportAsFixedFormat(pdf_path, constants.wdExportFormatPDF, Item=constants.wdExportDocumentWithMarkup,
CreateBookmarks=constants.wdExportCreateHeadingBookmarks)
wd.Quit(constants.wdDoNotSaveChanges)
| 第一页 | 第二页 |
|---|
 |  |
优点:代码简洁,效果好
缺点:需要安装Microsoft Word,不支持 Linux
pip install comtypes
from pathlib import Path
import comtypes.client
word = comtypes.client.CreateObject('Word.Application')
doc = word.Documents.Open(str(Path('1.docx').absolute()))
wdFormatPDF = 17
doc.SaveAs(str(Path('1.pdf').absolute()), FileFormat=wdFormatPDF)
doc.Close()
word.Quit()
| 第一页 | 第二页 |
|---|
 |  |
优点:代码简洁,效果好
缺点:需要安装Microsoft Word,不支持 Linux
wdFormatPDF 的值为 17 查阅 WdSaveFormat enumeration
原理是调用 Microsoft Word,所以必须安装
pip install docx2pdf
docx2pdf 1.docx
from docx2pdf import convert
convert('1.docx')
print('转换完成')
| 第一页 | 第二页 |
|---|
 |  |
优点:速度快,效果好
缺点:需要安装Microsoft Word,不支持 Linux
Linux 安装
sudo apt-get install abiword
abiword -t pdf 1.docx
from subprocess import Popen
file = '1.docx'
Popen(['abiword', '-t', 'pdf', file]).communicate()
print('转换完成')
命令行参数详细阅读:Command line options
优点:占用空间小,安装方便
缺点:不支持 Windows,导出可能不完整
安装 LibreOffice
添加环境变量 PATH:C:\Program Files\LibreOffice\program
soffice.exe --convert-to pdf 1.docx
from subprocess import Popen
file = '1.docx'
Popen(['soffice.exe', '--convert-to', 'pdf', file]).communicate()
print('转换完成')
从 Index of libreoffice 找到合适的文件(x.x.x 指具体的版本,如 7.1.8)
LibreOffice_x.x.x_Linux_x86-64_deb.tar.gz
LibreOffice_x.x.x_Linux_x86-64_deb_sdk.tar.gz
LibreOffice_x.x.x_Linux_x86-64_deb_langpack_zh-CN
mkdir -p ~/download/libreoffice/deb
cd ~/download/libreoffice
wget http://mirrors.ustc.edu.cn/tdf/libreoffice/stable/7.1.8/deb/x86_64/LibreOffice_7.1.8_Linux_x86-64_deb.tar.gz
wget http://mirrors.ustc.edu.cn/tdf/libreoffice/stable/7.1.8/deb/x86_64/LibreOffice_7.1.8_Linux_x86-64_deb_sdk.tar.gz
wget http://mirrors.ustc.edu.cn/tdf/libreoffice/stable/7.1.8/deb/x86_64/LibreOffice_7.1.8_Linux_x86-64_deb_langpack_zh-CN.tar.gz
tar -zxvf LibreOffice_7.1.8_Linux_x86-64_deb.tar.gz -C deb
tar -zxvf LibreOffice_7.1.8_Linux_x86-64_deb_sdk.tar.gz -C deb
tar -zxvf LibreOffice_7.1.8_Linux_x86-64_deb_langpack_zh-CN.tar.gz -C deb
sudo dpkg -i LibreOffice_7.1.8.1_Linux_x86-64_deb/DEBS/*.deb
sudo dpkg -i LibreOffice_7.1.8.1_Linux_x86-64_deb_sdk/DEBS/*.deb
sudo dpkg -i LibreOffice_7.1.8.1_Linux_x86-64_deb_langpack_zh-CN/DEBS/*.deb
soffice --headless --convert-to pdf 1.docx
libreoffice --headless --convert-to pdf 1.docx
删除安装包
rm -r ~/download/libreoffice
TODO:卸载(要一个个删,很多)
dpkg -l | grep LibreOffice
sudo dpkg -r xxx
详细阅读:LibreOffice command line parameters
指定保存位置(不含文件名):--outdir
sudo
apt-get install wv texlive-base texlive-latex-base ghostscript
wvPDF 1.docx 1.pdf
效果:这份文档无法导出
pip install aspose-words
import aspose.words as aw
doc = aw.Document('1.docx')
doc.save('1.pdf')
print('转换完成')
sudo apt-get install unoconv
unoconv -fpdf 1.docx
doc2pdf 1.docx
import base64
import requests
encoded = base64.b64encode(open('1.docx', 'rb').read())
url = 'https://word2pdf.showapi.com/word2pdf'
appcode = '你的AppCode'
headers = {
'Authorization': 'APPCODE ' + appcode,
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
r = requests.post(url, data={'base64': encoded}, headers=headers, verify=False)
print(r)
print(r.json()['showapi_res_body']['url'])
创建转换任务
import json
import requests
url = 'https://api.docsdk.com/v2/jobs'
apiKey = '你的apiKey'
data = {
'tasks': {
'ImportURL': {
'operation': 'import/url',
'url': 'https://image2.9yuntu.cn/resources/api/九云图API使用说明.docx'
'ConvertFile': {
'input': ['ImportURL'],
'operation': 'convert',
'output_format': 'pdf'
'ExportResult': {
'input': ['ConvertFile'],
'operation': 'export/url'
headers = {
'Authorization': 'Bearer ' + apiKey,
'Content-Type': 'application/json'
r = requests.post(url, data=json.dumps(data), headers=headers)
print(r)
result = r.json()
print(result)
print(result['data']['status'])
print(result['data']['job_id'])
主动查询转换结果(复制上一步的 job_id)
import requests
jobId = '上一步的job_id'
url = f'https://api.docsdk.com/v2/jobs/{jobId}'
apiKey = '你的apiKey'
headers = {
'Authorization': 'Bearer ' + apiKey
r = requests.get(url, headers=headers)
print(r)
result = r.json()
print(result)
status = result['data']['status']
print(status)
if status == 'finished':
tasks = result['data']['tasks']
for task in tasks:
files = task['result']['files']
print(task['id'], task['status'], str(task['percent']) + '%')
for index, file in enumerate(files):
print(index, file['filename'], file.get('url', '无下载地址'))
安装 Python SDK
pip install docsdk
import docsdk
docsdk.configure(api_key='你的apiKey')
payload = {
'tasks': {
'ImportURL': {
'operation': 'import/url',
'url': 'https://image2.9yuntu.cn/resources/api/九云图API使用说明.docx'
'ConvertFile': {
'input': ['ImportURL'],
'operation': 'convert',
'output_format': 'pdf',
'ExportResult': {
'input': ['ConvertFile'],
'operation': 'export/url'
res = docsdk.Job.create(payload=payload)
print(res)
job_id = res['id']
res = docsdk.Job.wait(
job_id)
file = res['tasks'][-1]['result']['files'][0]
filename = docsdk.download(url=file['url'], filename=file['filename'])
print(filename)
| 第一页 | 第二页 |
|---|
 |  |
此方法需要 X11
查看是否已安装 X11
dpkg -l | grep xserver-xorg-core
查看是否开启 X11
cat /etc/ssh/sshd_config | grep X11Forwarding
dpkg --print-architecture
根据架构下载 WPS Office 2019 for Linux,如本人为 amd64,选择 X64

安装(本人实际安装的是wget https://wdl1.pcfg.cache.wpscdn.com/wpsdl/wpsoffice/download/linux/10920/wps-office_11.1.0.10920.XA_amd64.deb,以下为新版)
mkdir -p ~/download/wps
cd ~/download/wps
wget https://wdl1.cache.wps.cn/wps/download/ep/Linux2019/10920/wps-office_11.1.0.10920_amd64.deb
sudo dpkg -i wps-office_11.1.0.10920_amd64.deb
sudo apt-get install qt5-default
pip3 install pywpsrpc
wget https://raw.githubusercontent.com/timxx/pywpsrpc/master/examples/rpcwpsapi/convertto/convertto.py
打开 WPS(应该是中文的)
wps 1.docx
弹出,同意即可(如果没有弹出,要装 X11,阅读 Linux安装X11实现GUI)


命令行
python3 convertto.py -f pdf 1.docx
这时可能会报错,再运行一次即可
Convert failed:
Details: Can't get the application
ErrCode: 0x80000008

也有可能因为网络问题渲染画面迟迟才出来报错
安装无界面模式
sudo apt install xserver-xorg-video-dummy
vim dummy.conf
输入以下内容
Section "Monitor"
Identifier "dummy_monitor"
HorizSync 28.0-80.0
VertRefresh 48.0-75.0
Modeline "1920x1080" 172.80 1920 2040 2248 2576 1080 1081 1084 1118
EndSection
Section "Device"
Identifier "dummy_card"
VideoRam 256000
Driver "dummy"
EndSection
Section "Screen"
Identifier "dummy_screen"
Device "dummy_card"
Monitor "dummy_monitor"
SubSection "Display"
EndSubSection
EndSection
启动虚拟界面
X :0 -config dummy.conf
另外开一个 SSH,实现无界面运行
export DISPLAY=localhost:0.0
echo $DISPLAY
python3 convertto.py -f pdf 1.docx
| 第一页 | 第二页 |
|---|
 |  |
删除安装包
rm -r ~/download/wps
dpkg -l | grep wps-office
sudo dpkg -r wps-office
sudo apt-get --purge remove wps-office
创建 X11 的配置文件 xorg.conf
sudo vim /usr/share/X11/xorg.conf.d/xorg.conf
填入内容,具体含义见 xorg.conf
Section "Monitor"
Identifier "dummy_monitor"
HorizSync 28.0-80.0
VertRefresh 48.0-75.0
Modeline "1920x1080" 172.80 1920 2040 2248 2576 1080 1081 1084 1118
EndSection
Section "Device"
Identifier "dummy_card"
VideoRam 256000
Driver "dummy"
EndSection
Section "Screen"
Identifier "dummy_screen"
Device "dummy_card"
Monitor "dummy_monitor"
SubSection "Display"
EndSubSection
EndSection
创建子进程配置文件
sudo vim /etc/supervisor/conf.d/X11.conf
[program:X11]
command=X :0 -config /usr/share/X11/xorg.conf.d/xorg.conf
autostart=true
autorestart=true
startsecs=10
stdout_logfile=/tmp/X11.stdout.log
stderr_logfile=/tmp/X11.stderr.log
重新读取配置并更新子进程
supervisorctl reread
supervisorctl update
查看进程状态
ps -ef | grep Xorg
supervisorctl status | grep X11
import os
import argparse
from pathlib import Path
from pywpsrpc.common import S_OK
from pywpsrpc.rpcwpsapi import wpsapi, createWpsRpcInstance
os.environ['DISPLAY'] = ':0.0'
formats = {
'doc': wpsapi.wdFormatDocument,
'docx': wpsapi.wdFormatXMLDocument,
'rtf': wpsapi.wdFormatRTF,
'html': wpsapi.wdFormatHTML,
'pdf': wpsapi.wdFormatPDF,
'xml': wpsapi.wdFormatXML,
class ConvertException(Exception):
def __init__(self, text, hr):
self.text = text
self.hr = hr
def __str__(self):
return 'Convert failed:\nDetails: {}\nErrCode: {}'.format(self.text, hex(self.hr & 0xFFFFFFFF))
def convert_to(paths, format='pdf'):
hr, rpc = createWpsRpcInstance()
if hr != S_OK:
raise ConvertException('Can not create the rpc instance', hr)
hr, app = rpc.getWpsApplication()
if hr != S_OK:
raise ConvertException('Can not get the application', hr)
app.Visible = False
docs = app.Documents
for path in paths:
path = Path(path)
if path.is_file():
hr, doc = docs.Open(str(path.absolute()), ReadOnly=True)
if hr != S_OK:
raise ConvertException('can not open file {}'.format(path.name), hr)
new_file = '{}.{}'.format(path.parent / path.stem, format)
hr = doc.SaveAs2(new_file, FileFormat=formats[format])
if hr != S_OK:
raise ConvertException('convert_file failed', hr)
doc.Close(wpsapi.wdDoNotSaveChanges)
app.Quit()
if __name__ == '__main__':
parser = argparse.ArgumentParser()
parser.add_argument('path', nargs='+')
args = parser.parse_args()
paths = args.path
print(paths)
try:
convert_to(paths)
print('转换完成')
except ConvertException as e:
print(e)
1. 报错 NotImplementedError: docx2pdf is not implemented for linux as it requires Microsoft Word to be installed
docx2pdf 不能在 Linux 上运行
2. 报错 unoconv: Cannot find a suitable pyuno library and python binary combination in /usr/lib/libreoffice
sudo vim /usr/bin/unoconv
#!/usr/bin/env python3
#!/usr/bin/python3
3. 报错 The program ‘libreoffice’ is currently not installed. To run ‘libreoffice’ please ask your administrator to install the package ‘libreoffice-common’
sudo apt-get libreoffice-common
4. 报错 Error: source file could not be loaded
sudo apt-get libreoffice-writer
5. WPS 的方案,测试代码能正常转换,部署代码报错 Can not get the application
检查环境变量 PATH 是否添加 WPS 所在目录:/usr/bin
import os
print(os.environ['PATH'])
print('/usr/bin' in os.environ['PATH'])
可能不支持并发多线程
X11 可能不支持不同用户或无 sudo 权限用户使用,Can’t start X11 applications after “su” or “su -” to another user
6. WPS 的方案,报错 convert_file failed ErrCode: 0x80010105
没有写入权限
7. WPS 可能有 BUG,需要切换为多组件模式
设置多组件模式流程:wps → 右上角设置按钮 → Settings → Others → Change window manage mode… → 选择【Multi-Module Mode】



8. Errors were encountered while processing
cd /var/lib/dpkg
sudo mv info info.bak
sudo mkdir info
sudo apt-get update
- pywpsrpc GitHub
- wpsrpc-sdk GitHub
- wps_cpp
- WPS 开放平台
- WPS C++ 集成源码
- WPSOffice二次开发帮助文档
- docx2pdf GitHub
- Converting docx to pdf with pure python (on linux, without libreoffice)
- LibreOffice command line parameters
- How to convert Word (doc) to PDF in linux
- unoconv: Cannot find a suitable pyuno library and python binary combination · Issue #49 · unoconv/unoconv
- AbiWord vs LibreOffice 2022 Comparison
- Linux 下的LibreOffice安装
- pywpsrpc Run on Server
- Linux deb 软件包管理
- Linux安装X Window服务——远程显示GUI
- linux服务器通过X11实现图形化界面显示
- Error: source file could not be loaded
- Python 中docx转pdf
- comtypes Documentation
- comtypes GitHub
- ubuntu 下使用python操作wps文档和表格
- python 设置linux环境变量
- python 如何设置linux环境变量?
- What is the $DISPLAY environment variable?
- Python实现的进程管理神器——Supervisor
- Where is the X.org config file? How do I configure X there?
- 并发执行文件转换的程序获取不到application
- Can’t start X11 applications after “su” or “su -” to another user
- xserver - What are xhost and xhost +si?
- How can I run /usr/bin/Xorg without sudo?
- /usr/bin/xauth: file /…/.Xauthority does not exist
- Word转PDF-阿里云
- Requests Documentation
- Python图片转base64
- 九云图 - API文档
- docsdk GitHub
from win32com.client import Dispatch, constants, gencache
def doc2pdf(input, output):
w = Dispatch('Word.Application')
# 打开文件
doc = w.Documents.Open(input, ReadOnly=1)
# 转换文件
完整项目资源代码
先上源代码
程序的基本思路是在数据库中存储文件名和他的MD5信息,校验这两个数据,如果数据库里面没有就转换,如果有就不转换,如果文件名有但MD5不同,就要删除原有的数据条目,避免word文档回到旧版本时转换不了
import subprocess
# from win32com.client import gencache
# from win32com.client import constants, gencache
import os
import sys
import
一些重要文档格式之间的互转在目前显得尤为重要,pdf作为通用格式在现在各个平台上兼容性是最好的,所以写python脚本将这些word文档批量转换pdf是最好的解决方案。
由于windows系统对于word文档有天然的兼容性优势,所以转换起来很简单,普遍上是通过comtypes模块。
Python编程中raise可以实现报出错误的功能,而报错的条件可以由程序员自己去定制。在面向对象编程中,可以先预留一个方法接口不实现,在其子类中实现。如果要求其子类一定要实现,不实现的时候会导致问题,那么采用raise的方式就很好。而此时产生的问题分类是NotImplementedError。
写一段代码如下:
class ClassDemo:
def test
使用python脚本完成word转pdf(兼容linux)
参考:https://v3u.cn/a_id_96
起因:看到一个需求是用java把word转成pdf,在windows上使用Jacob可以实现,但linux上比较麻烦, 性能等综合考虑使用OpenOffice比较好。
感觉可以用java调用python脚本实现,这里做个记录。
在原博客中,作者在windows环境下使用了comtypes实现的转换,我本地换成了pywin32实现,另,增加了一个输出目录的参数,用于指
Linux下将word转换为PDF较为费劲,一方面是格式是否正确,另一方面是时间问题,下面简单列出几个工具,比较说明它们的用法和局限性。
1. openoffice+unoconv
2. docx-to-pdf-converter
3. xdocreport
4. aspose-words
openoffice+unoconv
1. 安装
https://www...
您可以使用Python的docx2pdf库将Word文档转换为PDF格式。您需要在Linux环境下安装该库,并使用Python代码调用它来执行转换。以下是一个示例代码:
from docx2pdf import convert
# 将Word文档转换为PDF
convert("input.docx", "output.pdf")
请注意,您需要将“input.docx”替换为您要转换的Word文档的文件名,并将“output.pdf”替换为您要生成的PDF文件的文件名。
selenium.common.exceptions.SessionNotCreatedException: Message: session not created: This version of
申时霁雨:
Python划分图像文件夹为训练集、验证集和测试集——split-folders
PyCharm快捷键大全
是晨星啊: