PHP生成检验PDF版本的报告单

pdf插件:tcpdf

TP5.0框架

报告单截图

PDF字体:yahei

参考代码如下:

public function testpdflib()
    {
        require_once(ROOT_PATH.'/../extend/tcpdf/tcpdf.php');
        $tcpdf = new Pdf();
        $title = '';//标题
        $fileName = 'demo';//文件名称
        /*$imgs["wbc"] = "https://applet.linic.com.cn/static/histpaiter/46210_WBC.png";
        $imgs["plt"] = "https://applet.linic.com.cn/static/histpaiter/46210_PLT.png";
        $imgs["rbc"] = "https://applet.linic.com.cn/static/histpaiter/46210_RBC.png";
        $data_json = '[{"Flag":"","Name":"wbc","RangeHigh":"9.5","RangeLow":"3.5","Unit":"10^9\/L","Value":"9.44","CName":"白细胞"},{"Flag":"","Name":"lym%","RangeHigh":"50","RangeLow":"20","Unit":"%","Value":"20.6","CName":"淋巴细胞百分比"},{"Flag":"","Name":"gran%","RangeHigh":"75","RangeLow":"40","Unit":"%","Value":"68.8","CName":"粒细胞百分比"},{"Flag":"Up","Name":"mid%","RangeHigh":"10","RangeLow":"3","Unit":"%","Value":"10.6","CName":"中间群细胞百分比"},{"Flag":"","Name":"lym#","RangeHigh":"3.2","RangeLow":"1.1","Unit":"10^9\/L","Value":"1.94","CName":"淋巴细胞数目"},{"Flag":"Up","Name":"gran#","RangeHigh":"6.3","RangeLow":"1.8","Unit":"10^9\/L","Value":"6.50","CName":"粒细胞数目"},{"Flag":"Up","Name":"mid#","RangeHigh":"0.6","RangeLow":"0.1","Unit":"10^9\/L","Value":"1.00","CName":"中间群细胞数目"},{"Flag":"","Name":"rbc","RangeHigh":"5.8","RangeLow":"3.8","Unit":"10^12\/L","Value":"4.09","CName":"红细胞"},{"Flag":"","Name":"hgb","RangeHigh":"175","RangeLow":"115","Unit":"g\/L","Value":"134","CName":"血红蛋白"},{"Flag":"","Name":"hct","RangeHigh":"50","RangeLow":"35","Unit":"%","Value":"36.1","CName":"红细胞压积"},{"Flag":"","Name":"mcv","RangeHigh":"120","RangeLow":"82","Unit":"fL","Value":"88.2","CName":"红细胞平均体积"},{"Flag":"","Name":"mch","RangeHigh":"34","RangeLow":"27","Unit":"pg","Value":"32.7","CName":"平均血红蛋白含量"},{"Flag":"Up","Name":"mchc","RangeHigh":"354","RangeLow":"316","Unit":"g\/L","Value":"371","CName":"平均血红蛋白浓度"},{"Flag":"","Name":"rdw-cv","RangeHigh":"16","RangeLow":"11","Unit":"%","Value":"11.4","CName":"红细胞变异系数"},{"Flag":"","Name":"rdw-sd","RangeHigh":"56","RangeLow":"35","Unit":"fL","Value":"36.2","CName":"分布宽度标准差"},{"Flag":"","Name":"plt","RangeHigh":"350","RangeLow":"125","Unit":"10^9\/L","Value":"333","CName":"血小板"},{"Flag":"","Name":"mpv","RangeHigh":"12","RangeLow":"6.5","Unit":"fL","Value":"9.0","CName":"血小板平均体积"},{"Flag":"Down","Name":"pdw","RangeHigh":"17","RangeLow":"9","Unit":"fL","Value":"6.3","CName":"血小板分布宽度"},{"Flag":"Up","Name":"pct","RangeHigh":"0.282","RangeLow":"0.108","Unit":"%","Value":"0.298","CName":"血小板压积"},{"Flag":"","Name":"p-lcr","RangeHigh":"45","RangeLow":"11","Unit":"%","Value":"12.1","CName":"大血小板比例"},{"Flag":"","Name":"p-lcc","RangeHigh":"90","RangeLow":"30","Unit":"10^9\/L","Value":"40","CName":"大血小板数目"}]';
        $data_json = json_decode($data_json,true);
        list($tabledata1,$tabledata2) = array_chunk($data_json,14);
        $subtable2 = $subtable1 = '<table border="0" cellspacing="0" cellpadding="0" ><tr><th style="width:145px;font-weight: bold;" >检测项目</th><th style="width:80px;font-weight: bold;" >结果</th><th  style="width:60px;font-weight: bold;">单位</th><th style="width:80px;font-weight: bold;">参考范围</th></tr>';
        foreach ($tabledata1 as $k => $v){
            $subtable1 .= "<tr><td style='font-weight: bold;'>".($k + 1)." ".$v["CName"]."(".$v["Name"].")"."</td>";
            $subtable1 .= "<td >".$v["Value"]." <span style='color: red;font-weight: normal;'>↑</span></td>";
            $subtable1 .= "<td >".$v["Unit"]."</td><td >".$v["RangeLow"] . "~" .$v["RangeHigh"]."</td></tr>";
        }
        $subtable1 .= '</table>';
        foreach ($tabledata2 as $k => $v){
            $subtable2 .= "<tr><td style='font-weight: bold;'>".($k + 1)." ".$v["CName"]."(".$v["Name"].")"."</td>";
            $subtable2 .= "<td >".$v["Value"]." <span style='color: blue;font-weight: normal;'>↓</span></td>";
            $subtable2 .= "<td >".$v["Unit"]."</td><td >".$v["RangeLow"] . "~" .$v["RangeHigh"]."</td></tr>";
        }
        $subtable2 .= '</table>';
        $tdsubtable = '<td align="left"  colspan="2" style="width:49%;height: 350px;">'.$subtable1.'</td><td align="left"  colspan="2" style="width:47%;height: 350px;">'.$subtable2.'</td>';
        */
        $imgs = [];
        $tabledata = [
            [
                "Flag" => "",
                "Name" => "CRP",
                "RangeHigh" => "9.5",
                "RangeLow" => "3.5",
                "Unit" => "10^9\/L",
                "Value" => "9.44",
                "CName" => "C反应蛋白"
            ],
            [
                "Flag" => "",
                "Name" => "Hp-Ab",
                "RangeHigh" => "9.5",
                "RangeLow" => "3.5",
                "Unit" => "10^9\/L",
                "Value" => "9.44",
                "CName" => "胃幽门螺杆菌抗体"
            ],
            [
                "Flag" => "",
                "Name" => "MP-IgM",
                "RangeHigh" => "9.5",
                "RangeLow" => "3.5",
                "Unit" => "10^9\/L",
                "Value" => "9.44",
                "CName" => "肺炎支原体IgM抗体"
            ]
        ];
        $tdsubtable = '<td align="left"  colspan="4" style="width:100%;height: 350px;"><table border="0" cellspacing="0" cellpadding="0" ><tr><th style="width:300px;font-weight: bold;" >检测项目</th><th style="font-weight: bold;" >结果</th><th  style="font-weight: bold;">单位</th><th style="font-weight: bold;">参考范围</th></tr>';
        foreach ($tabledata as $k => $v){
            $tdsubtable .= "<tr><td style='font-weight: bold;'>".($k + 1)." ".$v["CName"]."(".$v["Name"].")"."</td>";
            $tdsubtable .= "<td >".$v["Value"]." <span style='color: blue;font-weight: normal;'>↓</span></td>";
            $tdsubtable .= "<td >".$v["Unit"]."</td><td >".$v["RangeLow"] . "~" .$v["RangeHigh"]."</td></tr>";
        }
        $tdsubtable .= '</table></td>';
        $html = <<<EOF
<style>
.tabheader{
    border-bottom: 1px solid #000;
    width: 100%;
}
.tabfooter{
    border-top: 1px solid #000;
    width: 100%;
    margin-top: 4px;
}
</style>
<table border="0" cellspacing="2" cellpadding="3" class="tabheader">
    <tr>
        <th align="center" colspan="4" style="font-weight: bold;font-size: 16px">长沙中质恒泰医学验报告单</th>
    </tr>
    <tr>
         <td style="font-weight: bold;padding-left: 20px"><label >患者姓名:</label>刘子琴</td>
         <td colspan="2"  style="font-weight: bold"><label >样本类型:</label>全血,血清,血浆</td>
         <td style="font-weight: bold"><label >样本编号:</label>202489</td>
    </tr>
    <tr>
       <td style="font-weight: bold;padding-left: 20px"><label >性 别:</label>男</td>
       <td colspan="2"  style="font-weight: bold"><label >年 龄:</label>13 周岁</td>
       <td style="font-weight: bold" ><label >检验时间:</label>2023-09-14 08:19:41</td>
    </tr>
</table>
<table border="0" cellspacing="2" cellpadding="3" >
    <tr>
        $tdsubtable
    </tr>
</table>
<table border="0" cellspacing="0" cellpadding="1" class="tabfooter">
    <tr >
        <td  align="left" style="width: 180px;font-weight: bold;padding-left: 20px"><label >报告时间:</label>2023-09-11 13:34:26</td>
        <td  align="left" style="width: 180px;font-weight: bold;"><label>打印时间:</label>2023-09-11 13:34:26</td>
        <td  align="right" style="font-weight: bold"><label >检测人:</label> </td>
        <td  align="center" style="font-weight: bold"><label >审核人:</label> </td>
    </tr>
    <tr><td colspan="4" style="font-weight: bold;">注:此检验结果仅对此次检验标本负责,结果仅供临床参考!</td></tr>
</table>
EOF;

        $synthesis = [];//图片水印 可多个
        $info = [];//二维码相关参数

        echo $tcpdf->pdfRender_D($html, $title, $fileName, $synthesis, $info,$imgs);//生成PDF
    }

封装的PDF类: 

class Pdf {
    /*
  * 生成pdf
  * @param 	string 	$html 			内容
  * @param 	string 	$title 		    标题
  * @param 	string 	$fileName 		生成的文件名称
  * @param 	string 	$synthesis 		要合成的图片路径
  * @param 	number 	$x 				x轴
  * @param 	number 	$y 				Y轴
  * @param 	number 	$m 				图片宽度
  * @param   number  $h              图片高度
  * @param	number  $setPage		图片放置在第几页
  * @param 	array 	$info
  * @param 	number 	$pdf_type 	    新的PDF存储路径标识 2019/10/23
  * @return 	合成正确返回PDF路径  合成失败返回为false
  */
    public function pdfRender_D($html, $title = '', $fileName, $synthesis = [], $info=[],$imgs=[])
    {
        //新增路径标识
        $path = '/static/preview/' . date('Ym') . '/';//文件存放路径
        $directory = ROOT_PATH;//根目录
        $is_path = $directory . $path;//全路径
        //检测并创建文件夹
        if ($this->exists_dir($is_path) === false) {
            return false;
        }
        // GetX获取x轴坐标  GetY获取y轴坐标
        $pdf = new \TCPDF("L", PDF_UNIT, "A5", true, 'UTF-8', false);//A4  PDF_PAGE_FORMAT
        //设置件信息
        $pdf->SetCreator(PDF_CREATOR);
        $pdf->SetAuthor(str_replace("http://", "", $_SERVER['HTTP_HOST']));
        $pdf->SetTitle($title);
        $pdf->SetSubject($title);
        $pdf->SetKeywords('TCPDF, PDF, example, test, guide,PHP');
        // 设置间距
        //设置默认等宽字体
        $pdf->SetDefaultMonospacedFont(PDF_FONT_MONOSPACED);
        //设置间距   左侧、上侧、右侧的间距
        $pdf->SetMargins(5, 5, 5);//PDF_MARGIN_TOP
        //$pdf->SetFooterMargin(0);
        $pdf->setCellPaddings(0, 0, 0, 0);
        $pdf->SetLineStyle(array('width' => 0, 'cap' => 'butt', 'join' => 'miter', 'dash' => '0', 'color' => array(0, 0, 0)));
        //设置自动分页符
        //$pdf->MultiCell(0, 0, 'DISK CACHING TEST: check the parameters of the class constructor.', 1, 'L', 0, 0, '', '', true);
        $pdf->SetAutoPageBreak(TRUE, 10);
        //设置图像比例因子
        $pdf->setCellHeightRatio(1.2);//设置单元格行高  1.3   1.2
        $pdf->setImageScale(PDF_IMAGE_SCALE_RATIO);
        $pdf->SetFont('yahei', '', 9); //设置中文显示  stsongstdlight
        $pdf->setPrintHeader(false);
        $pdf->setPrintFooter(false);
        $pdf->AddPage();
        $pdf->Cell(0, 1, '', 0, 1, 'C');//1.5
        if(!empty($imgs)){
            $pdf->Image($imgs["wbc"],8 ,90,50,36);
            $pdf->Image($imgs["plt"],80 ,90,50,36);
            $pdf->Image($imgs["rbc"],150 ,90,50,36);
        }
        $pdf->writeHTML($html);//时间要的多
        //PDF添加图片
        /*$num_num = $pdf->getNumPages();//获取当前页码
        if ($synthesis) {
            $count = count($synthesis);
            foreach ($synthesis as $k => $v) {
                if ($count > 10 && isset($v['qm'])) {//签名标记
                    $v['setPage'] = $num_num - 1;
                }
                if (!isset($v['h'])) {
                    $v['h'] = '';
                }
                if (isset($v['setPage'])) {
                    $pdf->setPage($v['setPage']);//setPage 在那样插入图片  默认为最后一页   $k>=6 ||  图片太多要加新页面
                }
                $pdf->Image($v['org'], $v['x'], $v['y'], $v['w'], $v['h'], '', '', '', false, 300);//时间要的多
                if (isset($v['html']) && $v['html']) {
                    $pdf->writeHTMLCell('', '', $v['x'] - 5, $v['y'] + 8, $v['html'], '', 0, 0, true, 'L', true);
                }
            }
        }*/

        //添加二维码  on_off=1 开启  set_page 二维码放置在第几页
        /*$this->qr_code_pdf(
            [
                'pdf' => $pdf, 'uniq_key' => $info['uniq_key'] ?? '',
                'on_off' => $info['on_off'] ?? 0,
                'set_page' => $info['set_page'] ?? $num_num,
                'num_num' => $num_num,
                'is_wine' => $info['wine_footer'] ?? 0,//0股权 其他为酒业
            ]
        );*/
        /*$pdf->SetFontSize(5);
        //分页
        $this->footer($pdf);//自定义分页*/

        $pdf->Output($is_path . $fileName . ".pdf","D");
        /*$url = $path . $fileName . ".pdf";
        if (file_exists($is_path . $fileName . ".pdf") !== false) {
            return $url;
        }
        return false;*/
    }


    /*Page footer 自定义分页
     *param object PDF插件对象
     *param array   $info['uniq_key'] 唯一标识
     * */
    public function footer($pdf): void
    {
        $page = 1;//页码
        //$pdf->setPage(1);//设置页面
        //用此函数可以设置可选边框,背景颜色和HTML文本字符串来输出单元格(矩形区域)  W:设置单元格宽度。0,伸展到右边幅的距离  H:设置单元格最小的高度  X:以左上角为原点的横坐标  Y:以左上角为原点的纵坐标  Html:html文本  Border:边框  Ln:0,单元格后的内容插到表格右边或左边,1,单元格的下一行,2,在单元格下面  Fill:填充   Reseth:true,重新设置最后一行的高度  Align:文本的位置  Autopadding:true,自动调整文本到边框的距离。
        $pdf->writeHTMLCell('', '', 14, 2, '<span style="color:#000;">' . $page . '  page</span>', '2', 0, 0, true, 'L', true);
        $pdf->writeHTMLCell('', '', 80, 2, '<span style="color:#000;">页眉内容</span>', '2', 0, 0, true, 'L', true);
        //设置单行单元格:W:设置单元格的宽  H:设置单元格的高  Text:单元格文本  Border:设置单元格的边框。0,无边框,1,一个框,L,左边框,R,右边框,B, 底边框,T,顶边框,LTRB指四个边都显示   Ln:0,单元格后的内容插到表格右边或左边,1,单元格的下一行,2,在单元格下面   Align:文本位置。L,左对齐,R,右对齐,C,居中,J,自动对齐  Fill:填充。false,单元格的背景为透明,true,单元格必需被填充   Link:设置单元格文本的链接。
        $pdf->SetY(8);
        $pdf->Cell(180, 0, '', 1, 0, 'C', 0, '', 0, true);//180
    }

    /**
     * Notes:pdf 加二维码  http:/hw.com/sign/pdf/demo
     * User: ZHOU WEI YUN
     * Date: 2021/9/23 0023
     * Time: 下午 5:37
     * @param array $arr on_off=1 开启添加二维码  uniq_key:唯一标识 pdf控件对象  set_page放置页面
     * @return void
     */
    public function qr_code_pdf(array $arr): void
    {
        //生成二维码  文档 https://tcpdf.org/examples/example_027/
        if (!empty($arr['on_off']) && $arr['on_off'] === 1) {
            if ($arr['num_num'] < $arr['set_page']) {
                $arr['set_page'] = $arr['num_num'];
            }

            //二维码链接
            $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');
        }
    }

    /**
     * Notes: 获取当前域名
     * User: ZHOU WEI YUN
     * Date: 2022/2/12 0012
     * Time: 上午 11:38
     * @param array
     * @return string
     */
    public function site(): string
    {
        return $_SERVER['REQUEST_SCHEME'] . '://' . $_SERVER['SERVER_NAME'];
    }

    /**
     * Notes: 检测文件夹是否存在 不存在自动创建文件夹
     * User: ZHOU WEI YUN
     * Date: 2021/3/23 0023
     * Time: 上午 10:51
     * @param string $path 文件的绝对路径
     * @return bool  false 文件创建失败 其他返回为true
     */
    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, 755) && is_dir($ping)) {
                    return false;
                }
            }
        }
        return true;
    }


}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

qq_35652070

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值