PHP操作LibreOffice将替换变量后的word文件转换为PDF文件

发布于:2025-09-03 ⋅ 阅读:(17) ⋅ 点赞:(0)

安装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;
        }
    }
}


网站公告

今日签到

点亮在社区的每一天
去签到