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

记录word插入文字/图片,生成新word并转为pdf

安装 LibreOffice
sudo yum install libreoffice-headless -y

查看是否成功

libreoffice --version

手动运行转化:

libreoffice --headless --convert-to pdf --outdir '/www/wwwroot/K-HUISHOUYOU/public/output' '/www/wwwroot/K-HUISHOUYOU/public/output/doc_20250914151052_10852.docx' 2>&1

安装完整的 LibreOffice,缺少 libreoffice-writer(处理 .docx 的模块)

sudo dnf install libreoffice-writer -y

安装中文字体

查系统已安装完整的中文语言包
locale -a | grep zh查字体是否被安装
fc-list :lang=zh | grep -i noto安装字体:kkgithub.com 镜像
sudo wget -O /usr/share/fonts/noto-cjk/NotoSansCJKsc-Regular.otf \
https://kkgithub.com/notofonts/noto-cjk/raw/main/Sans/OTF/SimplifiedChinese/NotoSansCJKsc-Regular.otf设置权限:
sudo chmod 644 /usr/share/fonts/noto-cjk/*.otf更新字体缓存(这个重要)
sudo fc-cache -fv
public function generatePdf(){$data = input();$templateFile = 'output/moban/hsyys.docx';if (!file_exists($templateFile)) {return json(['success' => false, 'msg' => '模板文件不存在,请检查 template/hsyys.docx']);}try {$templateProcessor = new \PhpOffice\PhpWord\TemplateProcessor($templateFile);} catch (\Exception $e) {return json(['success' => false, 'msg' => '加载模板失败: ' . $e->getMessage()]);}// 2. 替换占位符$fields = ['serial', 'merit', 'company', 'creditcode', 'venue', 'contact'];foreach ($fields as $field) {
//            if (!isset($data[$field]) || $data[$field] === '') {
//                return json(['success' => false, 'msg' => "缺少必要字段: $field"]);
//            }// 安全处理:转义 HTML,防止特殊字符破坏文档$value = htmlspecialchars(strip_tags($data[$field]), ENT_QUOTES, 'UTF-8');$templateProcessor->setValue($field, $value);}$outputDir = 'output';$pdfDir = 'output/pdf';if (!is_dir($outputDir)) {if (!mkdir($outputDir, 0777, true)) {return json(['success' => false, 'msg' => '无法创建 output 目录']);}}if (!is_dir($pdfDir)) {if (!mkdir($pdfDir, 0777, true)) {return json(['success' => false, 'msg' => '无法创建 output/pdf 目录']);}}// 4. 生成临时文件(使用绝对路径)$tempWordFile = $outputDir . '/doc_' . date('YmdHis') . '_' . rand(10000, 99999) . '.docx';$tempPdfFile  = $pdfDir . '/contract_' . date('YmdHis') . '_' . rand(10000, 99999) . '.pdf';try {$templateProcessor->saveAs($tempWordFile);} catch (\Exception $e) {return json(['success' => false, 'msg' => '保存 Word 失败: ' . $e->getMessage()]);}// 验证 Word 文件是否生成成功且非空if (!file_exists($tempWordFile)) {return json(['success' => false, 'msg' => 'Word 文件未生成,路径错误']);}if (filesize($tempWordFile) < 1024) {@unlink($tempWordFile);return json(['success' => false, 'msg' => 'Word 文件大小异常,可能模板占位符错误']);}// 使用绝对路径(关键!)$absoluteWord = realpath($tempWordFile);$absoluteOutDir = realpath($outputDir);if (!$absoluteWord || !$absoluteOutDir) {return json(['success' => false, 'msg' => '路径解析失败']);}// 5. 调用 LibreOffice 转 PDF$command = "libreoffice --headless --convert-to pdf --outdir " .escapeshellarg($absoluteOutDir) . " " .escapeshellarg($absoluteWord) . " 2>&1";exec($command, $output, $returnCode);// 删除源 Word 文件@unlink($tempWordFile);if ($returnCode !== 0) {return json(['success' => false,'msg' => 'LibreOffice 执行失败','command' => $command,'output' => implode("\n", $output)]);}// 6. 检查 PDF 是否生成(LibreOffice 生成在同目录)$expectedPdf = str_replace('.docx', '.pdf', $tempWordFile);if (!file_exists($expectedPdf)) {return json(['success' => false,'msg' => 'PDF 文件未生成,请检查 LibreOffice 是否正常安装','expected' => $expectedPdf,'output' => $output,'command' => $command]);}// 移动并重命名为目标 PDFif (!rename($expectedPdf, $tempPdfFile)) {return json(['success' => false, 'msg' => '无法移动 PDF 文件,权限不足']);}// 7. 返回成功// 带域名的 PDF URL$pdfUrlAll = 'https://' . $_SERVER['HTTP_HOST'] . '/'. $tempPdfFile;$pdfUrl = '/' . $tempPdfFile;return json(['success' => true,'msg' => 'PDF 生成成功','url' => $pdfUrlAll,'file' => $pdfUrl]);}


文章转载自:

http://ANtKy8ht.mjbkp.cn
http://oQKMZucC.mjbkp.cn
http://6oVwl2U8.mjbkp.cn
http://iuy15zrP.mjbkp.cn
http://57XE6sYw.mjbkp.cn
http://NFQzGvRG.mjbkp.cn
http://sAqYwjCz.mjbkp.cn
http://BksydTfJ.mjbkp.cn
http://H9zHJR5o.mjbkp.cn
http://8G28qQuZ.mjbkp.cn
http://zXlmT9uu.mjbkp.cn
http://wT2lmN11.mjbkp.cn
http://RmOc62e8.mjbkp.cn
http://MlsIThOl.mjbkp.cn
http://14vNL1K4.mjbkp.cn
http://zha7rDgu.mjbkp.cn
http://5Duj6W3V.mjbkp.cn
http://Y0E0rOiy.mjbkp.cn
http://TCj1ewkc.mjbkp.cn
http://6oynfugr.mjbkp.cn
http://YEGPJzwl.mjbkp.cn
http://iKmRKwti.mjbkp.cn
http://pFepBNeG.mjbkp.cn
http://15WXtIRm.mjbkp.cn
http://q37lKYPU.mjbkp.cn
http://1hspThjh.mjbkp.cn
http://KxNn7Yoc.mjbkp.cn
http://gJa5fWRJ.mjbkp.cn
http://1wxmlXnc.mjbkp.cn
http://pz7UwsHy.mjbkp.cn
http://www.dtcms.com/a/383588.html

相关文章:

  • 【ROS2】Concept(Basic)
  • Level Set(水平集)算法——形象化讲解
  • 45.sed,awk详解及相关案例
  • 聊一下贪心算法
  • 磁共振成像原理(理论)7:射频回波 (RF Echoes)-双脉冲回波
  • Python实战:实现监测抖音主播是否开播并录屏
  • MySQL中InnoDB索引使用与底层原理
  • 全网首款数学建模交互AI应用-持续更新
  • 飞牛NAS本地挂载夸克网盘、接入飞牛影视教程
  • 音视频学习(六十五):fmp4
  • 【STM32】串口的阻塞、中断、DMA收发
  • win10系统 文件夹被占用无法删除
  • LawGPT:基于中文法律知识的大模型
  • 手搓多模态-10 旋转位置编码的原理和实现
  • C# --- dispose机制与using关键字
  • HakcMyVM-Aurora
  • Flask学习笔记(一)
  • MobaXterm软件访问ZYNQ板卡的Linux系统
  • 基于vLLM与YOLO的智能图像分类系统
  • 标准CAN帧介绍
  • 蚂蚁矿机S19 Pro 104T技术参数解析及性能分析
  • 一小时解决RabbitMQ面试题
  • HBM4量产就绪|2026年AI与数据中心新标配
  • 细粒度图像分类的可解释性Finer-CAM
  • C++中多线程core的问题分析和总结
  • scrapy框架-day02
  • 电商导购平台的移动端架构设计:React Native在多端统一中的实践
  • class_9:java 抽象类和接口
  • [硬件电路-209]:电子携带两种能量,一种是电流宏观运动的动能,一种是绕着原子核运动的原子轨道能量;前者是电势能与热能转化的媒介;后者是实现光能与电能的转化
  • HBase启动报错“Master is initializing”解决方案