如何通过命令行设置LibreOffice文档自定义变量/属性并生成PDF
问题描述
已成功通过命令行将ODT文件转换为PDF,命令如下:
soffice --headless --convert-to pdf:"writer_pdf_Export:SelectPdfVersion=1" --outdir outdir testDocument.odt
但文档中包含通过字段插入的用户自定义变量(user defined variables),希望通过命令行设置这些变量的值,使生成的PDF包含正确文本;也可改用自定义属性(custom properties),但同样需要通过CLI设置。
尝试的以下命令执行失败:
soffice --headless --convert-to "odt:{\"Version\":{\"type\":\"string\",\"value\":\"1.0\"}}" ReadMe.odt
报错信息:
convert /home/queeg/ReadMe.odt -> /home/queeg/ReadMe.odt using filter : {"Version":{"type":"string","value":"1.0"}} Overwriting: /home/queeg/ReadMe.odt Error: Please verify input parameters... (SfxBaseModel::impl_store <file:///home/queeg/ReadMe.odt> failed: 0x81a(Error Area:Io Class:Parameter Code:26) ./sfx2/source/doc/sfxbasemodel.cxx:3202 ./sfx2/source/doc/sfxbasemodel.cxx:1775)
另一个命令未报错,但既未设置自定义属性Version,也未设置自定义变量Version:
soffice --headless --convert-to "pdf:draw_pdf_Export:{“Version”:{“type”:“string”,“value”:“draft”}}" ReadMe.odt
执行输出:
convert /home/queeg/ReadMe.odt -> /home/queeg/ReadMe.pdf using filter : draw_pdf_Export:{“Version”:{“type”:“string”,“value”:“draft”}} Overwriting: /home/queeg/ReadMe.pdf
需要实现通过命令行设置自定义变量/属性后转换为PDF的需求。
解决方案
LibreOffice/OpenOffice的soffice命令行工具本身不支持直接通过--convert-to的过滤参数设置文档自定义变量或属性,需要借助宏脚本结合命令行来实现,以下是两种可行方案:
方案1:使用Basic宏设置属性并转换PDF
- 创建一个Basic宏,用于设置文档的自定义属性并导出为PDF,示例代码如下(保存为
SetProperties.xba):
Sub SetAndExportPDF(sVersion As String) Dim oDoc As Object Dim oProps As Object Dim args(1) As New com.sun.star.beans.PropertyValue ' 获取当前文档 oDoc = StarDesktop.CurrentComponent ' 访问文档自定义属性 oProps = oDoc.DocumentProperties.UserDefinedProperties ' 设置自定义属性Version If oProps.hasByName("Version") Then oProps.setPropertyValue("Version", sVersion) Else oProps.addProperty("Version", com.sun.star.beans.PropertyAttribute.MAYBEVOID Or com.sun.star.beans.PropertyAttribute.REMOVABLE, sVersion) End If ' 刷新文档字段(如果使用的是引用自定义属性的字段) oDoc.refresh() ' 设置导出PDF的参数 args(0).Name = "FilterName" args(0).Value = "writer_pdf_Export" args(1).Name = "SelectPdfVersion" args(1).Value = 1 ' 导出PDF到指定路径 oDoc.storeToURL("file:///home/queeg/ReadMe.pdf", args()) oDoc.close(True) End Sub
- 通过命令行加载宏文件并执行:
soffice --headless --macro "SetProperties.SetAndExportPDF(\"1.0\")" ReadMe.odt
方案2:使用Python脚本调用LibreOffice API
通过Python直接调用LibreOffice的UNO API,更灵活地控制文档属性和转换流程,示例代码如下:
import uno from com.sun.star.beans import PropertyValue def set_version_and_export(odt_path, pdf_path, version): local_context = uno.getComponentContext() resolver = local_context.ServiceManager.createInstanceWithContext( "com.sun.star.bridge.UnoUrlResolver", local_context ) ctx = resolver.resolve("uno:socket,host=localhost,port=2002;urp;StarOffice.ComponentContext") smgr = ctx.ServiceManager desktop = smgr.createInstanceWithContext("com.sun.star.frame.Desktop", ctx) # 打开文档 doc_url = uno.systemPathToFileUrl(odt_path) doc = desktop.loadComponentFromURL(doc_url, "_blank", 0, ()) # 设置自定义属性 props = doc.DocumentProperties.UserDefinedProperties if props.hasByName("Version"): props.setPropertyValue("Version", version) else: props.addProperty("Version", 0, version) # 刷新字段 doc.refresh() # 导出PDF pdf_url = uno.systemPathToFileUrl(pdf_path) export_props = [] prop = PropertyValue() prop.Name = "FilterName" prop.Value = "writer_pdf_Export" export_props.append(prop) prop = PropertyValue() prop.Name = "SelectPdfVersion" prop.Value = 1 export_props.append(prop) doc.storeToURL(pdf_url, tuple(export_props)) doc.close(True) if __name__ == "__main__": # 先启动LibreOffice服务 import subprocess subprocess.Popen(["soffice", "--headless", "--accept=socket,host=localhost,port=2002;urp;"]) # 执行设置和导出 set_version_and_export("/home/queeg/ReadMe.odt", "/home/queeg/ReadMe.pdf", "1.0")
执行该Python脚本即可完成自定义属性设置和PDF转换。
关键说明
- 如果文档中使用的是用户自定义变量(而非自定义属性),宏或脚本中需要修改为访问
oDoc.TextFields.UserDefined集合来设置变量值,逻辑类似。 - 确保LibreOffice启用了宏支持,必要时可在命令行中添加
--enable-macros参数。
内容的提问来源于stack exchange,提问作者queeg
相关产品推荐
相关产品推荐

