在 python 中使用 soffice,Command 在终端中有效,但在 Python 子进程中无效
Posted
技术标签:
【中文标题】在 python 中使用 soffice,Command 在终端中有效,但在 Python 子进程中无效【英文标题】:Using soffice within python, Command works in terminal but not in Python subprocess 【发布时间】:2016-06-12 08:38:04 【问题描述】:我在 Python 中遇到了最令人沮丧的 libreoffice 问题
当我在终端中运行以下命令时,我完全没有问题,pdf 文件会在我想要的地方生成,并且生活很美好:
cd /Applications/LibreOffice.app/Contents/MacOS/
./soffice --convert-to pdf --outdir output_folder path_to_docx_file/title.docx
但是,当我尝试将其添加到我的 python 脚本中时:
SOFFICE = r'/Applications/LibreOffice.app/Contents/MacOS/soffice'
subprocess.Popen([SOFFICE, "--convert-to", "pdf", "--outdir", "output_folder ", "path_to_docx_file/title.docx"])
我收到一条错误消息:
错误:无法加载源文件
我已经尝试打开所有二进制文件和文件的所有权限,但这在 python 脚本中仍然不起作用。我究竟做错了什么?
【问题讨论】:
【参考方案1】:对我来说,这只是缺少“libreoffice-writer”包的问题。因此,如果您使用的是 Debian:
apt-get 安装 libreoffice-writer
【讨论】:
【参考方案2】:我也遇到过同样的问题。 (我使用了绝对路径,所以亚历克西斯的回答并没有解决我的问题)。
经过大量实验,我发现使用os.system
代替subprocess.Popen
不会引发同样的问题,所以也许这可以作为一个快速解决方案。
更详细地说,我创建了以下适用于我的环境的方法。
def makePdfFromDoc_linux_batch(input_folder_path, target_folder_path):
input_folder_files = os.path.join(input_folder_path, "*.doc")
os.system("/Applications/LibreOffice.app/Contents/MacOS/soffice --headless --convert-to pdf --outdir " + target_folder_path + " " + input_folder_files)
但是,我不知道这个问题的原因。由于os.system
显示不同的行为,它可能取决于 subprocess.Popen 为运行命令而生成的环境 - 但我没有实际证据。
我发现this blog post,遇到同样的问题似乎出现在红宝石环境中。它并没有真正帮助我理解问题的根源,但实际上我很着急,所以也许它可以对你更有帮助。
【讨论】:
【参考方案3】:这是因为您需要更改当前工作目录,而不仅仅是给出命令的绝对路径。
subprocess.Popen(["/Applications/LibreOffice.app/Contents/MacOS/soffice", "--convert-to", "pdf", "--outdir", "output_folder ", "path_to_docx_file/title.docx"])
应替换为:
subprocess.Popen(["soffice", "--convert-to", "pdf", "--outdir", "output_folder ", "path_to_docx_file/title.docx"], cwd="/Applications/LibreOffice.app/Contents/MacOS/")
即使它看起来很相似,这两个调用之间也有一个主要区别:当前工作目录。
使用脚本:
subprocess.Popen(["/Applications/LibreOffice.app/Contents/MacOS/soffie", "--convert-to", "pdf", "--outdir", "output_folder ", "file.docx"])
如果您在 ~ 目录中调用 python 脚本,它将尝试访问 ~/file.docx。
但是,在第二个中:
subprocess.Popen(["soffice", "--convert-to", "pdf", "--outdir", "output_folder ", "file.docx"], cwd="/Applications/LibreOffice.app/Contents/MacOS/")
它将尝试访问“/Applications/LibreOffice.app/Contents/MacOS/file.docx”中的文件,这与您使用 cd
命令所做的行为相同(实际上 cd 命令改变了当前目录,所以给出 cwd 参数与进行cd
调用相同)。
您可以也对所有文件使用绝对路径,它也可以解决问题,但这不是您想要做的。这取决于您尝试构建的软件及其用途。
这就是提示说文件不存在的原因。程序在WHERE_YOU_CALL_THE_SCRIPT/path_to_docx_file/title.docx
中找不到文件,因为我认为该文件在/Applications/LibreOffice.app/Contents/MacOS/path_to_docx_file/title.docx
中。
【讨论】:
我不认为这就是 OP 的意思。我遇到了同样的问题。如果我在 bash 中运行“/Applications/LibreOffice.app/Contents/MacOS/soffice --convert-to pdf --outdir /Users/andrea/pdf_conversion/tempOutput/ /Users/andrea/pdf_conversion/tempInput/*”,它可以工作.如果我尝试使用 subprocess.Popen 在 Python 中运行它,使用完全相同的字符串(将其拆分为空格)会引发“无法加载源文件”问题。以上是关于在 python 中使用 soffice,Command 在终端中有效,但在 Python 子进程中无效的主要内容,如果未能解决你的问题,请参考以下文章
无法读取使用 soffice 命令转换 pdf 后得到的 .docx 文件
使用 soffice 命令行将 xls 转换为分号分隔的 csv