准备工作
- composer require tecnickcom/tcpdf 安装插件
- 下载中文字体(tcpdf某部分字体导出的是中文是乱码),放到“\tecnickcom\tcpdf\tools\”目录下
- 在第二步骤打开cmd ,输入php tcpdf_addfont.php -i .\msyh.ttf(执行成功之后会生成对应文件)
字体下载
注意事项
- 强烈建议把pdf输出到本地文件查看,实测apipost查看会出现乱码
- 字体下载好之后把ttf格式解压出来放到tools,别把rar放到tools文件夹
- 字体样式请注意是否侵权
可扩展
-
php合并PDF FPDI
- https://blog.csdn.net/qq_31695557/article/details/122936987?spm=1001.2014.3001.5502 可参考此文章
-
FPDF 下载网址 http://www.fpdf.org/
FPDI 下载网址 https://www.setasign.com/products/fpdi/about/
设置pdf页面数据
public function exportPDF()
{
$path = '/static/uploads/preview/' . date('Ym') . '/';//文件存放路径
$directory=ROOT_PATH.'public';//根目录
$is_path = $directory. $path;//全路径
//检测并创建文件夹
if ($this->exists_dir($is_path) === false) {
return false;
}
$objPDF = new \TCPDF(PDF_PAGE_ORIENTATION, PDF_UNIT, PDF_PAGE_FORMAT, true, 'UTF-8', false);
// 是否显示页眉
$objPDF->setPrintHeader(false);
// 是否显示页脚
$objPDF->setPrintFooter(true);
// 设置页脚的字体
$objPDF->setFooterFont(Array('msyh', '', '8'));
// 设置页脚距离底部的距离
$objPDF->SetFooterMargin('7');
// 设置默认等宽字体
$objPDF->SetDefaultMonospacedFont(PDF_FONT_MONOSPACED);
// 设置行高
$objPDF->setCellHeightRatio(1.5);
// 设置是否自动分页 距离底部多少距离时分页
$objPDF->SetAutoPageBreak(TRUE, '10');
$objPDF->setFontSubsetting(true);
$objPDF->AddPage();
// 设置字体
$objPDF->SetFont('msyh', '', 12);
$info = [];
$info['grade'] = '一年级';
$info['year'] = '2023';
$info['season'] = '第四季度';
$info['student'] = '50';
$info['cmit'] = '49';
$list = [];
$list[0]['type'] = '单选题';
$list[0]['title'] = '题目题干';
$list[0]['answer'] = 'A';
$list[0]['percent'] = '50';
$list[0]['option_A'] = 'A选项内容';
$list[0]['sel_A'] = '0';
$list[0]['percent_A'] = '0';
$list[0]['option_B'] = 'A选项内容';
$list[0]['sel_B'] = '0';
$list[0]['percent_B'] = '0';
$list[0]['option_C'] = 'A选项内容';
$list[0]['sel_C'] = '0';
$list[0]['percent_C'] = '0';
$list[0]['option_D'] = 'A选项内容';
$list[0]['sel_D'] = '0';
$list[0]['percent_D'] = '0';
$list[0]['option_E'] = 'A选项内容';
$list[0]['sel_E'] = '0';
$list[0]['percent_E'] = '0';
$list[0]['option_F'] = 'A选项内容';
$list[0]['sel_F'] = '0';
$list[0]['percent_F'] = '0';
$list[0]['option_G'] = 'A选项内容';
$list[0]['sel_G'] = '0';
$list[0]['percent_G'] = '0';
$list[0]['cmit_num'] = '20';
// 调用拼接html代码方法
$pdf_html = $this->pdfHtml($info,$list,'期末考试');
$objPDF->writeHTMLCell(0, 0, '', '', $pdf_html, 0, 1, 0, true, '', true);
//添加二维码
$url = $this->site() . '/h5/' . '1.png';
$url = 'https://lrfgkhjlksg/1.jpg';
$num_num = $objPDF->getNumPages();//获取当前页码
$objPDF->setPage($num_num);//二维码放置指定的页面
$style = array(
'border' => false,
'padding' => 0,
'fgcolor' => array(0, 0, 0),
'bgcolor' => false, //array(255,255,255)
//'module_width' => 1, // width of a single module in points
//'module_height' => 1 // height of a single module in points
);
//生成二维码
$objPDF->write2DBarcode($url, 'QRCODE,L', 16, 12, 17, 17, $style, 'N');
// 输出 四种模式 I输出、D下载、F保存本地、S输出二进制字符串
$objPDF->Output($is_path . 123456 . ".pdf", "F");
}
检测文件夹
public function exists_dir(string $path): bool
{
if (file_exists($path) === false) {
$path = str_replace("\\", '/', $path);
$path_arr = explode('/', $path);
$ping = '';
//循环逐级检测 不存在则创建
foreach ($path_arr as $k => $v) {
$ping .= $v . '/';
if (file_exists($ping) === false && !mkdir($ping, 777) && is_dir($ping)) {
return false;
}
}
}
return true;
}
书写html
public function pdfHtml($info,$list,$title)
{
$html = '';
$html .= '<h2 style="text-align:center;"><b>'.$title.'</b></h2>
<table style="text-align:right">
<tr><td>班级:'.$info['grade'].'_'.$info['year'].$info['season'].'</td></tr>
<tr><td>总人数:'.$info['student'].'; 已交卷:'.$info['cmit'].'</td></tr>
<tr><td>导出时间:'.date('Y-m-d H:i:s',time()).'</td></tr>
</table>';
foreach ($list as $k => $v) {
$html .= '<div>
【'.$v['type'].'】 第'.($k+1).'题:'.$v['title'].'<br><span style="color: green;">【正确答案:'.$v['answer'].'】</span><b style="color: #1E9FFF"> 正确率:'.$v['percent'].'%</b>
</div>
<table border="1" style="text-align:center">
<colgroup>
<col width="40%">
<col width="10%">
<col width="50%">
<col>
</colgroup>
<tr style="background:#f2f2f2; ">
<th>选项</th>
<th>选择次数 / 人</th>
<th>比例</th>
</tr>
<tr>
<td style="text-align:left">A:'.$v['option_A'].'</td>
<td>'.$v['sel_A'].'</td>
<td>'.$v['percent_A'].'%</td>
</tr>
<tr>
<td style="text-align:left">B:'.$v['option_B'].'</td>
<td>'.$v['sel_B'].'</td>
<td>'.$v['percent_B'].'% </td>
</tr>
<tr>
<td style="text-align:left">C:'.$v['option_C'].'</td>
<td>'.$v['sel_C'].'</td>
<td> '.$v['percent_C'].'% </td>
</tr>
<tr>
<td style="text-align:left">D:'.$v['option_D'].'</td>
<td>'.$v['sel_D'].'</td>
<td> '.$v['percent_D'].'% </td>
</tr>
<tr>
<td style="text-align:left">E:'.$v['option_E'].'</td>
<td>'.$v['sel_E'].'</td>
<td> '.$v['percent_E'].'% </td>
</tr>
<tr>
<td style="text-align:left">F:'.$v['option_F'].'</td>
<td>'.$v['sel_F'].'</td>
<td> '.$v['percent_F'].'% </td>
</tr>
<tr>
<td style="text-align:left">G:'.$v['option_G'].'</td>
<td>'.$v['sel_G'].'</td>
<td> '.$v['percent_G'].'% </td>
</tr>
<tr>
<th>作答人数:'.$v['cmit_num'].' 人次</th>
<th></th>
<th></th>
</tr>
</table><br/>';
}
return $html;
}
扩展功能-添加二维码
public function qrCodePdf(array $arr): void
{
//生成二维码 文档 https://tcpdf.org/examples/example_027/
if (!empty($arr['on_off']) && $arr['on_off'] === 1) {
//二维码链接
$url = $this->site() . '/h5_contract_url/' . $arr['uniq_key'];
$arr['pdf']->setPage($arr['set_page']);//二维码放置指定的页面
$style = array(
'border' => false,
'padding' => 0,
'fgcolor' => array(0, 0, 0),
'bgcolor' => false, //array(255,255,255)
//'module_width' => 1, // width of a single module in points
//'module_height' => 1 // height of a single module in points
);
//生成二维码
$arr['pdf']->write2DBarcode($url, 'QRCODE,L', 16, 12, 17, 17, $style, 'N');
return $arr;
}
}
public function site(): string
{
return $_SERVER['REQUEST_SCHEME'] . '://' . $_SERVER['SERVER_NAME'];
}
