PHP中將Word文件轉換爲PDF

http://blog.hsojo.com/2020/06/02/PHPWordToPdf/

版權聲明:本文爲博主原創文章,轉載請註明出處。

前言

在上一篇水文中,我提到了需要實現“docx轉pdf”;

經過一番折騰,最終得出了一個結論:PHP可真不愧是一兩面撬刀的🔨。

在嘗試了使用“phpoffice/phpword”+“dompdf/mpdf”等主流PDF轉換庫對docx進行轉換後,最後得到的效果實在是不盡人意。(錯位+亂碼)

雖然在Windows平臺可通過“.net COM組件”這種外掛方式實現轉換,但這種方法不具備跨平臺特性,不方便部署,同時也不方便在日後的項目複用。

最後得到的解決方案則是通過PHP調用Python unoconv工具調用LibreOffice實現。(究極套娃)

調用unoconv

實現調用unoconv進行轉換隻需要簡單兩行代碼。

 

1
2
3
4
5
6
7
8
9
10
11
12
/**
 * @param string $unoconv unoconv執行文件位置
 * @param string $uno_path LibreOffice執行文件所在目錄
 * @param string $src 待轉換的源文件路徑
 * @param string|null $dest 轉換文件的路徑
 * @param string $format 轉換的文件格式,需要LibreOffice支持
 */
function unoconv($unoconv, $uno_path, $src, $dest = null, $format = 'pdf')
{
    putenv('UNO_PATH=' . $uno_path);
    shell_exec(sprintf('%s -f %s "%s" %s', $unoconv, $format, $src, empty($dest) ? '' : '-o ' . $dest));
}

以下是通過“phpoffice/phpword”實現數據注入模版並轉換爲pdf的業務代碼。(截選部分)

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
header('Content-Type: application/pdf');
header(sprintf('Content-Disposition: attachment;filename="%s"', $cert_name));
header('Cache-Control: max-age=0');

$cert_path = WEB_ROOT . 'upload/' . $cert_path;

$template = new TemplateProcessor($cert_path);
$template->setValues($data);

$src = $template->save();
$ext = @pathinfo($src)['extension'];
if (!empty($ext))
    $dest = str_replace('.' . $ext, '.pdf', $src);
else
    $dest = $src . '.pdf';
unoconv($setting['unoconv'], $setting['uno_path'], $src, $dest);

$io = fopen("php://output", "w");
fwrite($io, readfile($dest));
fclose($io);

部署unoconv環境

  • 安裝最新版本LibreOffice

  • 安裝最新版本Python(3.+)。

  • 使用pip安裝unoconv。

 

1
pip install unoconv
  • 配置“UNO_PATH”環境變量
    • /Applications/LibreOffice.app/Contents/MacOS
    • C:\Program Files\LibreOffice\program

這時,一般情況下只要在終端輸入unoconv,就可以看到相關幫助信息。

  • 但注意,Windows除外,在Windows裏,unoconv並不是以可執行文件的形式存在(因爲沒有後綴)。

    那麼,在Windows環境下,則需要輸入python C:\Users\HsOjo\AppData\Local\Programs\Python\Python37\Scripts\unoconv運行unoconv。

到這裏,unoconv環境的部署就完成了。

PHP調用前注意

在不同的運行環境下,情況可能有所不同。

通常情況下,PHP無法獲取到完整的系統環境變量。(有些環境變量配置是僅限於Shell的)

對於前面方法中的“unoconv執行文件位置”參數,建議提供絕對路徑。

後記

發現PHP版unoconv。(dbq,是我🔨了)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章