最近在做一个电商的项目,某天项目经理突然甩过来一个PDF
“快按照这个模版,给客户做个导出订单出库单的功能”
"看到是PDF的模版,看看陌生的PHP(已经在JAVA道路上渐行渐远),心里有一瞬间万念俱灰,不得已开始面向百度编程,在查看诸多XXCSDN,XX书之后仍未获得有效方案"
"两天过后"
"终于看到今天的主人公 TCPDF"
先附上官网大大TCPDF
上实操
1. 毫无疑问,对于PHPER来说,安装新的依赖,直接composer
//在你的composer.json文件中添加依赖
"require": {
"tecnickcom/tcpdf": "^6.2.13"
}
复制代码
然后
composer update
或者你可以在项目下运行
composer require tecnickcom/tcpdf
2.此时你项目中已经安装好了TCPDF
// 一个最简单的dmeo
$pdf = new TCPDF(); // create TCPDF object with default constructor args
$pdf->AddPage(); // pretty self-explanatory
$pdf->Write(1, 'Hello world'); // 1 is line height
$pdf->Output('hello_world.pdf'); // send the file inline to the browser (default).
复制代码
该demo可以用于检测你安装和引用是否成功
3.手把手项目实战
1️⃣: 先上PDF
2️⃣: 分析PDF
- 我们通过截图可以看出页面含有一个公共的页头,而且还是一张公司logo图.
- 页面大体有三部分组成,两个左右图表,一些文字以及一张logo公章图
3️⃣: 实操
//首先实例化PDF对象
$pdf = new TCPDF(PDF_PAGE_ORIENTATION, PDF_UNIT, PDF_PAGE_FORMAT, true, 'UTF-8', false);
// create new PDF document
$pdf->SetCreator('DimStar');
$pdf->SetAuthor('DimStar');
// $pdf->SetTitle('TCPDF Example 001');
// $pdf->SetSubject('TCPDF Tutorial');
// $pdf->SetKeywords('TCPDF, PDF, example, test, guide');
// $logo = dirname(__FILE__) ."/logo.jpg";
// set default header data
//这里着重说下页头的图片是如何实现的,起初想着拿静态资源中的一张图代替PDF_HEADER_LOGO参数中但是实际发现无论是绝对路径的图片还是网络图片地址都无法生效
//最终将logo图与composer安装的tcpdf文件包中的tcpdf_logo.png文件进行了替换
///这里只可以设置logo图的宽,但其实高也会随着宽进行等比例的缩放
$pdf->SetHeaderData(PDF_HEADER_LOGO, 40, '', '', array(0,64,255), array(0,64,128));
$pdf->setFooterData(array(0,64,0), array(0,64,128));
// set header and footer fonts
// $pdf->setHeaderFont(Array(PDF_FONT_NAME_MAIN, '', PDF_FONT_SIZE_MAIN));
$pdf->setFooterFont(Array(PDF_FONT_NAME_DATA, '', PDF_FONT_SIZE_DATA));
// set default monospaced font
$pdf->SetDefaultMonospacedFont(PDF_FONT_MONOSPACED);
// set margins
// $pdf->SetMargins(PDF_MARGIN_LEFT, PDF_MARGIN_TOP, PDF_MARGIN_RIGHT);
// $pdf->SetHeaderMargin(PDF_MARGIN_HEADER);
$pdf->SetFooterMargin(PDF_MARGIN_FOOTER);
// set auto page breaks
$pdf->SetAutoPageBreak(TRUE, PDF_MARGIN_BOTTOM);
// set image scale factor
$pdf->setImageScale(PDF_IMAGE_SCALE_RATIO);
$pdf->SetFont('stsongstdlight', '', 12, '', true);
// Add a page
// This method has several options, check the source code documentation for more information.
$pdf->AddPage();
//组装订单数据
$sumCN = CommonUtil::convertAmountToCn($order['pay_price'],0);
$table = "";
foreach ($cartInfo as $k => $v){
$price = $order['disCountStatus'] == 2 ? $v['cart_info']['vip_truePrice'] : $v['cart_info']['truePrice'];
$sum = bcmul($price, $v['cart_info']['cart_num'],2);
$table .= '<tr>
<td>' . $v['cart_info']['productInfo']['product_code'] . '</td>
<td colspan="2">' . $v['cart_info']['productInfo']['store_name'] . '</td>
<td>' . $v['cart_info']['productInfo']['attrInfo']['suk'] . '</td>
<td>' . $v['cart_info']['productInfo']['unit_name'] . '</td>
<td>' . $v['cart_info']['cart_num'] . '</td>
<td>' . $price . '</td>
<td>' . $sum .'</td>
</tr>';
}
//不足6条数据进行补充防止页面不够长,章盖在空白处
if(count($cartInfo) < 6){
for ($i = count($cartInfo); $i <6; $i++){
$table .= '<tr>
<td></td>
<td colspan="2"></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>';
}
}
$startTime = date("Y/m/d");
$endTime = date("Y/m/d",time() + 31536000);
//这里说下用的是最最最最基础的table布局编写的html,为什么要用这种方式编写html呢?因为tcpdf支持的css太低级了,唯有接触table布局才能实现我们想要的样式
$html = <<<EOD
<div style="font-size: 12px;">
<h2 style=" text-align: center; font-size: 28px; font-weight: bold;">销 售 合 同</h2>
<table cellspacing="3" cellpadding="4">
<tr>
<th colspan="3" align="left" style="font-size: 12px;">供方: 深圳逗点生物技术有限公司</th>
<th></th>
<th></th>
<th></th>
<th colspan="2" align="left" style="font-size: 12px;">合同编号: {$contractNumber}</th>
</tr>
<tr>
<td colspan="3" align="left" style="font-size: 12px;">需方: {$userInfo['real_name']}</td>
</tr>
<tr>
<td colspan="3" align="left" >一、产品名称、数量、金额:</td>
</tr>
<tr>
<td colspan="8" >
<table class="pdf-table" cellpadding="5" border="1" align="center" cellspacing="0" width="100%">
<thead>
<tr>
<td>产品编码</td>
<td colspan="2">产品名称</td>
<td>包装规格</td>
<td>规格型号</td>
<td>数量</td>
<td>含税单价</td>
<td>价税合计</td>
</tr>
</thead>
<tbody>
{$table}
<tr>
<td align="center">合计:</td>
<td colspan="2" align="left">{$order['pay_price']}</td>
<td colspan="2" align="center">人民币大写:</td>
<td colspan="3" align="left">{$sumCN}</td>
</tr>
<tr>
<td align="center">备注:</td>
<td colspan="7" align="left">{$order['remark']}</td>
</tr>
</tbody>
</table>
</td>
</tr>
<tr>
<td colspan="8" align="left" >二、质量要求:产品技术参数符合需方订货的要求。产品质量根据提供客户的说明书为标准。由运输造成的破损, 由供方承担。</td>
</tr>
<tr>
<td colspan="8" align="left" >三、运输方式及费用负担:采用快递运输,费用由供方负担。</td>
</tr>
<tr>
<td colspan="8" align="left" >四、包装标准:外包装为普通纸箱。</td>
</tr>
<tr>
<td colspan="8" align="left" >五、付款方式及发票:转账,款到发货。供方提供13%增值税销售发票。</td>
</tr>
<tr>
<td colspan="8" align="left" >六、本合同在履行过程中发生争议,双方当事人协商解决。</td>
</tr>
<tr>
<td colspan="8" align="left" >七、本合同一式两份,供方需方各一份。本合同传真件同样有效。</td>
</tr>
<tr>
<td colspan="8" >
<table border="1" cellspacing="0" cellpadding="6" width="100%" >
<tr>
<td>
<table>
<tr>
<td colspan="2" align="center">供 方</td>
</tr>
<tr><td></td></tr>
<tr>
<td width="80">单位名称: </td>
<td>深圳逗点生物技术有限公司</td>
</tr>
<tr>
<td>单位地址: </td>
<td>深圳市龙岗区布吉街道甘李六路12号中海信创新 产业城12栋1楼</td>
</tr>
<tr>
<td>委托代理人: </td>
<td>{$sale}</td>
</tr>
<tr>
<td>电话: </td>
<td>0755-25498787</td>
</tr>
<tr>
<td>传真: </td>
<td>深圳逗点生物技术有限公司</td>
</tr>
<tr><td></td></tr>
<tr>
<td>公司账号:</td>
<td>44201595600052506437</td>
</tr>
<tr><td></td></tr>
<tr>
<td>开户银行:</td>
<td>中国建设银行深圳东湖支行</td>
</tr>
<tr><td></td></tr>
<tr>
<td>户名:</td>
<td>深圳逗点生物技术有限公司</td>
</tr>
</table>
</td>
<td>
<table>
<tr>
<td colspan="2" align="center">需 方</td>
</tr>
<tr><td></td></tr>
<tr>
<td width="80">单位名称: </td>
<td>{$userInfo['real_name']}</td>
</tr>
<tr><td></td></tr>
<tr>
<td>单位地址: </td>
<td>{$userInfo['f_biz_address']}</td>
</tr>
<tr><td></td></tr>
<tr>
<td>委托代理人: </td>
<td>{$userInfo['f_contact']}</td>
</tr>
<tr><td></td></tr>
<tr>
<td>移动电话: </td>
<td>{$userInfo['f_mobile']}</td>
</tr>
<tr><td></td></tr>
<tr>
<td>固定电话: </td>
<td></td>
</tr>
<tr><td></td></tr>
<tr>
<td>邮编:</td>
<td></td>
</tr>
<tr><td></td></tr>
<tr>
<td>传真:</td>
<td></td>
</tr>
</table>
</td>
</tr>
</table>
</td>
</tr>
<tr>
<td colspan="3">合同有效期: {$startTime} 至 {$endTime}</td>
</tr>
</table>
</div>
EOD;
//这里其实就是盖那个章哦,这个地方要使用网络路径
$pdf->Image($site_url .'/uploads/1.png', 30, 180, 75, 75, 'PNG', '', '', true, 150, '', false, false, 1, false, false, false);
// output the HTML content
$pdf->writeHTML($html, true, false, true, false, '');
// Close and output PDF document
// This method has several options, check the source code documentation for more information.
$pdf->Output($name, 'F');
复制代码
总结
到这里基本上就已经实现通过tcpdf从0导出较复杂的PDF.