js html转pdf并在线浏览器,Egg + Puppeteer 实现Html转PDF

背景

项目组有个类似富文本编辑器功能,在IE浏览器下需要支持打印。为解决打印兼容性问题,需要一套根据Html输出PDF的服务。

so, 想直接看结果的: Html转PDF 在线预览 😎😎😎

45ef853dd664df70258620c16df6347a.png

调研

html转pdf方案有很多,怎么选择也看各位的具体情况

1、chrome浏览器自带

0ea13ceffac9f29be610f77317e35640.png

缺点:

需要用户自己点击

用户需要使用chrome等支持的浏览器

打印默认是全局打印

eb9ed86e0ae50ce20a0e6227488c432d.png

广告:局部打印可以参考我的插件😝😝😝: vue-iframe-print

npm install vue-iframe-print 在需要打印的DOM上加上v-print即可实现局部打印

2、html2canvas + jsPdf

缺点:

html2canvas插件在IE的兼容性问题

清晰度问题

分页问题

文字图片截断问题

3、node服务端转换

phantomjs 基于webkit的无头浏览器,社区使用的不多,很久没更新了,可以深度了解下

Puppeteer + Headless Chrome 社区里使用该方案的也比较多

eab5f53d501610898c29bc3a828e7cb6.png

选用Egg + Puppeteer 😉😉😉

部署(敲黑板)❗❗❗

当你已经完成了基本功能以后,高高兴兴的以为就剩下最后一步了,那么坑来了~

1、在 Docker 中使用 Puppeteer

官方文档指出“在 Docker 中使用 headless Chrome 并使其运行起来可能会非常棘手”。官方文档有疑难解答部分,你可以找到有关用 Docker 安装 puppeteer 的所有必要信息。

如果你在 Alpine 镜像上安装 Puppeteer,请确保在看到页面的这一部分时再向下滚动一点。否则你可能会忽略一个事实:你无法运行最新的 Puppeteer 版本,并且你还需要用一个标记禁用 shm

const browser = await puppeteer.launch({

headless: true,

args: ['--disable-dev-shm-usage']

});

复制代码

否则,Puppeteer 子进程可能会在正常启动之前耗尽内存。

2、在centOS中部署

第一步:安装chrome

因为是直接使用的Puppeteer包,需要依赖于chrome内核,所以你在启动项目npm install 的时候会一直卡在node install.js这里,因为china网络问题和chrome太大,你很难在服务器上直接部署成功。

puppeteer支持本地chrome安装链接,所以可以手动指定

跳过chrome安装:npm install puppeteer --ignore-scripts

坑出没,warning~

const browser = await puppeteer.launch({

args: ['--disable-dev-shm-usage', '--no-sandbox'],

headless:true,

// linux chrome的默认安装路径

executablePath:'/opt/google/chrome/chrome'

});

复制代码

这里写的puppeteer启动路径executablePath是linux下chrome的安装路径,如果换了本地,不同的系统对应的路径可能都不一样~ 千辛万苦找了一个包,很好用~ npm install carlo

'use strict';

const puppeteer = require('puppeteer');

const findChrome = require('../../node_modules/carlo/lib/find_chrome');

let browser = null;

module.exports = async () => {

if (!browser) {

const findChromePath = await findChrome({});

// browser = await puppeteer.launch();

browser = await puppeteer.launch({

headless: true,

// chrome的默认安装路径

executablePath: findChromePath.executablePath,

args: [

'--disable-gpu',

'--disable-dev-shm-usage',

'--disable-setuid-sandbox',

'--no-first-run',

'--no-sandbox',

'--no-zygote',

'--single-process',

],

});

}

return browser;

};

复制代码

第二步:部署脚本

虽然egg有自己的进程管理,但是这里还是推荐使用pm2,在项目根目录下

新建 deploy.sh

# 部署脚本

type node

npm install puppeteer --ignore-scripts

npm install

pm2 kill

# 睡眠,避免出现错误:Spawning PM2 daemon with pm2_home

sleep 2

pm2 start pm2.config.json

复制代码

新建 pm2.config.json

{

"apps": [

{

"name": "html-to-pdf",

"script": "npm",

"args": "run start",

"log_date_format": "YYYY-MM-DD HH:mm:ss",

"exec_mode": "fork",

"max_memory_restart": "500M"

}

]

}

复制代码

一切就绪,启动!!!

在服务器的项目中执行sh deploy.sh, pm2显示启动成功即可

这个时候服务是没问题了,但是其他问题就来了,因为服务器上是没有中文字体库的~所以生成的pdf,中文字体全是乱码

6cdcfff1a581f6585067c47087e17c2c.png

第三步:安装字体

一、安装fontconfig

yum -y install fontconfig

这个命令执行完成之后,就可以在/usr/share文件夹里面看到fonts和fontconfig

二、添加中文字体库

从window的C:\Windows\Fonts里面字体拷贝一份,或者只选择你需要的

在CentOS的/usr/share/fonts新建一个叫chinese的文件夹

然后把刚刚拷贝字体放到CentOS的/usr/share/fonts/chinese里面

修改chinese目录的权限。chmod -R 775 /usr/share/fonts/chinese

接下来需要安装ttmkfdir来搜索目录中所有的字体信息,并汇总生成fonts.scale文件,输入命令yum -y install ttmkfdir

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

打开字体配置文件,vi /etc/fonts/fonts.conf,添加下面这一段

复制代码

刷新内存中的字体缓存,fc-cache

看一下现在机器上已经有了刚才添加的字体。fc-list :lang=zh

大功告成

这个时候基本就没问题了, 后续遇到的问题再更新

0dc986fb0fed26200e12ab1b2f31cd56.png

最后:IE加载PDF

需要安装下adobe reader

c399dd8e70fba114684922c8ebd2a2fd.png

参考

3d62305187fbcfc0cac772eeab22edb7.png

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值