mpdf 结合thinkphp5.1 容器调用

<?php

/*
 * @Description:  html转pdf 在线查看pdf ,下载pdf,保存pdf 至服务器 如果需要自行参考手册网站:https://mpdf.github.io/
 * @ComposerRequire: composer require mpdf/mpdf
 * @ComposerRemove: composer remove mpdf/mpdf
 * @Author: 阿海 <764882431@qq.com>
 * @Date: 2020-11-10 15:19:53
 * @LastEditTime: 2021-01-11 10:54:21
 * @LastEditors: 阿海
 *  echo app("php_pdf",['config'=>['desc'=>false,'content'=>'<div style="color:red;text-align:center">html主体<img src="http://himg.bdimg.com/sys/portrait/item/150a6168616939337535.jpg" /></div>']])->createServer();
 */

namespace app\common\library;

use Mpdf\Mpdf;
use Smalot\PdfParser\Parser;

class PHPPdf
{
    /**
     * 文件保存名称,不用写后缀名称
     * @param string
     */
    private $fileName = 'mpdf.pdf';

    /**
     * 每一页的页眉
     * eg:<div style='text-align:center;color:red;font-size:12px;'>我是页眉</div>
     */
    private $header = "";

    /**
     * 每一页的页脚
     * eg:<div style='text-align:center;color:red;font-size:12px;'>我是页脚</div>
     */
    private $footer = "";

    /**
     * 正文 --- html文本内容
     * 您可以设置CSS值page-break-before,以always | left | right用于任何块级元素(P,DIV等)。
     * 这将强制分页,但是请注意,所有封闭的(外部)块元素都将被“关闭”,并且其特性将丢失。
     * 您可以设置CSS值page-break-inside到avoid任何块元素。
     * mPDF会尝试避免在块内进行分页,但这只能在最多2页上使用,并且与表格自动调整大小或表格旋转不兼容
     * eg:<style>div{font-size:30px;color:red}</style><h2 style='text-align:center'>阿海</h2><div>正文</div>主题
     * @param string
     */
    private $content = "";

    /**
     * null:在线查看[我本地查看乱码-找到原因-不能使用其他网站的图片链接[绝对地址均可],也就是图片的文件必须在本地,不能跨域],
     * true:下载至本地[没有问题], 
     * false:保存至服务器[没有问题]
     * @param null|boolean
     */
    private $desc = null;

    /**
     * 保存至服务器的路径
     */
    private $filePath = "";

    /**
     * 水印
     * ['path'=>'水印相对路径即可 如runtime/.../**.png','text'=>'水印文本','alpha'=>'透明度,大于0小于等于1','size'=>'大小','pos'=>'位置','behind'=>'水印文字和水印图片是否在内容后面']
     */
    private $water = [];

    /**
     * mpdf 的临时文件目录
     */
    private $tempdir = "";

    public function __construct($config = [])
    {
        isset($config['fileName']) && $this->fileName =  mb_convert_encoding($config['fileName'], 'UTF-8', 'UTF-8,GBK,GB2312,BIG5');
        isset($config['content']) && $this->content = $config['content'];
        isset($config['header']) && $this->header = $config['header'];
        isset($config['footer']) && $this->footer = $config['footer'];
        isset($config['desc']) && $this->desc = $config['desc'];
        $this->water = (isset($config['water']) && is_array($config['water'])) ? array_merge(['path' => '', 'text' => '', 'alpha' => 0.9, 'size' => 'D', 'pos' => 'F', 'behind' => true], $config['water']) : [];
        $this->filePath = env('root_path').(isset($config['filePath']) ? $config['filePath'] : "runtime/uploads/files/" . date("Y-m-d"));
        //设置默认的临时目录
        $this->tempdir = env('root_path').(isset($config['tempdir']) ? $config['tempdir'] : 'runtime/temp_pdf');
        //文件名去除后缀,强制文件后缀为pdf
        if (strripos($this->fileName, ".") !== false) {
            $this->fileName = substr($this->fileName, 0, strripos($this->fileName, ".")) . ".pdf";
        } else {
            $this->fileName .= ".pdf";
        }
       //测试水印
       //$this->water = ['path'=>'https://ss3.bdstatic.com/70cFv8Sh_Q1YnxGkpoWK1HF6hhy/it/u=2563232234,119593447&fm=26&gp=0.jpg','text'=>'公章0058','alpha'=>'0.5','size'=>'D','pos'=>'F','behind'=>true];
    }

    /**
     * 设置html内容
     * @param $html html内容
     */
    public function setHtmlContent($html)
    {
        $this->content = $html;
    }

    /**
     * 下载pdf
     * @return empty|string
     */
    public function createServer()
    {
        try {
           
            //在线看---有bug---乱码---直接展示在浏览器页面 : 找到原因-- 不能使用其他网站的图片链接,也就是图片的文件必须在本地,不能跨域
            if (is_null($this->desc)) {
               return $this->inLink();
            }
            //下载至本地
            if ($this->desc == true) {
              return  $this->download();
            }
            //保存至服务器
            if ($this->desc == false) {
               return $this->save();
            }
        } catch (\Mpdf\MpdfException $e) {
            app("api_result")->echoJson(-3,['msg'=>$e->getMessage()]);
        }
    }

    /**
     * 下载pdf
     */
    public function download(){
        $mpdf = $this->createMpdf();
        $mpdf->Output($this->fileName, true);
        exit;
    }

    /**
     * 保存至本地
     * @return obj
     */
    public function save(){
        $mpdf = $this->createMpdf();
         //创建保存文件的目录--文件目录
         if (!file_exists($this->filePath)) {
            // @mkdir($this->filePath, 0777, true);
            @mkdir(iconv("UTF-8", "GBK", $this->filePath), 0777, true);
        }
        //如果文件已经存在,则以新建文件名称--保存文件,避免覆盖文件
        if (file_exists($this->filePath . "/" . $this->fileName)) {
            $this->fileName = substr($this->fileName, 0, strripos($this->fileName, ".")) . "_" . date("Y") . "_" . date("m") . "_" . date("d") . "_" . rand(0, 10000) . ".pdf";
        }
        $mpdf->Output($this->filePath . "/" . $this->fileName, false);

        return substr($this->filePath . "/" . $this->fileName,strlen(env('root_path')));
    }

    /**
     * 线上查看
     * 
     */
    public function inLink(){
        $mpdf = $this->createMpdf();
        $mpdf->Output();
        exit;
    }

    /**
     * @return obj
     */
    private function createMpdf(){
         //创建临时文件目录
         if (!file_exists($this->tempdir)) {
            @mkdir($this->tempdir, 0777, true);
        }
        //'default_font'=>'Sun-ExtA' 解决中文乱码 中文标点符号 ---Sun-ExtA 这个字体是在mpdf中composer包里面的ttfonts目录里面的文件名
        $mpdf = new Mpdf(['tempDir' => $this->tempdir,'default_font'=>'Sun-ExtA']);
        //设置中文字体--乱码解决
        // $mpdf->autoScriptToLang = true;
        // $mpdf->autoLangToFont = true;
     
        //您可以设置CSS值page-break-inside到avoid任何块元素。mPDF会尝试避免在块内进行分页,但这只能在最多2页上使用,并且与表格自动调整大小或表格旋转不兼容
        $mpdf->use_kwt = true;
        //页眉
        $mpdf->SetHTMLHeader($this->header);
        //页脚
        $mpdf->SetHTMLFooter($this->footer);
        //调试图片不显示时,可以使用--会报告错误原因
        // $mpdf->showImageErrors = true;
        //是否加水印
        if (is_array($this->water) && count($this->water) > 0) {
            //watermarkImgBehind --- true:将水印图像放置在页面内容后面;false:将水印图像放置在所有页面内容的前面
            $mpdf->watermarkImgBehind = $this->water['behind'];
            //解决中文水印文字---Sun-ExtA 这个字体是在mpdf中composer包里面的ttfonts目录里面的文件名
            $mpdf->watermark_font = 'Sun-ExtA';
            //水印图片
            if (isset($this->water['path']) && !empty($this->water['path'])) {
                $mpdf->showWatermarkImage = true;
                $mpdf->SetWatermarkImage($this->water['path'], $this->water['alpha'], $this->water['size'], $this->water['pos']);
            }
            //水印文字
            if (isset($this->water['text']) && !empty($this->water['text'])) {
                $mpdf->showWatermarkText = true;
                $mpdf->SetWatermarkText($this->water['text'],  $this->water['alpha']);
            }
        }
        //记住一点,所有的参数设置必须在写入内容之前。至于分页建议在html代码里面设置
        //您可以设置CSS值page-break-before,以always | left | right用于任何块级元素(P,DIV等)。
        //这将强制分页,但是请注意,所有封闭的(外部)块元素都将被“关闭”,并且其特性将丢失。
        //WriteHTML第二个参数0:html内容+css样式 1:css样式,不编译html代码, 2:只编译html内容,style包含的样式原样输出 3:不编译html代码,4:将html代码写入到缓冲区
        $mpdf->WriteHTML($this->content, 0);
        
        return $mpdf;
    }

    /**
     * 解析pdf文件  只能进行提取文字 图片 分页提取等 [不能完整将pdf的排版输出]
     * @param string $filePath docx 文件路径
     * @return string
     */
    public function pdfParser($filePath)
    {
        if (!file_exists($filePath)) {
            throw new \Exception("文件不存在,请检查文件路径");
        }

        $parser = new Parser();
        $pdf    = $parser->parseFile($filePath);

        //提取图片
        $images = $pdf->getObjectsByType('XObject', 'Image');

        foreach ($images as $image) {
            echo '<img src="https://img-blog.csdnimg.cn/2022010700424212042.jpg' . base64_encode($image->getContent()) . '" />';
        }

        // 输出文件的描述 如文件的创建时间,页码数等...
        $details  = $pdf->getDetails();

        foreach ($details as $property => $value) {
            if (is_array($value)) {
                $value = implode(', ', $value);
            }
            echo $property . ' => ' . $value . "\n";
        }

        //提取文字
        $pages  = $pdf->getPages();

        foreach ($pages as $page) {
            echo $page->getText();

            var_dump($page->getTextArray());
            echo "~我是有底线的~";
        }
    }
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值