准备工作
- 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']; }