word转pdf遇到的坑

2020-04-21

最近写一个报告模板,最终需要pdf格式,但是不想用latex直接写,感觉太麻烦,最后采取了docxtpl写成word,然后word转为pdf的方法。

原先信心满满,用了pywin32包,利用win32com调用windows的microsoft office进行转换,代码在网上撸了一份:

from win32com.client import Dispatch
import inspect, os
from os import walk

wdFormatPDF = 17


def doc2pdf(input_file):
    word = Dispatch('Word.Application')
    doc = word.Documents.Open(input_file)
    doc.SaveAs(input_file.replace(".docx", ".pdf"), FileFormat=wdFormatPDF)
    doc.Close()
    word.Quit()

另外还考虑到别人使用方便,打算部署到一个小网站上。

遇到哪些坑呢?

  1. 感觉速度有点慢,于是想开多个窗口分别跑不同的文件;结果本地测试的时候发现,同时只能跑一个word转pdf的程序,如果又开了另一个,会直接报错,程序死掉;
  2. 部署到lavel-php和apache-django上都无法完成word转pdf的过程;

经过一番搜索,找到这篇讲真,别再用win32com包来实现Word文档转PDF了 文章, 提供了一个用libreoffice来转换word到pdf的方法。看上去至少第二个坑可以填上了。

换了libreoffice之后,发现比原先慢得多。又经过一番搜索,发现了这篇简单一步让LibreOffice不再卡顿(version 6.3.3.2 64位 Windows), 根据这个方法,把字体固定之后,速度果然变得可观了。

那么上面两个坑有没有填上呢?

  1. 本地测试发现,还是同时只能跑一个word转pdf的程序,如果又开了另一个,它会不工作,程序不会死掉,然而并没有什么卵用;
  2. 部署apache-django的过程又遇见了新坑,当然最后填掉了……

这个新坑是,在django的runserver里测试没有问题,但是部署到apache之后报错找不到soffice命令。

解决思路就是把soffice写成绝对路径。

然而我的libreoffice安在了默认的“C:\Program Files\LibreOffice\program”下,os.system()调用的时候死活处理不了那空格,加引号也没用。 google再次发挥了它的作用,我用上了python处理Windows平台上路径有空格这篇文章作者说的方法, 不折腾了,先os.chdir到路径下,再soffice.exe了。

真·一把辛酸泪。

至于无法并行的坑,我又找到这篇使用docker来实现libreoffice并发转换docx文件为pdf,不多说了,我去研究docker了。

手动再见.jpg