使用 Unoconv 将 docx 转换为 pdf 时出错
Posted
技术标签:
【中文标题】使用 Unoconv 将 docx 转换为 pdf 时出错【英文标题】:Error converting docx to pdf using Unoconv 【发布时间】:2021-09-11 13:54:58 【问题描述】:我正在尝试使用 Unoconv 将 .docx 文件转换为 .pdf 文件。 Libreoffice 安装在我的服务器上,该脚本适用于服务器上的另一个网站。
使用use Unoconv\Unoconv;
行得到HTTP ERROR 500
。
有人知道我为什么收到HTTP ERROR 500
吗?
这是我的脚本:
<?php
require './Unoconv.php';
use Unoconv\Unoconv;
$originFilePath = './uf/invoice/17/word/202100021.docx';
$outputDirPath = './uf/invoice/17/pdf/202100021.pdf';
Unoconv::convertToPdf($originFilePath, $outputDirPath);
header("Content-type:application/pdf");
header("Content-Disposition:attachment;filename=202100021.pdf");
?>
这是我的 Unoconv.php 脚本:
<?php
namespace Unoconv;
class Unoconv
public static function convert($originFilePath, $outputDirPath, $toFormat)
$command = 'unoconv --format %s --output %s %s';
$command = sprintf($command, $toFormat, $outputDirPath, $originFilePath);
system($command, $output);
return $output;
public static function convertToPdf($originFilePath, $outputDirPath)
return self::convert($originFilePath, $outputDirPath, 'pdf');
public static function convertToTxt($originFilePath, $outputDirPath)
return self::convert($originFilePath, $outputDirPath, 'txt');
?>
【问题讨论】:
真的是反斜杠还是应该是正斜杠? 我认为 ik 应该是一个反斜杠。但我已经用正斜杠试过了:)$result1
在哪里声明和设置?我们没有看到这里涉及的所有代码
两个文件(您的脚本和 Unoconv.php)是否在同一个文件夹中?
@Alex 是的。该脚本和 Unoconv.php 位于同一文件夹中。 $result1 如果工作正常,你可以这样读:"$map1 ='map1'; $filename = 'test';"
【参考方案1】:
@Alex 关于首先包装 try/catch 是正确的,但语法应该是:
...
catch(\Exception $e)
...
【讨论】:
不错的收获。谢谢。 双关语;-)【参考方案2】:首先使用try...catch
包装您的代码以获取错误消息:
<?php
try
require 'Unoconv.php';
use Unoconv\Unoconv;
$map1 = $_SESSION['companyid'];
$filename = $result1['filename'];
$originFilePath = './uf/doc/'.$map1.'/word/'.$filename.'.docx';
$outputDirPath = './uf/doc/'.$map1.'/pdf/'.$filename.'.pdf';
Unoconv::convertToPdf($originFilePath, $outputDirPath);
header("Content-type:application/pdf");
header("Content-Disposition:attachment;filename=".$filename.".pdf");
readfile($outputDirPath);
catch (\Exception $e)
die($e->getMessage());
【讨论】:
@John 那是不可能的。在脚本的第一行尝试die('test')
。如果我们不能 catch
它,问题似乎不在您的脚本之外。
die('test')
没有改变任何东西。我仍然收到错误 500。我第一篇文章中的脚本正是我正在使用的。不多也不少。
@John 那是不可能的。删除所有内容并只保留die('test');
似乎你根本就没有接触过这个脚本。
但它正在发生:)。只有die('test');
我在浏览器中得到文本test
:)
@John 根据 Noelpotnic 的评论,我已经调整了我的代码。再试一次以检测破坏您页面的真正错误消息。【参考方案3】:
我观察到 LibreOffice 在进行转换时可能有点奇怪,尤其是在从网络服务器帐户以无头模式运行时。
最简单的尝试是修改 unoconv
以使用与 LibreOffice 一起提供的相同 Python 二进制文件:
#!/usr/bin/env python
应该是(在检查 libreoffice 的安装位置之后)
#!/opt/libreoffice7.1/program/python
否则,我已经通过直接调用 libreoffice(没有 Unoconv)解决了这个问题:
$dir = dirname($docfile);
// Libreoffice saves here
$pdf = $dir . DIRECTORY_SEPARATOR . basename($docfile, '.docx').'.pdf';
$ret = shell_exec("export HOME=$dir && /usr/bin/libreoffice --headless --convert-to pdf --outdir '$dir' '$docfile' 2>&1");
if (file_exists($pdf))
rename($pdf, $realPDFName);
else
return false;
return true;
所以你的代码会变成:
$originFilePath = './uf/invoice/17/word/202100021.docx';
$outputDirPath = './uf/invoice/17/pdf/202100021.pdf';
$dir = dirname($originFilePath);
$pdf = $dir . DIRECTORY_SEPARATOR . basename($originFilePath, '.docx').'.pdf';
$ret = shell_exec("export HOME=$dir && /usr/bin/libreoffice --headless --convert-to pdf --outdir '$dir' '$originFilePath' 2>&1");
// $ret will contain any errors
if (!file_exists($pdf))
die("Conversion error: " . htmlentities($ret));
rename($pdf, $outputDirPath);
header("Content-type:application/pdf");
header("Content-Disposition:attachment;filename=202100021.pdf");
readfile($outputDirPath);
我假设 libreoffice 存在于“/usr/bin/libreoffice”的常用替代链接中,否则您需要使用“which libreoffice”的终端命令检索其路径。或者,从 php 脚本,
<?php
header('Content-Type: text/plain');
print "If this works:\n";
system('which libreoffice 2>&1');
print "\n-- otherwise a different attempt, returning too much information --\n";
system('locate libreoffice');
【讨论】:
以上是关于使用 Unoconv 将 docx 转换为 pdf 时出错的主要内容,如果未能解决你的问题,请参考以下文章
使用 LibreOffice / OpenOffice 将 docx 转换为 pdf
使用 jodconverter 和 OpenOffice 将 doc/docx 转换为 pdf