PHP操作LibreOffice将替换变量后的word文件转换为PDF文件
安装libreoffice见:Centos安装unoconv文档转换工具并在PHP中使用phpword替换word模板中的变量后,使用unoconv将word转换成pdf-CSDN博客
<?php
namespace app\lib;
use think\Exception;
/**
* 单个或批量将Word文件转换为PDF
* 需要服务器安装LibreOffice
* yum install -y libreoffice.x86_64
*/
class WordToPdfConverter {
// LibreOffice可执行文件路径
private $libreOfficePath;
// 构造函数,设置LibreOffice路径
public function __construct($libreOfficePath = '/usr/bin/libreoffice') {
$this->libreOfficePath = $libreOfficePath;
}
/**
* 检查LibreOffice是否可用
*/
public function checkLibreOffice() {
if (!file_exists($this->libreOfficePath)) {
throw new Exception("LibreOffice未找到,请检查路径设置");
}
return true;
}
/**
* 转换单个Word文件为PDF
* @param string $inputFile 输入Word文件路径
* @param string $outputDir 输出PDF目录
* @return bool 转换是否成功
*/
public function convertToPdfByShellExec($inputFile, $outputDir) {
// 检查输入文件是否存在
if (!file_exists($inputFile)) {
throw new Exception("输入文件不存在: " . $inputFile);
}
// 确保输出目录存在
if (!file_exists($outputDir)) {
mkdir($outputDir, 0755, true);
}
// 获取文件名(不含扩展名)
$filename = pathinfo($inputFile, PATHINFO_FILENAME);
// 核心-构建转换命令
// --headless: 无界面模式
// --convert-to pdf: 转换为PDF
// --outdir: 输出目录
//libreoffice --headless --convert-to pdf:writer_pdf_Export --outdir /output/path input.docx
$command = escapeshellcmd($this->libreOfficePath) .
' --headless --convert-to pdf:writer_pdf_Export --outdir '
.escapeshellarg($outputDir).' '.escapeshellarg($inputFile).' 2>&1 &';
// 执行命令
shell_exec($command);
// 检查是否转换成功
$pdfFile = $outputDir . '/' . $filename . '.pdf';
if (file_exists($pdfFile)) {
return [
'success' => true,
'pdf_path' => $pdfFile,
'message' => '转换成功'
];
} else {
return [
'success' => false,
'input_file' => $inputFile,
'message' => '转换失败'
];
}
}
/**
* 转换单个Word文件为PDF
* @param string $inputFile 输入Word文件路径
* @param string $outputDir 输出PDF目录
* @return bool 转换是否成功
*/
public function convertToPdfByExec($inputFile, $outputDir) {
// 检查输入文件是否存在
if (!file_exists($inputFile)) {
throw new Exception("输入文件不存在: " . $inputFile);
}
// 确保输出目录存在
if (!file_exists($outputDir)) {
mkdir($outputDir, 0755, true);
}
// 获取文件名(不含扩展名)
$filename = pathinfo($inputFile, PATHINFO_FILENAME);
// 核心-构建转换命令
// --headless: 无界面模式
// --convert-to pdf: 转换为PDF
// --outdir: 输出目录
//libreoffice --headless --convert-to pdf:writer_pdf_Export --outdir /output/path input.docx
$command = escapeshellcmd($this->libreOfficePath) .
' --headless --convert-to pdf:writer_pdf_Export --outdir '
.escapeshellarg($outputDir).' '.escapeshellarg($inputFile).' 2>&1 &';
// 执行命令
\exec($command, $output, $returnVar);
// 检查是否转换成功
$pdfFile = $outputDir . '/' . $filename . '.pdf';
if ($returnVar === 0 && file_exists($pdfFile)) {
return [
'success' => true,
'pdf_path' => $pdfFile,
'message' => '转换成功'
];
} else {
return [
'success' => false,
'input_file' => $inputFile,
'message' => '转换失败,错误码: ' . $returnVar . ', 输出: ' . implode("\n", $output)
];
}
}
/**
* 批量转换目录中的Word文件
* @param string $inputDir 输入目录
* @param string $outputDir 输出目录
* @param array $extensions 要处理的文件扩展名
* @return array 转换结果
*/
public function batchConvertToPdf($inputDir, $outputDir, $extensions = ['doc', 'docx']) {
if (!is_dir($inputDir)) {
throw new Exception("输入目录不存在: " . $inputDir);
}
$results = [];
$directory = new \RecursiveDirectoryIterator($inputDir);
$iterator = new \RecursiveIteratorIterator($directory);
$regex = new \RegexIterator($iterator, '/^.+\.(' . implode('|', $extensions) . ')$/i', \RecursiveRegexIterator::GET_MATCH);
foreach ($regex as $file) {
$filePath = $file[0];
$results[] = $this->convertToPdfByShellExec($filePath, $outputDir);
}
return $results;
}
}
/*******************************************************
<?php
namespace app\index\controller;
use app\BaseController;
use PhpOffice\PhpWord\TemplateProcessor;
use app\lib\WordToPdfConverter;
use think\Exception;
class Ceshi extends BaseController
{
public function index(){
//使用示例
try {
$documentTemplate = './222.docx';
$doc = new TemplateProcessor($documentTemplate);
$replace = '============*****==================';
$replace01 = '*******申请人张三有限责任公司********';
$doc->setValue('val001', $replace);
$doc->setValue('val002', $replace01);
//Temporary document filename (with path)
$tempDocumentFilename = $doc->save();
// 根据操作系统设置正确的LibreOffice路径
// Windows示例: 'C:/Program Files/LibreOffice/program/soffice.exe'
// Linux示例: '/usr/bin/libreoffice'
// Mac示例: '/Applications/LibreOffice.app/Contents/MacOS/soffice'
$converter = new WordToPdfConverter('/usr/bin/libreoffice');
// 检查LibreOffice是否可用
$converter->checkLibreOffice();
// 设置输入文件和输出目录
$inputFile = $tempDocumentFilename;
// PDF输出目录
$outputDir = '.';
$res_arr = $converter->convertToPdfByShellExec($inputFile, $outputDir);
if($res_arr['success']){
dd(rename($res_arr['pdf_path'], './123.pdf'));
}else{
dd($res_arr);
}
} catch (Exception $e) {
echo "错误: " . $e->getMessage() . "\n";
exit;
}
}
}