如何在CodeIgniter 3中结合TCPDF使用FPDI合并PDF?
问题排查与修复方案
核心问题分析
你的代码存在几个关键问题导致PDF合并失败:
- 自定义
Pdf类继承错误,未基于FPDI实现 - FPDI库的文件引入路径错误
- 使用HTTP URL而非本地文件路径加载PDF源文件
- 循环逻辑存在索引越界和页码参数错误
- 未在导入页面后添加新页面
步骤1:修正自定义Pdf类(application/tcpdf/Pdf.php)
需要让你的Pdf类继承Fpdi而非TCPDF,同时修正库文件的引入路径:
<?php if(!defined('BASEPATH')) exit('No direct script access allowed'); // 使用CodeIgniter的APPPATH常量确保路径正确 require_once APPPATH . 'library/tcpdf/tcpdf.php'; require_once APPPATH . 'library/fpdi/src/Fpdi.php'; class Pdf extends Fpdi { public $my_header_title = "Report"; function __construct() { parent::__construct(); } // Page header public function Header() { // Set font $this->SetFont('helvetica', 'B', 20); // Title $this->Cell(0, 15, $this->my_header_title, 0, false, 'C', 0, '', 0, false, 'M', 'M'); } // Page footer public function Footer() { // Position at 15 mm from bottom $this->SetY(-15); // Set font $this->SetFont('helvetica', 'I', 8); // Page number //$this->Cell(0, 10, 'Page '.$this->getAliasNumPage().'/'.$this->getAliasNbPages(), 0, false, 'C', 0, '', 0, false, 'T', 'M'); } }
步骤2:修正控制器中的合并逻辑(Orders控制器)
修复路径、循环索引、页码参数,以及添加页面的逻辑:
public function multiplePdfGeneration() { $pdfNameArr = $_POST['imagesvalues']; $List = implode(',', $pdfNameArr); $id = $_POST['sendid']; $expPdf = explode(',',$List); $path = FCPATH . "createpdf/"; $imgName = []; foreach($expPdf as $pdfVal) { // 避免glob路径问题,用引号包裹路径 foreach(glob("{$path}{$pdfVal}*") as $imgfilename) { $ext = strtolower(pathinfo($imgfilename, PATHINFO_EXTENSION)); if($ext == 'pdf') { $imgName[] = $imgfilename; // 直接保存完整本地路径,后续无需再拼接 } } } $count = count($imgName); $filelocation = FCPATH . "createpdf/multigenerate/"; // 确保目录存在,防止写入失败 if (!is_dir($filelocation)) { mkdir($filelocation, 0755, true); } $time = date("d-m-Y")."-".time(); $mainfilename = "ID{$id}-multipdf-{$time}"; $filename = "{$mainfilename}.pdf"; $fileNL = $filelocation . $filename; $pdf = new Pdf(PDF_PAGE_ORIENTATION, PDF_UNIT, PDF_PAGE_FORMAT, true, 'UTF-8', false); $pdf->SetCreator(PDF_CREATOR); $pdf->SetAuthor('OrderCal'); $pdf->SetSubject('Invoice Pdf'); $pdf->SetKeywords('Invoice Pdf'); $pdf->setHeaderFont(Array(PDF_FONT_NAME_MAIN, '', PDF_FONT_SIZE_MAIN)); $pdf->setFooterFont(Array(PDF_FONT_NAME_DATA, '', PDF_FONT_SIZE_DATA)); $pdf->SetDefaultMonospacedFont(PDF_FONT_MONOSPACED); $pdf->SetMargins(2, 10, 2, true); $pdf->SetHeaderMargin(PDF_MARGIN_HEADER); $pdf->SetFooterMargin(PDF_MARGIN_FOOTER); $pdf->SetAutoPageBreak(TRUE, 10); $pdf->setImageScale(PDF_IMAGE_SCALE_RATIO); $pdf->SetFont('times', 'BI', 10); $pdf->my_header_title = ''; foreach($imgName as $pdfFile) { if(empty($pdfFile) || !file_exists($pdfFile)) { continue; } // 设置本地PDF文件路径(必须是本地路径,不能用URL) $pageCount = $pdf->setSourceFile($pdfFile); // 获取PDF的总页数,循环导入所有页面 for ($pageNo = 1; $pageNo <= $pageCount; $pageNo++) { $tplIdx = $pdf->importPage($pageNo); $size = $pdf->getTemplateSize($tplIdx); // 添加与原页面尺寸匹配的新页面 $pdf->AddPage($size['w'] > $size['h'] ? 'L' : 'P', array($size['w'], $size['h'])); $pdf->useTemplate($tplIdx); } } $pdf->Output($fileNL, 'F'); }
关键修复点说明
- 继承关系修正:
Fpdi类已经继承了TCPDF,所以自定义类继承Fpdi即可同时使用两者的功能 - 路径处理:使用
APPPATH和FCPATH确保文件路径正确,避免相对路径错误;加载PDF源文件必须用本地磁盘路径,不能用base_url()生成的HTTP URL - 循环逻辑:遍历PDF文件时,获取每个PDF的总页数,逐页导入;添加与原页面尺寸一致的新页面,避免内容被裁剪
- 目录检查:创建输出目录前先检查是否存在,防止因目录不存在导致PDF写入失败
内容的提问来源于stack exchange,提问作者userdev2222
相关产品推荐
相关产品推荐

