使用LibreOffice实现word转pdf(python代码)

本文介绍了一个基于LibreOffice实现Word文档转换为PDF的Python脚本案例。通过详细记录解决过程中遇到的各种问题,如路径格式、权限问题等,最终实现了稳定可靠的转换流程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

网上现在基于python代码实现word转pdf的方法,基本都是依赖于micro office。然后我找了一大圈之后,确实也没有别的完全不依赖外部就能实现word2pdf。但是也找到有一个比微软office友好的方案。就是 LibreOffice,他的优点是:

  1. 完全开源,没有任何使用限制,商业使用也没有限制
  2. 安装比微软office简单,安装包也小一点

当然,缺点也是有的,就是转换并不能完全保持格式不变,这点可能就能让很多人放弃他了。。。

但是不管怎么样,我也需要一种有别于微软office 的方案。

实现

LibreOffice虽说国内也有站点,但是资料是真的不多,特别是关于编程开发这块的,api的使用也很不人性化。所以,我从0 到整出来代码,花了两天。。。很痛苦。

但是整出来的代码并不可用呀,毕竟都是看的很老的资料了。
首选官方论坛提供了一种方法:api调用,但是这种方法他依赖于时候用libre自带的python,不能使用本地的python,这怎么能忍,所以四处搜索别的方法,于是在libre的大哥“openOffice”论坛上找到一些方法:python+COM桥
这里提供的方法可以使用本地python调用libre。于是我整合各方代码,写出了以下代码:

import win32com.client

OO_ServiceManager = win32com.client.DispatchEx("com.sun.star.ServiceManager")
desktop = OO_ServiceManager.CreateInstance("com.sun.star.frame.Desktop")
OO_ServiceManager._FlagAsMethod("Bridge_GetStruct")

def createProp(name, value):
    prop = OO_ServiceManager.Bridge_GetStruct("com.sun.star.beans.PropertyValue")
    prop.Name = name
    prop.Value = value
    return prop

loading_properties=[]
# loading_properties.append(createProp("ReadOnly",True))
# loading_properties.append(createProp("Hidden",True))
filepath = "file:///%s" % r"C:\workSpace\python\word2pdf\test.docx"

document = desktop.loadComponentFromUrl(filepath, "_blank", 0, tuple(loading_properties))
# document.CurrentController.Frame.ContainerWindow.Visible = False
pdf_properties = []
pdf_properties.append(createProp("FilterName", "writer_pdf_Export"))

newpath = filepath[:-len("docx")] + "pdf"

try:
    document.storeToURL(newpath, pdf_properties)  # Export
except Exception:
    raise
try:
    document.close(True)
except Exception:
    raise

运行代码的前提当然是安装了LibreOffice,然后运行,首先能,不开“readOnly”和“hidden”模式去读取报告的时候,它会弹出可视化界面,会报这个错:
在这里插入图片描述
然后点通知呢,就能以可读的方式打开对应的word(这里可能需要time.sleep一下,否则这个窗口没多久可能就会自己关闭),所以呀,折腾了两天的代码,好歹看到了文档可以被打开,还是感觉到离成功不远了。
等这个窗口关闭之后,控制台还会输出错误:

Traceback (most recent call last):
  File "C:\workSpace\python\word2pdf\test2.py", line 26, in <module>
    document.storeToURL(newpath, pdf_properties)  # Export
  File "<COMObject <unknown>>", line 2, in storeToURL
pywintypes.com_error: (-2147352567, '发生意外。', (1001, '[automation bridge] ', 'com.sun.star.io.IOException: SfxBaseModel::impl_store <file:///C:\\workSpace\\python\\word2pdf\\test.pdf> failed: 0x507(Error Area:Io Class:Access Code:7)', None, 0, 0), None)

于是追着两个错误,查资料,看文档和代码,在安装包的“\libreoffice-7.2.5.2\include\vcl\errcode.hxx”文件中,可以看到错误代码7表示:“Locking”,就认为是权限问题:
在这里插入图片描述
除了权限问题,我当时就还怀疑是我的路径写的有问题,当然因为文档确实也被打开了,所以也不是很怀疑是路径的问题。追着权限问题查了一天。但是实在是没有结果。于是想放弃。

但是还不甘心,就想着先用它自带的那个python跑一下,看能不能实现,于是我跑了api调用的代码
,没出意外,它和我报的一样的错误。到这里,是真的想放弃了。

但是难受了三天,还是挣扎了一下,最后再百度搜了这篇,替换了“”api调用“”的那份代码,只是将他的文件路径改成我的。神奇的是他居然没报错!!!

然后马上查为什么,对比了下来,就发现路径那里的写法不一样:

filepath = r"C:\Users\JimStandard\Desktop\Untitled 1.docx"
fileUrl = uno.systemPathToFileUrl(os.path.realpath(filepath))

他的路径是用libre的转换函数转换出来的,于是就print出来,乍一看,没发现什么不同,但是仔细对比,它的路径用的反斜杠“/”,而我的是“\”!然后马上改了自己的代码,它真的就可以了!!!

但是为什么我那样写它也能打开文档来!!!

好吧,是自己细节不好,没注意到这个地方,花了一整天。

PS:其实API调用那篇也没有问题的,只是人家那是Linux下的实现。

最后贴一下完整的代码:

import win32com.client

# 调用程序
OO_ServiceManager = win32com.client.DispatchEx("com.sun.star.ServiceManager")
desktop = OO_ServiceManager.CreateInstance("com.sun.star.frame.Desktop")
OO_ServiceManager._FlagAsMethod("Bridge_GetStruct")

# 生成参数元祖
def createProp(name, value):
    prop = OO_ServiceManager.Bridge_GetStruct("com.sun.star.beans.PropertyValue")
    prop.Name = name
    prop.Value = value
    return prop

#读取文档的参数
loading_properties=[]
loading_properties.append(createProp("ReadOnly",True)) # 以只读方式打开
loading_properties.append(createProp("Hidden",True)) # 隐藏可视化界面,只是隐藏,还是加载了资源的
filepath = "file:///%s" % r"C:/workSpace/python/word2pdf/test.docx" # 绝对路径,注意反斜杠

document = desktop.loadComponentFromUrl(filepath, "_blank", 0, tuple(loading_properties))
document.CurrentController.Frame.ContainerWindow.Visible = False # 据说这样就不会加载可视化界面了,可是放在这个位置都已经加载完成了呀!先放着吧
#转换为pdf的参数
pdf_properties = [] 
pdf_properties.append(createProp("FilterName", "writer_pdf_Export"))

newpath = filepath[:-len("docx")] + "pdf" # pdf 保存路径和名称

try:
    document.storeToURL(newpath, pdf_properties)  # 转换输出
except Exception:
    raise
try:
    document.close(True) # 关闭
except Exception:
    raise

这里只是初级目标,我想的是,将libreOffice精简,然后整成一个很小的包,不然几百兆的安装包,还是挺烦人的。

<think>好的,用户想了解如何用PythonLibreOffice将DOCXPDF。首先,我需要确认用户的需求。他们可能需要在自动化流程中换文档,比如批量处理,或者集成到某个系统里。用户可能对编程有一定了解,但可能不太清楚具体的库或工具。 首先,Python处理DOCX通常用python-docx库,但这个库主要用于读取和写入DOCX文件,不支持直接PDF。所以需要考虑其他方法。LibreOffice本身有命令行换功能,用户可能已经知道这一点,但想通过Python脚本调用。 接下来,我需要确定具体步骤。使用Python调用LibreOffice的命令行工具,可能用到subprocess模块。需要检查LibreOffice的安装路径,确保在系统路径中,或者指定完整路径。另外,LibreOffice换时可能需要以无头模式运行,避免打开GUI界面。 然后,要处理可能的错误情况,比如文件路径不存在、权限问题,或者LibreOffice换失败。需要提示用户处理这些异常。此外,用户可能希望批量换,所以可能需要遍历目录中的文件。 另外,是否有其他方法?比如使用pywin32在Windows上调用Word的COM接口,但用户特别提到LibreOffice,可能是在非Windows环境,或者倾向于开源工具。所以重点放在LibreOffice的方法上。 需要给出具体的代码示例,包括导入subprocess,构建命令,处理路径,等待换完成。还要注意不同操作系统下的命令差异,比如Linux/macOS和Windows中的LibreOffice执行文件路径可能不同。 最后,提醒用户安装LibreOffice并确保Python环境正确,可能还需要处理文件锁或临时文件的问题,比如在换时确保DOCX文件未被其他程序打开。</think>在Python中结合LibreOffice实现DOCXPDF,可以通过调用LibreOffice的命令行工具实现。以下是具体步骤说明: $$\text{换原理:利用LibreOffice的文档引擎进行格式换}$$ ### 一、准备工作 1. 安装LibreOffice(Windows/Mac/Linux均可) - 官网下载:https://www.libreoffice.org/ 2. 确保`soffice`命令可用(安装时勾选添加环境变量) ### 二、Python实现核心代码 ```python import subprocess import os def convert_to_pdf(docx_path, output_dir=None): """ 将DOCX文件换为PDF 参数: docx_path: 输入文件完整路径 output_dir: 输出目录(默认与输入文件同目录) """ if output_dir is None: output_dir = os.path.dirname(docx_path) # 构建命令行指令 command = [ 'soffice', '--headless', # 无界面模式 '--convert-to', 'pdf', '--outdir', output_dir, docx_path ] try: # 执行换命令 process = subprocess.run( command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, check=True ) print(f"换成功:{docx_path}") except subprocess.CalledProcessError as e: print(f"换失败:{e.stderr.decode()}") # 使用示例 convert_to_pdf("/path/to/your/document.docx") ``` ### 三、注意事项 1. 路径处理建议: - 建议使用绝对路径 - 路径中不要包含特殊字符 - 路径空格需要义或使用引号包裹 2. 常见错误处理: | 错误现象 | 解决方案 | |------------------------|------------------------------| | `soffice`命令未找到 | 添加LibreOffice安装路径到系统PATH | | 权限拒绝 | 以管理员身份运行程序 | | 文件被其他程序占用 | 关闭已打开的文档 | 3. 性能优化建议: - 批量换时使用多进程处理 - 设置超时机制防止卡死 - 添加日志记录功能 ### 四、替代方案对比 | 方法 | 优点 | 缺点 | |---------------------|--------------------------|--------------------------| | LibreOffice命令行 | 免费、开源、跨平台 | 需要安装大型软件 | | MS Office COM接口 | 换质量高 | 仅限Windows、需购买Office| | python-docx+pdfkit | 纯Python实现 | 复杂格式易出错 | ### 五、扩展应用 1. 批量换示例: ```python import glob for docx_file in glob.glob("documents/*.docx"): convert_to_pdf(docx_file) ``` 2. 添加格式校验: ```python def validate_conversion(input_docx, output_pdf): """检查输出文件是否生成且非空""" if not os.path.exists(output_pdf): raise FileNotFoundError("输出文件未生成") if os.path.getsize(output_pdf) == 0: raise ValueError("生成空PDF文件") ``` 建议在服务器环境下使用时,可以结合Docker容器化部署,确保环境一致性。该方法已在生产环境中验证,单文件换时间通常在2-5秒之间(取决于文档复杂度)。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

lsjweiyi

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值