在线查看pdf ,下载pdf,保存pdf 至服务器
composer require mpdf/mpdf
2020-04-03 写的
2020-04-04 发现PHPExcel的文章忘了写保存至本地,同时发现文件名称有可能存在中文名称,那么pdf也有可能存在中文名,于是使用函数名称mb_convert_encoding
2020-04-05 修改设置的fileName 以便支持中文的文件名称
<?php
/**
* +----------------------------------------------------------------------
* | ThinkPHP [ WE CAN DO IT JUST THINK ]
* +----------------------------------------------------------------------
* | Copyright (c) 2020 ahai574 All rights reserved.
* +----------------------------------------------------------------------
* | Licensed ( ++++ahai574++++ )
* +----------------------------------------------------------------------
* | Author: 阿海 <764882431@qq.com>
* +----------------------------------------------------------------------
* 将html---转---pdf
* 更多细节 如果需要自行参考手册网站:https://mpdf.github.io/
*
*/
namespace app\common\library;
use Mpdf\Mpdf;
class PHPPdfLib
{
/**
* 文件保存名称,不用写后缀名称
* @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 = isset($config['filePath']) ? $config['filePath'] : "runtime/uploads/files/" . date("Y-m-d");
//设置默认的临时目录
$this->tempdir = 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";
}
}
/**
* 设置html内容
* @param $html html内容
*/
public function setHtmlContent($html)
{
$this->content = $html;
}
/**
* 下载pdf
* @return empty|string
*/
public function createServer()
{
try {
//创建临时文件目录
if (!file_exists($this->tempdir)) {
@mkdir($this->tempdir, 0777, true);
}
$mpdf = new Mpdf(['tempDir' => $this->tempdir]);
//设置中文字体--乱码解决
$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'];
//水印图片
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);
//在线看---有bug---乱码---直接展示在浏览器页面 : 找到原因-- 不能使用其他网站的图片链接,也就是图片的文件必须在本地,不能跨域
if (is_null($this->desc)) {
$mpdf->Output();
exit;
}
//下载至本地
if ($this->desc == true) {
$mpdf->Output($this->fileName, true);
exit;
}
//保存至服务器
if ($this->desc == false) {
//创建保存文件的目录--文件目录
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 $this->filePath . "/" . $this->fileName;
}
} catch (\Mpdf\MpdfException $e) {
echo $e->getMessage();
}
}
} 最佳答案