03百融云策略引擎服务sdk对接将反馈的json格式的结果变成pdf形式并且可下载-优雅草卓伊凡
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中部分隐藏(如身份证、手机号)
- 验证用户输入防止注入gj
- 生成临时文件并及时清理
- 用户体验:
- 保持网页版和PDF版内容一致
- 提供明显的导出按钮
- 生成专业的报告格式
那么 导出pdf实现了 我们下一步需要继续完整的实现本内容。