公司现在需要开发一个简单的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

 

此时,数据页面完全转换成功!!!

总结常用命令

  1. --debug-javascript    显示JavaScript运行日志信息【用于测试的时候】
  2. --enable-local-file-access    允许加载本地的资源文件
  3. --enable-Javascript    运行js代码
  4. --javacript-delay    延时时间
  5. --no-stop-slow-scripts    允许加载运行缓慢的js脚本
  6. -B    设置底部边距
  7. -T    设置顶部边距
  8. -L    设置左部边距
  9. -R    设置右部边距
  10. --footer-line    显示底部分割线
  11. --footer-right [page]/[topage]/[date]    设置页码位置【right,left,center】以及各式【page:当前页码,topage:总页码,date:转换PDF时间】
  12. --footer-html    以html的形式加载页脚内容【自定义情况】
  13. --footer-spacing    页脚距离上面文字的间隙
  14. --header-line    用法与footer对应,不一一解释了。
  15. --header-right
  16. --header-html
  17. --header-spacing
  18. toc    生成目录
  19. --disable-dotted-lines    取消目录中默认的虚线
  20. --toc-text-size-shrink    更改目录中的页码数字大小【默认为0.8】
  21. 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、目录中不显示页码数

 

 

 

 

 

Logo

前往低代码交流专区

更多推荐