我在使用LibreOffice 5.4.6中的soffice.exe将Word文档转换为PDF时出现问题 - 通过IIS在Windows Server 2012 R2上运行。
将目录更改为PHP(chdir)中的相关LibreOffice程序目录后,我在PHP中调用的命令是:
$cmd = "soffice.exe --headless -convert-to pdf -outdir ".sys_get_temp_dir()." ".$workingdoc;
exec($cmd);
其中 $ workingdoc 是.docx Word文件的完整路径。
我系统上的sys_get_temp_dir()转换为C:\ Windows \ Temp
如果我将$ cmd变量回显给浏览器,然后在服务器上以交互方式将该输出复制粘贴到cmd.exe命令提示符中,则可以毫无问题地生成PDF。
例如,我复制粘贴到cmd.exe提示符中的回显$ cmd可能是:
soffice.exe --headless -convert-to pdf -outdir C:\Windows\TEMP C:\Windows\Temp\pdD125.docx
但是,在PHP中通过 exec()在与我交互式启动cmd.exe的用户上下文中运行此$ cmd变量只是挂起。我可以在任务管理器中看到soffice.exe,RAM使用率在10-20MB之间。此外,在我的C:\ Windows \ Temp文件夹中,我在soffice.exe保持运行时每秒都会连续创建多个空文件夹,所有文件的名称格式为 lu * .tmp
例如,生成的众多文件夹之一是 lu1124fq1pud.tmp
PDF不会被创建,并且允许PHP脚本完成并停止正在创建的 lu 文件夹(除了PHP超时)的唯一方法是强制结束soffice.exe任务任务经理。
那么,为什么soffice.exe命令在从cmd.exe调用时有效,但不能通过PHP调用,即使通过这两种方法在同一用户上下文中启动它们也是如此?
答案 0 :(得分:0)
事实证明,这是一个已知的问题,reported here。简而言之,这似乎是用户权限问题。
我通过首先在系统的temp目录中创建一个临时的LibreOffice用户配置文件文件夹解决了我的问题(不要创建该目录,请允许soffice.exe对其进行初始化):
$tempLibreOfficeProfile = sys_get_temp_dir()."\\LibreOfficeProfile".rand(100000, 999999);
然后将 env 参数添加到soffice.exe命令:
$cmd = 'soffice "-env:UserInstallation=file:///'.str_replace("\\", "/", $tempLibreOfficeProfile).'" --headless --convert-to pdf -outdir "'.sys_get_temp_dir().'" '.$workingDoc;
exec($cmd);
确保完成后清理临时配置文件文件夹,以免阻塞您的温度,例如:
exec('rmdir /S /Q "'.$tempLibreOfficeProfile.'"');