PDF输出功能实现方案实现思路与底层逻辑需求分析- 在现有百融云信息验证查询系统基础上增加PDF导出功能
- PDF内容应包含完整的查询结果和格式化数据
- 保持现有网页展示的同时提供PDF导出选项
- PDF需要专业的企业样式和布局
技术选型- TCPDF库:PHP中最流行的PDF生成库,支持UTF-8、多种字体和复杂布局
- HTML转PDF:利用现有HTML模板结构,转换为PDF格式
- 动态生成:根据每次查询结果实时生成PDF文件
架构设计- 前端触发:在结果展示区域添加”导出PDF”按钮
- 后端处理:
- 接收查询参数或结果数据
- 使用TCPDF生成PDF文档
- 返回PDF文件下载
- 内容组织:
- 封面页(带企业logo和标题)
- 查询基本信息
- 验证决策结果
- 详细数据表格
- 页脚(企业信息和生成时间)
关键实现点- 中文字体支持:需要加载支持中文的字体文件
- 样式转换:将CSS样式转换为TCPDF可识别的样式
- 分页控制:合理分页避免内容截断
- 安全考虑:验证用户权限和输入数据
完整实现代码<?php// 在文件开头添加TCPDF引入require_once('tcpdf/tcpdf.php');// ... 保留原有的BairongAPI类代码 .../** * PDF生成类 */class PDFGenerator{ /** * 生成查询结果PDF * @param array $result 查询结果数据 * @param array $queryParams 查询参数(姓名、身份证、手机号) * @return string PDF文件路径 */ public static function generateResultPDF($result, $queryParams) { // 创建TCPDF实例 $pdf = new TCPDF(PDF_PAGE_ORIENTATION, PDF_UNIT, PDF_PAGE_FORMAT, true, 'UTF-8', false); // 设置文档信息 $pdf->SetCreator('优雅草科技'); $pdf->SetAuthor('优雅草科技'); $pdf->SetTitle('百融云信息验证报告'); $pdf->SetSubject('信息验证结果'); $pdf->SetKeywords('百融云, 信息验证, 优雅草科技'); // 设置默认等宽字体 $pdf->SetDefaultMonospacedFont('courier'); // 设置边距 $pdf->SetMargins(15, 15, 15); $pdf->SetHeaderMargin(5); $pdf->SetFooterMargin(10); // 设置自动分页 $pdf->SetAutoPageBreak(TRUE, 25); // 设置图像比例 $pdf->setImageScale(PDF_IMAGE_SCALE_RATIO); // 添加页面 $pdf->AddPage(); // 生成封面 self::generateCoverPage($pdf, $queryParams); // 添加新页面放置详细内容 $pdf->AddPage(); // 生成基本信息部分 self::generateBasicInfo($pdf, $result, $queryParams); // 生成验证结果部分 self::generateVerificationResult($pdf, $result); // 生成手机验证部分 self::generatePhoneVerification($pdf, $result); // 生成特殊名单部分 self::generateSpecialList($pdf, $result); // 定义输出文件名 $filename = 'verify_result_'.date('YmdHis').'.pdf'; $filepath = sys_get_temp_dir().'/'.$filename; // 输出PDF文件 $pdf->Output($filepath, 'F'); return $filepath; } /** * 生成封面页 */ private static function generateCoverPage($pdf, $queryParams) { // 设置封面背景色 $pdf->SetFillColor(240, 240, 240); $pdf->Rect(0, 0, $pdf->getPageWidth(), $pdf->getPageHeight(), 'F', array()); // 添加logo (需要准备logo图片文件) $logoFile = __DIR__.'/logo.png'; if (file_exists($logoFile)) { $pdf->Image($logoFile, 15, 20, 30, 0, 'PNG', '', 'T', false, 300, '', false, false, 0, false, false, false); } // 设置标题 $pdf->SetFont('stsongstdlight', 'B', 20); $pdf->SetTextColor(13, 110, 253); $pdf->SetY(60); $pdf->Cell(0, 0, '百融云信息验证报告', 0, 1, 'C', 0, '', 0); // 副标题 $pdf->SetFont('stsongstdlight', '', 14); $pdf->SetTextColor(108, 117, 125); $pdf->SetY(75); $pdf->Cell(0, 0, '优雅草科技技术支持', 0, 1, 'C', 0, '', 0); // 分隔线 $pdf->SetY(90); $pdf->SetDrawColor(200, 200, 200); $pdf->Line(50, $pdf->GetY(), 160, $pdf->GetY()); // 查询信息 $pdf->SetFont('stsongstdlight', '', 12); $pdf->SetTextColor(0, 0, 0); $pdf->SetY(100); $pdf->Cell(0, 0, '查询主体信息', 0, 1, 'C', 0, '', 0); $pdf->SetFont('stsongstdlight', '', 10); $pdf->SetY(110); $pdf->Cell(40, 6, '姓 名:', 0, 0, 'R'); $pdf->Cell(0, 6, $queryParams['name'], 0, 1); $pdf->SetY(120); $pdf->Cell(40, 6, '身份证号:', 0, 0, 'R'); $pdf->Cell(0, 6, substr($queryParams['id_number'], 0, 3).'************'.substr($queryParams['id_number'], -3), 0, 1); $pdf->SetY(130); $pdf->Cell(40, 6, '手机号码:', 0, 0, 'R'); $pdf->Cell(0, 6, substr($queryParams['phone'], 0, 3).'****'.substr($queryParams['phone'], -4), 0, 1); // 生成时间 $pdf->SetFont('stsongstdlight', 'I', 10); $pdf->SetY(150); $pdf->Cell(0, 6, '生成时间: '.date('Y年m月d日 H:i:s'), 0, 1, 'C'); // 页脚 $pdf->SetFont('stsongstdlight', '', 8); $pdf->SetY(260); $pdf->Cell(0, 6, '© '.date('Y').' 优雅草科技 版权所有 | www.youyacao.com', 0, 1, 'C'); } /** * 生成基本信息部分 */ private static function generateBasicInfo($pdf, $result, $queryParams) { $pdf->SetFont('stsongstdlight', 'B', 14); $pdf->SetTextColor(13, 110, 253); $pdf->Cell(0, 8, '1. 查询基本信息', 0, 1); $pdf->SetDrawColor(200, 200, 200); $pdf->Line(15, $pdf->GetY(), 195, $pdf->GetY()); $pdf->Ln(5); $pdf->SetFont('stsongstdlight', '', 10); $pdf->SetTextColor(0, 0, 0); // 基本信息表格 $html = '<table border="0.5" cellpadding="4"> <tr> <td width="30%"><strong>查询状态</strong></td> <td width="70%">'.(($result['code'] === '00' || $result['code'] === '100002') ? '成功' : '失败').'</td> </tr> <tr> <td><strong>返回代码</strong></td> <td>'.$result['code'].'</td> </tr> <tr> <td><strong>查询流水号</strong></td> <td>'.($result['swift_number'] ?? '无').'</td> </tr> <tr> <td><strong>查询时间</strong></td> <td>'.date('Y-m-d H:i:s').'</td> </tr> <tr> <td><strong>计费标识</strong></td> <td>'.(isset($result['Flag']['infoverification']) ? ($result['Flag']['infoverification'] == '1' ? '是' : '否') : '无').'</td> </tr> </table>'; $pdf->writeHTML($html, true, false, true, false, ''); $pdf->Ln(10); } /** * 生成验证结果部分 */ private static function generateVerificationResult($pdf, $result) { if (!isset($result['InfoVerification'])) { return; } $verification = $result['InfoVerification']; $pdf->SetFont('stsongstdlight', 'B', 14); $pdf->SetTextColor(13, 110, 253); $pdf->Cell(0, 8, '2. 验证决策结果', 0, 1); $pdf->SetDrawColor(200, 200, 200); $pdf->Line(15, $pdf->GetY(), 195, $pdf->GetY()); $pdf->Ln(5); $pdf->SetFont('stsongstdlight', '', 10); $pdf->SetTextColor(0, 0, 0); // 决策结果表格 $html = '<table border="0.5" cellpadding="4"> <tr> <td width="30%"><strong>最终决策</strong></td> <td width="70%">'; $decision = $verification['final_decision'] ?? '无'; switch ($decision) { case 'Accept': $html .= '通过'; break; case 'Reject': $html .= '拒绝'; break; case 'Review': $html .= '复议'; break; default: $html .= $decision; } $html .= '</td> </tr> <tr> <td><strong>决策权重</strong></td> <td>'.($verification['final_weight'] ?? '无').'</td> </tr>'; if (isset($result['DataStrategy'])) { $strategy = $result['DataStrategy']; $html .= ' <tr> <td><strong>策略名称</strong></td> <td>'.($strategy['product_name'] ?? '无').'</td> </tr> <tr> <td><strong>策略编号</strong></td> <td>'.($strategy['strategy_id'] ?? '无').'</td> </tr> <tr> <td><strong>策略版本</strong></td> <td>'.($strategy['strategy_version'] ?? '无').'</td> </tr>'; } $html .= '</table>'; $pdf->writeHTML($html, true, false, true, false, ''); $pdf->Ln(5); // 命中规则表格 if (isset($verification['hit_rules'])) { $pdf->SetFont('stsongstdlight', 'B', 12); $pdf->Cell(0, 8, '命中规则详情', 0, 1); $pdf->SetFont('stsongstdlight', '', 8); $html = '<table border="0.5" cellpadding="3"> <thead> <tr style="background-color:#f8f9fa;"> <th width="30%"><strong>规则集</strong></th> <th width="20%"><strong>规则代码</strong></th> <th width="30%"><strong>规则名称</strong></th> <th width="20%"><strong>权重</strong></th> </tr> </thead> <tbody>'; foreach ($verification['hit_rules'] as $ruleSet => $rules) { foreach ($rules as $ruleCode => $rule) { $html .= ' <tr> <td>'.$ruleSet.'</td> <td>'.$ruleCode.'</td> <td>'.($rule['name_rule'] ?? '无').'</td> <td>'.($rule['weight'] ?? '0').'</td> </tr>'; } } $html .= '</tbody></table>'; $pdf->writeHTML($html, true, false, true, false, ''); } $pdf->Ln(10); } // ... 其他部分生成方法(手机验证、特殊名单等)与上面类似 ...}// 修改表单处理部分,添加PDF导出逻辑if ($_SERVER['REQUEST_METHOD'] === 'POST') { $bairong = new BairongAPI(); $name = trim($_POST['name'] ?? ''); $idNumber = trim($_POST['id_number'] ?? ''); $phone = trim($_POST['phone'] ?? ''); // 验证输入 if (empty($name) || empty($idNumber) || empty($phone)) { $result = ['error' => '姓名、身份证号和手机号不能为空']; } elseif (!preg_match('/^1[3-9]\d{9}$/', $phone)) { $result = ['error' => '手机号格式不正确']; } elseif (!preg_match('/^\d{17}[\dXx]$/', $idNumber)) { $result = ['error' => '身份证号格式不正确']; } else { $result = $bairong->query($name, $idNumber, $phone); // 处理PDF导出请求 if (isset($_POST['export_pdf']) && !isset($result['error'])) { $queryParams = [ 'name' => $name, 'id_number' => $idNumber, 'phone' => $phone ]; $pdfFile = PDFGenerator::generateResultPDF($result, $queryParams); // 发送PDF文件到浏览器 header('Content-Type: application/pdf'); header('Content-Disposition: attachment; filename="verify_report_'.date('YmdHis').'.pdf"'); readfile($pdfFile); unlink($pdfFile); // 删除临时文件 exit; } }}// 在HTML部分添加PDF导出按钮(在结果显示区域)<?php if (isset($result) && !isset($result['error'])): ?> <form method="post" style="display: inline;"> <input type="hidden" name="name" value="<?php echo htmlspecialchars($_POST['name']); ?>"> <input type="hidden" name="id_number" value="<?php echo htmlspecialchars($_POST['id_number']); ?>"> <input type="hidden" name="phone" value="<?php echo htmlspecialchars($_POST['phone']); ?>"> <button type="submit" name="export_pdf" class="btn btn-danger"> <i class="fas fa-file-pdf me-2"></i>导出PDF报告 </button> </form><?php endif; ?>实现说明TCPDF集成: - 需要先下载TCPDF库并放置在项目目录中
- 使用Composer安装:composer require tecnickcom/tcpdf
PDF生成流程: - 创建TCPDF实例并设置文档属性
- 添加封面页(带企业logo和查询信息)
- 添加内容页(分章节展示查询结果)
- 保存PDF文件并提供下载
样式处理: - 使用TCPDF的HTML解析功能处理简单表格
- 通过SetFont方法设置中文字体
- 使用颜色和线条增强可读性
安全考虑: - 敏感信息在PDF中部分隐藏(如身份证、手机号)
- 验证用户输入防止注入攻击
- 生成临时文件并及时清理
用户体验: - 保持网页版和PDF版内容一致
- 提供明显的导出按钮
- 生成专业的报告格式
那么 导出pdf实现了 我们下一步需要继续完整的实现本内容。
|