在日常的办公自动化或文档处理系统中,将Word文档转换为PDF是一个常见需求。本文将介绍一种在Windows服务器环境下,通过PHP调用LibreOffice命令行工具来实现高质量转换的稳定方案,并提供可直接使用的封装类。

上图展示了文档转换流程的抽象示意,而具体的实现则依赖于下面的代码逻辑。
核心原理:PHP调用命令行
该方案的核心是使用PHP的exec()函数调用已安装的LibreOffice的命令行接口。LibreOffice提供了无头模式(headless),可以在不启动图形界面的情况下完成文档格式转换,非常适合服务器端使用。
关键转换命令如下:
soffice --headless --invisible --convert-to pdf:writer_pdf_Export “input.docx” --outdir “output/path”
--headless --invisible: 确保在后台无界面运行。
--convert-to pdf:writer_pdf_Export: 指定输出格式为PDF。
--outdir: 指定PDF文件的输出目录。
完整的Word转PDF封装类
为了避免直接在脚本中编写命令,提高代码的复用性和健壮性,我们将其封装成一个PHP类 WordToPdfConverter。
<?php
/**
* 使用LibreOffice将Word文档转换为PDF
* 适用于Windows环境,需确保服务器已安装LibreOffice
*/
class WordToPdfConverter {
// LibreOffice可执行文件路径
private $libreOfficePath;
// 构造函数,设置LibreOffice路径
public function __construct($libreOfficePath = 'C:/Program Files/LibreOffice/program/soffice.exe') {
$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 array 转换结果
*/
public function convertToPdf($inputFile, $outputDir) {
// 检查输入文件是否存在
if (!file_exists($inputFile)) {
throw new Exception("输入文件不存在: " . $inputFile);
}
// 确保输出目录存在
if (!file_exists($outputDir)) {
mkdir($outputDir, 0777, true);
}
// 构建安全的转换命令
$command = escapeshellcmd($this->libreOfficePath) .
" --headless --invisible --convert-to pdf:writer_pdf_Export " .
escapeshellarg($inputFile) .
" --outdir " . escapeshellarg($outputDir);
// 执行命令
exec($command, $output, $returnVar);
// 检查是否转换成功
$filename = pathinfo($inputFile, PATHINFO_FILENAME);
$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 batchConvert($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->convertToPdf($filePath, $outputDir);
}
return $results;
}
}
?>
使用示例
以下是如何使用上述封装类进行文档批量转换的示例。这种PHP结合命令行工具的方式,常用于构建后端的文档自动化处理流程。
<?php
try {
// 初始化转换器,指定LibreOffice安装路径
$converter = new WordToPdfConverter('C:/Program Files/LibreOffice/program/soffice.exe');
// 检查环境
$converter->checkLibreOffice();
// 设置路径
$inputDir = 'D:/documents/word'; // Word源文件目录
$outputDir = 'D:/documents/pdf'; // PDF输出目录
// 执行批量转换
$results = $converter->batchConvert($inputDir, $outputDir);
// 输出结果
echo "转换完成,结果如下:\n";
foreach ($results as $result) {
if ($result['success']) {
echo "成功: " . $result['pdf_path'] . "\n";
} else {
echo "失败: " . $result['input_file'] . " - " . $result['message'] . "\n";
}
}
} catch (Exception $e) {
echo "错误: " . $e->getMessage() . "\n";
}
?>
关键注意事项
- 环境依赖:服务器必须安装LibreOffice(或OpenOffice),并确保
soffice命令可被执行。
- 路径处理:Windows路径中的反斜杠
\需要转义,或在PHP中使用正斜杠/。
- 权限问题:PHP进程(如Apache或php-fpm)需要有权限读取输入文件、写入输出目录以及执行LibreOffice程序。
- 中文路径:若文件或路径包含中文,需注意PHP文件系统函数与命令行环境下的编码一致性,必要时可使用
iconv函数进行转码。
通过上述封装类,你可以轻松地将Word转PDF功能集成到你的PHP应用中,实现稳定高效的文档处理。