【问题标题】:Headless LibreOffice very slow to export to PDF on Windows (6 times slow than on Linux)Headless LibreOffice 在 Windows 上导出为 PDF 非常慢(比 Linux 慢 6 倍)
【发布时间】:2020-08-10 08:18:24
【问题描述】:

我经常需要使用 LibreOffice 将许多 (> 1000) 个 .docx 文档导出为 PDF。这是一个示例文档:test.docx。以下代码有效,但在 Windows 上运行速度很慢(每个 PDF 文档平均需要 3.3 秒):

import subprocess, docx, time   # first do: pip install python-docx 
for i in range(10):
    doc = docx.Document('test.docx')
    for paragraph in doc.paragraphs:
        paragraph.text = paragraph.text.replace('{{num}}', str(i))
    doc.save('test%i.docx' % i)   # these 4 previous lines are super fast - a few ms
    t0 = time.time()
    subprocess.call(r'C:\Program Files\LibreOffice\program\soffice.exe --headless --convert-to pdf test%i.docx --outdir . --nocrashreport --nodefault --nofirststartwizard --nolockcheck --nologo --norestore"' % i)
    print('PDF generated in %.1f sec' % (time.time()-t0))

    # for linux:
    # (0.54 seconds on average, so it's 6 times better than on Windows!)
    # subprocess.call(['/usr/bin/soffice', '--headless', '--convert-to', 'pdf', '--outdir', '/home/user', 'test%i.docx' % i])  

如何在 Windows 上加快 PDF 导出速度?

我怀疑很多时间会浪费在"Start LibreOffice/Writer, (do the job), Close LibreOffice" "Start LibreOffice/Writer, (do the job), Close LibreOffice" "Start LibreOffice/Writer, (do the job), Close LibreOffice" 等上。

注意事项:

  • 作为比较:这里:https://bugs.documentfoundation.org/show_bug.cgi?id=92274 据说导出时间是 90 毫秒或 810 毫秒。

  • soffice.exe 替换为 swriter.exe:同样的问题:平均 3.3 秒

    subprocess.call(r'C:\Program Files\LibreOffice\program\swriter.exe --headless --convert-to pdf test%i.docx --outdir ."' % i)
    

【问题讨论】:

  • 在 macOS 和 Linux 上相同

标签: python pdf docx libreoffice


【解决方案1】:

确实,所有时间都浪费在启动/退出 LibreOffice 上。我们可以改为一次调用 soffice.exe 传递许多 docx 文档:

import subprocess, docx
for i in range(1000):
    doc = docx.Document('test.docx')
    for paragraph in doc.paragraphs:
        paragraph.text = paragraph.text.replace('{{num}}', str(i))
    doc.save('test%i.docx' % i)

# all PDFs in one pass:
subprocess.call(['C:\Program Files\LibreOffice\program\swriter.exe', 
    '--headless', '--convert-to', 'pdf', '--outdir', '.'] + ['test%i.docx' % i for i in range(1000)])

总共 107 秒,因此每个 PDF 平均大约 107 毫秒,要好得多!

注意事项:

  • 它不适用于 10,000 个文档,因为命令行参数的长度将超过 32k 个字符,如 explained here

  • 我想知道是否有可能以一种更具交互性的方式来使用 LibreOffice 无头:

    • 无头启动 Writer,保持启动
    • 向此进程发送类似open test1.docx 的操作
    • 发送动作export to pdf,然后关闭docx
    • 发送open test2.docx,然后导出等
    • ...
    • 无头退出 Writer

       

    这适用于带有 MS Office 的 COM(组件对象模型):.doc to pdf using python,但我想知道 LibreOffice 是否存在类似的东西。答案似乎是否定的:Does LibreOffice/OpenOffice Support the COM Model

【讨论】:

  • 发布了一个无需重启soffice即可处理多个文档的解决方案:stackoverflow.com/a/61466307/5100564.
  • 您可以将 LibreOffice 作为服务启动并使用它而无需启动/退出时间。 github.com/unoconv/unoserver
  • @nhuanvd 这真是个好主意,您可以将其发布为新答案吗?我认为它会很有趣,以供将来参考。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-12-23
  • 2016-12-23
  • 2010-12-17
  • 1970-01-01
  • 1970-01-01
  • 2018-02-27
  • 2018-06-29
相关资源
最近更新 更多