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,是我🔨了)