You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

CodeIgniter3中使用FPDI合并PDF报错:页码超出可用范围

CodeIgniter3 + FPDI合并PDF报错:页码超出可用范围

在CodeIgniter3框架中使用FPDI合并多个PDF为单个文件时,执行代码行$tplIdx = $pdf->importPage($i);时出现错误:

Fpdi Error Message: Page number "3" out of available page range (1 - 2)

以下是原代码:

function generateSinglePdf($List)
{
    $pdfValue = explode(',',$List);
    $path = $file = FCPATH."createpdf/";
    foreach($pdfValue as $pdfVal)
    {
        foreach(glob("$path/{$pdfVal}*") as $imgfile)
        {
            $ext = substr(strrchr($imgfile, '.'), 1);
            if($ext=='pdf')
            {
                $imgName[] = basename($imgfile);
            }   
        }
    }   
    $count = count($imgName);
    $filelocation = FCPATH."/newmultigenerate";
    $time = date("d-m-Y")."-".time();
    $mainfilename="ID".$id."-multipdf-".$time;
    $filename=$mainfilename.".pdf";
    $fileNL = $filelocation."/".$filename;

    $pdf = new MPdf(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 = '';


    for($i=0; $i<=$count;$i++)
    {
        if($imgName[$i]=="")
            continue;
        $imgUrl =  FCPATH."createpdf/".$imgName[$i];
        $pdf->setSourceFile($imgUrl);
        $tplIdx = $pdf->importPage($i);
        $pdf->useTemplate($tplIdx);
    }   

    $pdf->Output($fileNL, 'F');
}

错误原因分析

  1. 循环变量误用:把数组索引$i直接传给importPage(),但FPDI的importPage()需要的是当前PDF文件内的页码(从1开始),不是数组的循环索引。当处理第二个PDF文件时,$i已经是1,若该PDF只有2页,当$i增加到2时,就会超出该PDF的页码范围。
  2. 循环边界错误:$i<=$count会导致数组越界,因为$imgName的索引范围是0到$count-1,$i=$count时访问$imgName[$i]会获取到空值。
  3. 未添加新页面:直接调用useTemplate()会把内容覆盖在当前页面上,不会自动新增页面。

修复后的代码

function generateSinglePdf($List)
{
    $pdfValue = explode(',',$List);
    $path = FCPATH."createpdf/";
    $imgName = [];
    foreach($pdfValue as $pdfVal)
    {
        foreach(glob("$path/{$pdfVal}*") as $imgfile)
        {
            $ext = strtolower(substr(strrchr($imgfile, '.'), 1));
            if($ext == 'pdf')
            {
                $imgName[] = basename($imgfile);
            }   
        }
    }   
    $count = count($imgName);
    $filelocation = FCPATH."/newmultigenerate";
    // 确保输出目录存在
    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 MPdf(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))
            continue;
        $imgUrl = FCPATH."createpdf/".$pdfFile;
        // 获取当前PDF的总页数
        $pageCount = $pdf->setSourceFile($imgUrl);
        
        // 循环导入当前PDF的每一页
        for($pageNum = 1; $pageNum <= $pageCount; $pageNum++)
        {
            $tplIdx = $pdf->importPage($pageNum);
            // 获取模板尺寸
            $size = $pdf->getTemplateSize($tplIdx);
            // 添加匹配模板尺寸的新页面
            $pdf->AddPage($size['w'] > $size['h'] ? 'L' : 'P', [$size['w'], $size['h']]);
            // 使用模板
            $pdf->useTemplate($tplIdx);
        }
    }   

    $pdf->Output($fileNL, 'F');
}

关键改动说明

  • 把数组循环改为foreach遍历,避免索引混淆;
  • 对每个PDF文件,先通过setSourceFile()返回值获取总页数,再循环导入每一页(页码从1开始);
  • 每次导入页面时,先调用AddPage()创建匹配原页面尺寸的新页面,避免内容覆盖;
  • 添加了输出目录的创建逻辑,防止目录不存在导致保存失败;
  • 统一文件后缀判断为小写,避免大小写问题。

内容的提问来源于stack exchange,提问作者user2222

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 09:54:57