wkhtmltopdf工具转换Vue框架踩坑记录
vue搭建的一个简单的页面,没有使用脚手架,想把html页面转换为PDF,可是会出现如下的错误Warning: file:///E:/projects/html/cart/first_test/static/js/vue.js:1891 ReferenceError: Can't find variable: itemWarning: file:///E:/projects/html/cart/f
公司现在需要开发一个简单的Vue框架,对于只了解过简单前端只是的我来说,难度挺大的。
开发的过程是艰难的,和产品沟通的过程也是心酸的,不忍吐槽。
基本框架内容码出来后,产品提出了新的要求,她不需要html,需要给他转换成PDF。
记得Chrome浏览器在打印的时候,可以转换PDF,但是觉得问题不大,只注重于修改样式,样式,样式。难受的一批。
当用chrome浏览器转换PDF的时候,发现了没想象的那么容易,html内部有许多表格,并且数据长度是不同,因为在分页的时候,
可能会出现下图的情况。
百度了好久,找到了一个解决办法
修改全局table标签的样式
table {
table-layout: fixed;
word-break: break-all;
}
添加css样式后,用Chrome浏览器转换PDF同时又发现了一个新bug,如下图
table分页的时候,新的一页没有table的横线。这个情况让追求完美的我,不能忍受。
找到了一个wkhtmltopdf的命令行工具,也有Python的第三方包,但是未使用。
安装过程就不讲解了,百度上有详细的安装方式。
安装完毕,用官方文档的测试例子,测试了一下
E:\>wkhtmltopdf https://www.baidu.com/ baidu.pdf
Loading pages (1/6)
Counting pages (2/6)
Resolving links (4/6)
Loading headers and footers (5/6)
Printing pages (6/6)
Done
在E盘根目录下多了一个baidu.pdf的pdf文件。里面的内容个百度的首页一样,瞬间感觉发现了新大陆,觉得没什么难度,just so so啦。
当第一次用自己本地的html测试的时候发现了问题,测试代码如下
E:\projects\html\cart\first_test>wkhtmltopdf index.html first_tets.pdf
Loading pages (1/6)
Warning: Blocked access to file E:/projects/html/cart/first_test/static/js/jquery.js
Warning: Blocked access to file E:/projects/html/cart/first_test/static/js/vue.min.js
Warning: Blocked access to file E:/projects/html/cart/first_test/static/js/first_part.js
Warning: Blocked access to file E:/projects/html/cart/first_test/static/css/index.css
Error: Failed to load about:blank, with network status code 301 and http status code 0 - Protocol "about" is unknown
Error: Failed to load about:blank, with network status code 301 and http status code 0 - Protocol "about" is unknown
Error: Failed to load about:blank, with network status code 301 and http status code 0 - Protocol "about" is unknown
Warning: Blocked access to file E:/projects/html/cart/first_test/images/logo.png
Error: Failed to load about:blank, with network status code 301 and http status code 0 - Protocol "about" is unknown
Error: Failed to load about:blank, with network status code 301 and http status code 0 - Protocol "about" is unknown
Counting pages (2/6)
Resolving links (4/6)
Loading headers and footers (5/6)
Printing pages (6/6)
Done
Exit with code 1 due to network error: ProtocolUnknownError
测试过程中有好几个地方报错了,并且并且还有好几处的警告,但是生成了一个PDF文件,生成的PDF如下
Vue挖坑的位置,全部没有加载【html测试的时候没有任何的问题】,因此我怀疑是wkhtmltopdf不支持Vue。
将错误信息,复制到浏览器,找到一个解决方案。在生成PDF的时候,多添加一个命令--enable-local-file-access[加载本地的资源],如下
E:\projects\html\cart\first_test>wkhtmltopdf --enable-local-file-access index.html first_test.pdf
Loading pages (1/6)
Counting pages (2/6)
Resolving links (4/6)
Loading headers and footers (5/6)
Printing pages (6/6)
Done
此时,命令行没有报错信息,查看了生成的PDF文件,还是有问题存在,只转换了一部分的html内容。
左侧是正常的转换样式,右侧是出现的新bug。
怀疑js文件没有加载完全,之后尝试添加了
--debug-javascript【显示javascript日志信息】
--enable-javascript【启动javascript】
--javascript-delay 100000【js延迟时间】
--no-stop-slow-scripts【加载缓慢的js代码】
--allow【允许访问的资源】
测试了好多好多的参数,中间放弃了好几天,转而用其他的方式实现本功能,但是其他的需要结合Java代码,看了java的方式我放弃了。
最后还是继续探索wkhtmltopdf。
我有一个大胆的猜测:我怀疑是js文件的问题。
仔细对比生成PDF的部分和没加载成功部分js代码,发现加载成功的部分,Vue实例中data参数中的数据较少,而未加载成功的部分,Vue实例内data参数中数据量较大。
找到这个不一致的地方,先修改了一各简单的demo,进行测试,果然是js文件的问题,
花费了半个多小时的时间,修改了全部的vue实例中js代码中的格局。
因公司内部文件,不方便截图,展示前后JS文件的区别。
进而使用wkhtmltopdf命令进行测试,使用的依旧是上面的测试命令行,
最终生成的文件,大致浏览了一遍后,没发现问题,当第二次仔细对比html时,发现了依旧有些部分内容未加载出来。大致有七处内容内加载。
对比七处未加载部分的代码,发现有多个共同之处:
1、均使用的双重for循环
2、均合并了table的某些行
3、均是使用了template标签
4、数据格式复杂
展示一个简单的未加载处的Vue代码
<template v-for="(item,index) in infolist">
<tr v-for="(m,i) in item.details">
<td align="center" v-if="i==0" :rowspan="item.details.length"><strong>{{item.check_type}}</strong></td>
<td><input type="checkbox" name="vehicle" checked="checked" />{{m.check_conent}}</td>
<td>{{m.check_res}}</td>
</tr>
</template>
首先我怀疑是否是因为td中进行了动态的合并rowspan操作,wkhtmltopdf未能加载这个命令,
因此先修改了Vue实例中data的数据格式,未进行td中的rowspan合并,这样生成的PDF,此部分显示在PDF内。
但是其他几处的数据改动较大,并且修改Vue代码幅度以及难度较大。
接着,考虑是否是因为不支持双重for循环呢?查看了其他加载的table处的代码,均未使用双重for循环。
如果不支持双重for循环,我的数据应该怎么加载呢,这讲面临着一个巨大的难题。
想到了template这个标签,将template标签换成其他的会是什么样子呢?
于是,将template换成了tbody【html原生的table标签】
<tbody v-for="(item,index) in info">
<tr v-for="(m,i) in item.details">
<td align="center" v-if="i==0" :rowspan="item.details.length" class="td_add_cu">{{item.check_type}}</td>
<td>{{m.check_conent}}</td>
<td>{{m.check_res}}</td>
</tr>
</tbody>
用wkhtmltopdf命令行进行测试,只需要一个--enable-local-file-access参数即可转换。
E:\projects\html\cart\first_test.2>wkhtmltopdf --enable-local-file-access index.html 1.pdf
Loading pages (1/6)
libpng warning: iCCP: known incorrect sRGB profile ] 71%
Counting pages (2/6)
Resolving links (4/6)
Loading headers and footers (5/6)
Printing pages (6/6)
Done
此时,数据页面完全转换成功!!!
总结常用命令
- --debug-javascript 显示JavaScript运行日志信息【用于测试的时候】
- --enable-local-file-access 允许加载本地的资源文件
- --enable-Javascript 运行js代码
- --javacript-delay 延时时间
- --no-stop-slow-scripts 允许加载运行缓慢的js脚本
- -B 设置底部边距
- -T 设置顶部边距
- -L 设置左部边距
- -R 设置右部边距
- --footer-line 显示底部分割线
- --footer-right [page]/[topage]/[date] 设置页码位置【right,left,center】以及各式【page:当前页码,topage:总页码,date:转换PDF时间】
- --footer-html 以html的形式加载页脚内容【自定义情况】
- --footer-spacing 页脚距离上面文字的间隙
- --header-line 用法与footer对应,不一一解释了。
- --header-right
- --header-html
- --header-spacing
- toc 生成目录
- --disable-dotted-lines 取消目录中默认的虚线
- --toc-text-size-shrink 更改目录中的页码数字大小【默认为0.8】
- cover 封面
最终的whhtmltopdf命令
wkhtmltopdf --enable-local-file-access -B 30 -T 30 --footer-html footer.html --footer-right [page] --header-html header.html --footer-spacing 10 --header-spacing 10 cover https://www.baidu.com toc --toc-header-text "目录" --disable-dotted-lines --toc-text-size-shrink 1 xxxx.html xxxx.pdf
还要一些问题没解决,之后还会更新。
问题1、如何自定义目录
问题2、目录中不显示页码数
更多推荐
所有评论(0)