订单导出pdf文件

荒凉一梦 提交于 2020-04-21 13:35:11

原理

原始数据->加载模板->临时文件->PDF文件

方案准备

  1. html模板转pdf 难点:1. 每次变化都要找设计师;2. html样式很难控制(个人不擅长);3.html转pdf样式难以控制
  2. word模板转pdf 难点:1. 合适插件的选择;2. 中文的处理

最终选择,word模板模式

实现步骤

  1. WORD插件 开源地址
    composer require phpoffice/phpword

phpword非常好用,支持变量,太方便了。

  1. WORD转PDF插件 下载地址
/opt/libreoffice6.4/program/soffice
  1. 完整demo
    //生成订单pdf
    public function order_pdf_f()
    {
        #1. 准备订单信息
        $person_addr = "北京市";
        $person_name = "张三";
        $person_mobile= "18932000000";

        #2. 生成素材文件
        $res_dir_path = './res/';
        $templateFile = $res_dir_path.'temp_order.docx';
        $wordPath = $res_dir_path.'tmp/hello.docx';//计算机上的一个文件
        try {
            $templateProcessor = new \PhpOffice\PhpWord\TemplateProcessor($templateFile);
            $templateProcessor->setValue('person_name', $person_name);
            $templateProcessor->setValue('person_addr', $person_addr);
            $templateProcessor->setValue('person_mobile', $person_mobile);
            $templateProcessor->saveAs($wordPath);
        } catch (Exception $e) {
            echo $e->getMessage();
            return;
        }

        #3. 生成pdf并下载
        try {
            $pdfPath = $res_dir_path.'tmp';
            $set_charset = 'export LANG=zh_CN.UTF-8;';#linux
            $cmd = $set_charset."\n"."/opt/libreoffice6.4/program/soffice --headless --convert-to pdf:writer_pdf_Export {$wordPath} --outdir {$pdfPath}";

            $status = 1;
            $log = null;
            $log = shell_exec($cmd);
            if(is_null($log)) {
                #echo "start exec";
                exec($cmd.' 2>&1', $log, $status);
            }
            sleep(1);

            #4. 页面跳转到下载
            $file =$pdfPath."/hello.pdf";//计算机上的一个文件
            $fileName = basename($file);//获取文件名
            header("Content-Type:application/octet-stream"); //告诉浏览器文档类型(mime类型); octet-stream指的是二进制文件类型;下载任何类型的文件都可以这么指定
            header("Content-Disposition:attachment;filename=".$fileName); //告诉浏览器以附件方式对待文件(即下载文件);并设置下载后的文件名
            header("Accept-ranges:bytes"); //告诉浏览器文件大小的单位
            header("Accept-Length:".filesize($file)); //告诉浏览器文件的大小
            $h = fopen($file, 'r'); //打开文件
            echo fread($h, filesize($file));
        } catch (Exception $e) {
            echo $e->getMessage();
            return;
        }
    }

注意

导出时,老是出现乱码,一开始比较抓狂。不知道哪里出了问题。后来冷静分析了一下。

  1. 数据->word模板->word文件,只要生成的word文件,没有乱码就成功一半了 系统环境变量修改
#1. 修改语言环境变量
vi  /etc/locale.conf
LANG=zh_CN.UTF-8

插件底层源码修改

/www/wwwroot/项目名/vendor/phpoffice/phpword/src/PhpWord/TemplateProcessor.php
第256行
    /**
     * @param string $subject
     *
     * @return string
     */
    protected static function ensureUtf8Encoded($subject)
    {
        if (!Text::isUTF8($subject)) {
            #$subject = utf8_encode($subject);
            $subject =  iconv("GB2312","UTF-8//IGNORE",$subject);
        }

        return $subject;
    }

  1. word文件->pdf,要是还有乱码,考虑是字体的原因。安装字体解决 https://blog.csdn.net/wlwlwlwl015/article/details/51482065

#1. 在CentOS 4.x开始用fontconfig来安装字体库
yum -y install fontconfig

#2. 创建中文字体路径
mkdir -p /usr/shared/fonts/chinese

#3. ftp上传字体到 /usr/shared/fonts/chinese
c盘下的Windows/Fonts目录

#4. 修改字体权限
chmod -R 755 /usr/share/fonts/chinese

#5. 安装ttmkfdir来搜索目录中所有的字体信息
yum -y install ttmkfdir

#6. 执行ttmkfdir命令
ttmkfdir -e /usr/share/X11/fonts/encodings/encodings.dir

#7. 引入中文
vi /etc/fonts/fonts.conf
...
<dir prefix="xdg">fonts</dir>
<dir>/usr/share/fonts/chinese</dir> #新加这行
...

#8. 刷新内存中的字体缓存
fc-cache

#9. 检查是否生效
fc-list
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!