当前位置: 首页 > news >正文

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

http://www.xdnf.cn/news/1429957.html

相关文章:

  • ffmpeg 安装
  • C#基础(⑤ProcessStartInfo类和Process类)
  • Centos10虚拟机安装Zabbix
  • 面试tips--MySQLRedis--Redis 有序集合用跳表不用B+树 MySQL用B+树作为存储引擎不用跳表:原因如下
  • 卫朋:基于IPD思维的产品规划逻辑
  • Android Binder 驱动 - Media 服务启动流程
  • 三格电子CAN总线通信原理及在消防领域中的应用
  • 第三章:生活重构:当程序员不再只是“码农“
  • 威科夫与强化学习状态
  • @Apache Hive 介绍部署与使用详细指南
  • 跨越产业技术障碍、创新制造模式的智慧工业开源了
  • HiMarket:开源AI中台革命——企业智能化的新基建
  • 从全球视角到K8s落地的Apache IoTDB实战
  • 2025年渗透测试面试题总结-47(题目+回答)
  • C++入门自学Day17-- 模版进阶知识
  • [re_1] const|cap|zookper|snowflake
  • maven私有仓库配置
  • 【linux】firewall防火墙
  • 急招 MySQL / PG DBA,欢迎自荐或推荐朋友!推荐有奖!
  • Delphi 5 操作Word表格选区问题解析
  • 玩转Docker | 使用Docker部署Haptic笔记管理应用
  • Resemble Enhance:AI语音增强技术的革新之作
  • Rsync + Rsyncd 从入门到项目实战:自动化备份全攻略
  • 阅读Linux 4.0内核RMAP机制的代码,画出父子进程之间VMA、AVC、anon_vma和page等数据结构之间的关系图。
  • innovus: postRoute如何加shielding
  • ARM - GPIO 标准库开发
  • 【Python3教程】Python3高级篇之XML解析
  • 3dmax烘培插件3dmax法线贴图烘焙教程glb和gltf元宇宙灯光效果图烘焙烘焙光影贴图支持VR渲染器
  • 10 51单片机之DS1302实时时钟
  • Java集合源码解析之ArrayList