JS转PDF
前端时间调研了一下js转pdf的一些方案,做个整理。
一开始考虑前端转还是后端转,后来想想前端可能做出来和看到的会更像一点,所以先考虑前端的方案。
首先通过google和ata等搜到jsPDF这个库,不过一开始看到例子都不是把html转成pdf。
后来看了它的一些文档,里面有个fromHTML方法,不过它不支持utf8,其github上有个issue,就我看到了有这几个workaround:
1和2看上去比较复杂,而且也没找到明确的从HTML转pdf的方法,所以直接尝试方案三,不过有兴趣也可以研究一下。查看了addHTML的文档和代码后,写了下面这个js:
var pdf = new jsPDF('p','pt','a4'); var element = $("body"); element = document.getElementsByClassName("span12")[0];//element.find('.span12'); console.log(element); pdf.addHTML(element,{ format: 'png', pagesplit: true, rstz: true },function() { var string = pdf.output('datauristring'); pdf.save("abc.pdf"); $('.preview-pane').attr('src', string); });
看上去它的原理就是先把当前页面通过html2canvas或者rasterizeHTML库转成图片,然后调用jsPDF的addimage来生成pdf。上述代码中rstz就是控制用html2canvas还是rasterizeHTML。 不过它主要问题是不会自动分页,要自动分页的话要加上pagesplit这个选项,但是会失真。
下面贴一些效果图:
### html2canvas + No pagesplit
### html2canvas + pagesplit
### rasterizeHTML + No pagesplit
### rasterizeHTML + pagesplit
可以看到html2canvas在分页时候会失真,rasterizeHTML表现良好。
不过在做我们这个demo的时候,我发现rasterizeHTML对那些复杂一点的css支持不是太友好,而且装起来也比较复杂,所以最后还是用了html2canvas。然后尝试绕过分页的bug, 最后通过多次调用addHTML来避免问题。代码如下:
var pdf = new jsPDF('p', 'pt', 'a4'); var header = document.getElementsByTagName('header')[0]; var options = { format: 'png' }; var ready = false; var sections = [ document.getElementById('main-result'), document.getElementById('deep-result'), document.getElementById('other-result') ]; var cy = 120; function makePDF(eles) { pdf.addHTML(header, 0, 0, options, function () { addPage(eles); }); } function addPage(eles) { if (!eles || eles.length <= 0) { ready = true; return; } var ele = eles[0]; pdf.addHTML(ele, 0, cy, options, function () { cy = 0; if (eles.length > 1) { pdf.addPage(); } addPage(eles.slice(1)); }); } makePDF(sections); $('#onDownload').click(function () { if (ready) { pdf.save('def.pdf'); } });
理论上我感觉通过查看它本身addhtml的源码是能解决分页问题的,不过由于时间和能力关系我还没法解决。如果有能解决的欢迎告诉我。
另外网上有个类似的方案也可以参考一下.
对于后端生成pdf, 理论上也是可行的,比如这里 和 这里 不过看上去都很复杂,不如前端生成的简单。
还有就是通过phantomjs, 因为时间关系也没好好研究。
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
使用Guava 缓存的一次重构
前端时间看了一个guava教程, 然后项目中正好用到一个缓存的场景,于是用它的缓存重构了原来的代码。 背景 业务背景如下:有一个配置项rootStaff,一个耗时的运算从rootStaff下拿到一堆关联的staff,得到一个staffList。rootStaff可配置可更改,staffList可能会因为员工入职离职而变化,所以每天要更新一下计算结果。 根据以上业务背景,我们需要缓存rootStaff和staffList, 如果rootStaff和缓存不一样或者时间过期了就需要重新计算。 Guava缓存简析 guava缓存主要参考了这篇文章,这里就不再复述。 实现 在设计怎么构造和调用缓存时我还是想把它写成一个缓存工具类和一个业务类,虽然目前还没有第二个地方调用工具类,只是那样看上去会更清晰一些。 对缓存工具类,由于我想做成更业务无关些,所以打算采用get(K, Callable<V>)方法而不是build时候传入方法。然后缓存策略默认写死一天过期以后也可以方便的改。 另外由于我们缓存可能会因为外部配置项rootStaff改变而改变,我加了一个cleanCache的方法。 c...
- 下一篇
【从入门到放弃-PHP】foreach 引用的坑
背景描述 先看一段代码。 $arr = [ 'jack' => '20', 'tom' => '21', 'marry' => '54', 'less' => '23' ]; foreach ($arr as &$val) { echo $val; } foreach ($arr as $val) { echo $val; } print_r($arr); 想一下应该输出什么呢? 运行一下脚本,真实结果和你想的是否一致呢?在foreach中使用了引用后再次foreach发现$arr['less']的值变成了54,常规理解应该是23才对。 猜测可能是因为使用引用导致该值变为54 但本着知其然更要知其所以然 我们一起追一下php源码 是什么原因导致的 环境
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
-
Docker使用Oracle官方镜像安装(12C,18C,19C)
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- CentOS8编译安装MySQL8.0.19
- Docker快速安装Oracle11G,搭建oracle11g学习环境
- SpringBoot2配置默认Tomcat设置,开启更多高级功能
- MySQL8.0.19开启GTID主从同步CentOS8
- CentOS7,8上快速安装Gitea,搭建Git服务器
- Jdk安装(Linux,MacOS,Windows),包含三大操作系统的最全安装
- SpringBoot2编写第一个Controller,响应你的http请求并返回结果
推荐阅读
最新文章
- CentOS6,CentOS7官方镜像安装Oracle11G
- Windows10,CentOS7,CentOS8安装Nodejs环境
- CentOS8编译安装MySQL8.0.19
- SpringBoot2整合Thymeleaf,官方推荐html解决方案
- 设置Eclipse缩进为4个空格,增强代码规范
- CentOS7,8上快速安装Gitea,搭建Git服务器
- Windows10,CentOS7,CentOS8安装MongoDB4.0.16
- CentOS7安装Docker,走上虚拟化容器引擎之路
- CentOS6,7,8上安装Nginx,支持https2.0的开启
- CentOS7编译安装Cmake3.16.3,解决mysql等软件编译问题