如何在多页PDF文档中同时使用HTML2PDF与FPDF类
解决方案:同时使用PDF_CircularText与PDF_HTML类
明确说:可以同时集成这两个类,但要注意类的继承关系和加载逻辑——不能直接中途切换实例,推荐用以下两种方案实现,既保留原有环形文本功能,又能引入HTML渲染能力:
方案一:自定义继承类(单实例操作,推荐)
FPDF的所有扩展类都基于FPDF基类开发,你可以创建一个自定义类,把PDF_CircularText和PDF_HTML的功能合并到一起,这样就能在同一个PDF实例中调用两类的方法。
操作步骤:
- 先引入所有依赖文件:
fpdf.php、PDF_CircularText.php、PDF_HTML.php(或html2pdf.php) - 编写自定义合并类:
// 引入基础依赖 require('fpdf.php'); require('PDF_CircularText.php'); require('PDF_HTML.php'); // 自定义合并类,继承PDF_CircularText并整合PDF_HTML的核心方法 class PDF_Combined extends PDF_CircularText { // 复制PDF_HTML中的WriteHTML方法 function WriteHTML($html) { $html = str_replace("\n",' ',$html); $a = preg_split('/<(.*)>/U',$html,-1,PREG_SPLIT_DELIM_CAPTURE); foreach($a as $i=>$e) { if($i%2==0) { if($this->HREF) $this->PutLink($this->HREF,$e); else $this->Write(5,$e); } else { if($e[0]=='/') $this->CloseTag(strtoupper(substr($e,1))); else { $a2 = explode(' ',$e); $tag = strtoupper(array_shift($a2)); $attr = array(); foreach($a2 as $v) { if(preg_match('/([^=]*)=["\']?([^"\']*)["\']?/',$v,$a3)) $attr[strtoupper($a3[1])] = $a3[2]; } $this->OpenTag($tag,$attr); } } } } // 复制PDF_HTML中的OpenTag、CloseTag、PutLink等依赖方法 function OpenTag($tag, $attr) { // 原PDF_HTML的OpenTag实现代码 switch($tag){ case 'B': $this->SetFont('','B'); break; case 'I': $this->SetFont('','I'); break; case 'U': $this->SetTextColor(0,0,255); break; case 'H1': $this->SetFont('','B',16); break; case 'H2': $this->SetFont('','B',14); break; case 'H3': $this->SetFont('','B',12); break; } } function CloseTag($tag) { // 原PDF_HTML的CloseTag实现代码 switch($tag){ case 'B': case 'I': $this->SetFont(''); break; case 'U': $this->SetTextColor(0); break; case 'H1': case 'H2': case 'H3': $this->Ln(4); break; } } function PutLink($URL, $txt) { $this->SetTextColor(0,0,255); $this->SetFont('','U'); $this->Write(5,$txt,$URL); $this->SetTextColor(0); $this->SetFont(''); } }
- 用自定义类替换原有实例,同时调用两类功能:
$pdf = new PDF_Combined(); $pdf->AddFont('kids','','kids.php'); $pdf->AddFont('BENETOpti-Black','','BENETOpti-Black.php'); $pdf->AddPage(); $pdf->Image('images/background.png',0, 0, 210, 0, 'PNG'); // 调用PDF_CircularText的环形文本方法 $pdf->CircularText(105, 148, 80, 0, 360, '环形示例文本', 'BENETOpti-Black', 16); // 调用PDF_HTML的HTML渲染方法,插入数据库调取的内容 $db_content = '从数据库获取的用户信息示例'; $pdf->WriteHTML('<h3>用户详情</h3><p>'.$db_content.'</p>'); $pdf->Output();
方案二:多实例生成后合并(适合复杂冲突场景)
如果类继承出现方法冲突难以调和,可以分别用两个类生成独立PDF页面,再用FPDI工具合并成完整文档:
操作步骤:
- 生成环形文本页面的临时PDF:
require('fpdf.php'); require('PDF_CircularText.php'); $pdf_circular = new PDF_CircularText(); $pdf_circular->AddFont('kids','','kids.php'); $pdf_circular->AddFont('BENETOpti-Black','','BENETOpti-Black.php'); $pdf_circular->AddPage(); $pdf_circular->Image('images/background.png',0, 0, 210, 0, 'PNG'); $pdf_circular->CircularText(105, 148, 80, 0, 360, '环形示例文本', 'BENETOpti-Black', 16); $pdf_circular->Output('F', 'temp_circular.pdf');
- 生成HTML内容页面的临时PDF:
require('fpdf.php'); require('PDF_HTML.php'); $pdf_html = new PDF_HTML(); $pdf_html->AddPage(); $db_content = '从数据库获取的用户信息示例'; $pdf_html->WriteHTML('<h3>用户详情</h3><p>'.$db_content.'</p>'); $pdf_html->Output('F', 'temp_html.pdf');
- 用FPDI合并两个临时PDF:
require('fpdi.php'); $pdf_final = new FPDI(); // 合并环形文本页面 $page_count = $pdf_final->setSourceFile('temp_circular.pdf'); for ($page_no = 1; $page_no <= $page_count; $page_no++) { $template_id = $pdf_final->importPage($page_no); $pdf_final->AddPage(); $pdf_final->useTemplate($template_id); } // 合并HTML内容页面 $page_count = $pdf_final->setSourceFile('temp_html.pdf'); for ($page_no = 1; $page_no <= $page_count; $page_no++) { $template_id = $pdf_final->importPage($page_no); $pdf_final->AddPage(); $pdf_final->useTemplate($template_id); } // 输出最终PDF $pdf_final->Output('I', 'final_document.pdf'); // 清理临时文件(可选) unlink('temp_circular.pdf'); unlink('temp_html.pdf');
关键注意事项
- 若两类有重名方法,自定义继承类中要重写逻辑,优先保留核心需求的功能
- 数据库调取的内容要转义特殊字符(如HTML的
<>、PDF的特殊符号),避免格式错乱 - 12页的文档优先用方案一,减少文件IO操作,提升生成效率
内容的提问来源于stack exchange,提问作者Beth Roux
相关产品推荐
相关产品推荐

