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

PHP拆分重组pdf,php拆分pdf指定页数,并合并成新pdf

在ThinkPHP5中实现PDF拆分与合并功能,主要使用FPDI库来处理PDF页面操作。以下是完整的实现流程和代码示例。

环境准备与依赖安装

首先通过Composer安装必要的依赖包

composer require setasign/fpdi
composer require setasign/fpdf

核心功能实现

以下是完整的PDF处理类,包含拆分指定页面和合并多个PDF的功能:


<?php
namespace app\common\util;use setasign\Fpdi\Tcpdf\Fpdi;class PdfHandler
{/*** 拆分PDF指定页面并合并为新PDF* @param array $pdfFiles PDF文件路径数组* @param array $pageRules 页面规则 ['file1.pdf' => '1,3,5', 'file2.pdf' => '2-4']* @param string $outputName 输出文件名* @param string $outputMode 输出模式 D-下载 I-预览 F-保存* @return mixed*/public function splitAndMergePdf($pdfFiles, $pageRules, $outputName = 'merged.pdf', $outputMode = 'D'){try {$pdf = new Fpdi();foreach ($pdfFiles as $index => $pdfFile) {$fileKey = basename($pdfFile);if (!isset($pageRules[$fileKey])) {continue;}$pageCount = $pdf->setSourceFile($pdfFile);$selectedPages = $this->parsePageRules($pageRules[$fileKey], $pageCount);foreach ($selectedPages as $pageNo) {$templateId = $pdf->importPage($pageNo);$size = $pdf->getTemplateSize($templateId);$pdf->AddPage($size['orientation'], $size);$pdf->useTemplate($templateId);}}$pdf->Output($outputName, $outputMode);$pdf->closeParsers();return true;} catch (\Exception $e) {throw new \Exception("PDF处理失败: " . $e->getMessage());}}/*** 解析页面规则* @param string $rule 页面规则 '1,3,5' 或 '2-4' 或 'all'* @param int $totalPages 总页数* @return array*/private function parsePageRules($rule, $totalPages){$pages = [];if ($rule === 'all') {for ($i = 1; $i <= $totalPages; $i++) {$pages[] = $i;}return $pages;}if (strpos($rule, '-') !== false) {list($start, $end) = explode('-', $rule);$start = max(1, intval(trim($start)));$end = min($totalPages, intval(trim($end)));for ($i = $start; $i <= $end; $i++) {$pages[] = $i;}return $pages;}if (strpos($rule, ',') !== false) {$pageArray = explode(',', $rule);foreach ($pageArray as $page) {$page = intval(trim($page));if ($page >= 1 && $page <= $totalPages) {$pages[] = $page;}}return $pages;}$page = intval(trim($rule));if ($page >= 1 && $page <= $totalPages) {$pages[] = $page;}return $pages;}/*** 简单合并多个PDF(全部页面)* @param array $pdfFiles PDF文件路径数组* @param string $outputName 输出文件名* @param string $outputMode 输出模式* @return mixed*/public function simpleMergePdf($pdfFiles, $outputName = 'merged.pdf', $outputMode = 'D'){try {$pdf = new Fpdi();foreach ($pdfFiles as $pdfFile) {$pageCount = $pdf->setSourceFile($pdfFile);for ($pageNo = 1; $pageNo <= $pageCount; $pageNo++) {$templateId = $pdf->importPage($pageNo);$size = $pdf->getTemplateSize($templateId);$pdf->AddPage($size['orientation'], $size);$pdf->useTemplate($templateId);}}$pdf->Output($outputName, $outputMode);$pdf->closeParsers();return true;} catch (\Exception $e) {throw new \Exception("PDF合并失败: " . $e->getMessage());}}
}

控制器调用示例


<?php
namespace app\index\controller;use think\Controller;
use think\Request;
use app\common\util\PdfHandler;class Pdf extends Controller
{/*** 拆分合并PDF页面*/public function splitMerge(){if (Request::instance()->isPost()) {try {$pdfHandler = new PdfHandler();// PDF文件路径$pdfFiles = [ROOT_PATH . 'public/uploads/employee_agreement.pdf',ROOT_PATH . 'public/uploads/work_summary.pdf',ROOT_PATH . 'public/uploads/rental_agreement.pdf'];// 页面规则:指定每个PDF要提取的页面$pageRules = ['employee_agreement.pdf' => '1,3',      // 第1页和第3页'work_summary.pdf' => '2-4',             // 第2页到第4页'rental_agreement.pdf' => 'all'         // 所有页面];$result = $pdfHandler->splitAndMergePdf($pdfFiles, $pageRules, 'custom_merged.pdf', 'D');if ($result) {return json(['code' => 1, 'msg' => 'PDF处理成功']);}} catch (\Exception $e) {return json(['code' => 0, 'msg' => $e->getMessage()]);}}return $this->fetch();}/*** 简单合并多个PDF*/public function simpleMerge(){try {$pdfHandler = new PdfHandler();$pdfFiles = [ROOT_PATH . 'public/uploads/doc1.pdf',ROOT_PATH . 'public/uploads/doc2.pdf',ROOT_PATH . 'public/uploads/doc3.pdf'];$result = $pdfHandler->simpleMergePdf($pdfFiles,'simple_merged.pdf','D');if ($result) {return json(['code' => 1, 'msg' => 'PDF合并成功']);}} catch (\Exception $e) {return json(['code' => 0, 'msg' => $e->getMessage()]);}}
}

前端表单页面


<!DOCTYPE html>
<html lang="zh-CN">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>PDF拆分合并工具</title><style>.container { max-width: 800px; margin: 50px auto; padding: 20px; }.form-group { margin-bottom: 20px; }label { display: block; margin-bottom: 5px; font-weight: bold; }input, select { width: 100%; padding: 8px; border: 1px solid #ddd; border-radius: 4px; }.btn { background: #007bff; color: white; padding: 10px 20px; border: none; border-radius: 4px; cursor: pointer; }.btn:hover { background: #0056b3; }.file-item { background: #f8f9fa; padding: 15px; margin-bottom: 10px; border-radius: 4px; }</style>
</head>
<body><div class="container"><h2>PDF拆分重组工具</h2><form id="pdfForm" action="{:url('index/pdf/splitMerge')}" method="post"><div class="form-group"><label>选择PDF文件:</label><input type="file" id="pdfFiles" multiple accept=".pdf"><div id="fileList"></div></div><div class="form-group"><label>输出文件名:</label><input type="text" name="output_name" value="custom_merged.pdf" required></div><button type="submit" class="btn">生成新PDF</button></form></div><script>document.getElementById('pdfFiles').addEventListener('change', function(e) {const fileList = document.getElementById('fileList');fileList.innerHTML = '';Array.from(e.target.files).forEach((file, index) => {const fileItem = document.createElement('div');fileItem.className = 'file-item';fileItem.innerHTML = `<strong>${file.name}</strong><div style="margin-top: 10px;"><label>页面选择:</label><input type="text" name="page_rules[${file.name}]" placeholder="例如: 1,3,5 或 2-4 或 all"></div>`;fileList.appendChild(fileItem);});});</script>
</body>
</html>

功能特点说明

  1. 灵活的页面选择‌:支持单个页面、页面范围、多个指定页面以及全部页面的选择方式‌
  2. 多种输出模式‌:支持下载(D)、浏览器预览(I)、服务器保存(F)等输出方式
  3. 异常处理完善‌:包含完整的错误捕获和处理机制
  4. 内存管理优化‌:使用closeParsers()方法及时释放资源
  5. 自动尺寸适配‌:根据原PDF页面尺寸自动设置新页面大小
    该方案适用于文档管理系统、在线PDF处理服务等场景,能够高效地完成PDF页面的拆分和重组任务。
http://www.dtcms.com/a/524089.html

相关文章:

  • 详解C语言数组
  • 鹤山做网站公司建设网站宣传
  • 微信网站开发视频教程开发一个小软件多少钱
  • 释放内存与加速推理:PyTorch的torch.no_grad()与torch.inference_mode()
  • 论文笔记(九十六)VGGT: Visual Geometry Grounded Transformer
  • 城市基础设施安全运行监管平台
  • 网络 UDP 和 TCP / IP详细介绍
  • 数据结构(8)
  • [cpprestsdk] ~异步流处理(eg`basic_istream`、`basic_ostream`、`streambuf`) 底层
  • Linux 查找符合条件的文档
  • ​九小场所 / 乡镇监督防火 ——1 个平台管水源 / 隐患,整改率提 80%
  • 郑州做网站找绝唯科技地方类门户网站
  • 哪里可以做免费的物流网站国外室内设计案例网站
  • 【Linux系统】从零掌握make与Makefile:高效自动化构建项目的工具
  • ML:Supervised/Unsupervised
  • 开发网站多少钱北京 工业网站建设公司排名
  • 【后端开发面试题】
  • 【coze】基础概念与使用
  • Java 语法糖详解(含底层原理)
  • 企业网站介绍越南做企业网站
  • 免费建设电影网站宁波优化推广找哪家
  • JAVA1024 类 object类 包装类 享元模式 ;类继承 :interface ;构造方法
  • 树与二叉树的奥秘全解析
  • 《Python 正则表达式完全指南:从入门到精通》(AI版)
  • 【linux】vim快速清空整个文件
  • 基于单片机的故障检测自动保护智能防夹自动门设计及LCD状态显示系统
  • 2025妈妈杯大数据竞赛B题mathorcup:物流理赔风险识别及服务升级数学建模数模教学大学生辅导思路代码助攻
  • 对监控理解
  • 体育数据传输:HTTP API与WebSocket的核心差异
  • 货代如何做亚马逊和速卖通网站dedecms三合一网站源码