踩坑预警
最近更新已经三年前的事情了,将近四百多个问题还未close(重复的问题也挺多的) 官网地址
安装操作
js
npm install --save html2pdf.js
or
npm install --save html2pdf.js -- force
or
cnpm install --save html2pdf.js
实现直接下载保存PDF操作
可以通过html布局好了,直接打印下载
js
import html2pdf from 'html2pdf.js';
let tableElement = document.querySelectorAll('table')
html2pdf().from(tableElement).save(filename);
踩坑历程
要求: 我这边是纯表格的打印操作,但是要求是分页的时候每个表格都是需要携带
表头
,表格内的图片
需要展示
踩坑一: 网络图片无法展示
翻阅了源码开发者上别人提的Issues中发现,这玩意html2canvas处理的时候只能支持base64,虽然有人说可以配置 html2canvas: {scale: 2, useCORS: true},
可以解决【但是我测试不行,开发者提议使用base64】
js
let imageUrl = 'https://www.baidu.com/img/flexible/logo/pc/result.png'
let image = new Image();
//解决跨域问题
image.setAttribute('crossOrigin', 'Anonymous');
image.src = imageUrl
//image.onload为异步加载
let base64Datas = []
image.onload = () => {
var canvas = document.createElement("canvas");
canvas.width = image.width;
canvas.height = image.height;
var context = canvas.getContext('2d');
context.drawImage(image, 0, 0, image.width, image.height);
var quality = 0.8;
//这里的dataurl就是base64类型
var dataURL = canvas.toDataURL("image/jpeg", quality);//使用toDataUrl将图片转换成jpeg的格式,不要把图片压缩成png,因为压缩成png后base64的字符串可能比不转换前的长!
//数组存放图片base64
base64Datas.push(dataURL);
//递归执行图片url转base64
}
踩坑二: 表头没办法在分页后的自动携带上(printJS这个插件就相当不错,可太傲娇)
这个也是我搞了好久的地方,一开始在Issues中发现添加页码的方式想法去添加表头,如
js
html2pdf().from(tableElement).set(options).toPdf().get('pdf').then(function (pdf) {
console.log(pdf)
// paf.table({html: thead})
}).save(filename);
在,then
做PDF的操作,打印PDF暴露出来的API方法中改哪个都油盐不进,一点变化都没有,放弃了,运用固定住表格里的数据高度固定,动态去插入表头进去每个数据中,实现现有表头功能
javascript
const clonedThead = tableElement.querySelector('thead').innerHTML;
let tbodyList = tableElement.querySelectorAll('tbody');
console.log(tbodyList)
tbodyList.forEach((item,index) => {
if( index % 5 === 0 && index > 0) {
item.insertAdjacentHTML('afterbegin', '<div style="padding-top: 20px">'+clonedThead+'</div>');
}
})
踩坑三: 分页出现截断内容
- 配置options 解决分页问题:
javascript
const options = {
margin: 10,
html2canvas: {
scale: 2
},
jsPDF: { unit: 'mm', format: 'a4', orientation: 'portrait'},
pagebreak: { mode: ['avoid-all', 'css', 'legacy'] },
}
- 样式控制
page-break-inside: avoid
可以保留完整的页面
page-break-before: always
可以另起新的一页从源码发现可以添加类
html2pdf__page-break
进行换页
css
//对表格内容保持完整性
.td {
min-width: 60px;
text-align: center;
word-wrap: break-word;
word-break: break-all;
border: 1px solid #000;
}
3. 浑身解数之后发现还是会保留一点第二页的数据在第一页中,这种情况有可能是html2canvas
画的canvas和设置的A4纸的大小有关了
解决: 我这边运用了插入表头的时候增加个paddingTop的高度可以解决
printJS 打印使用
挺好用的,以上的要求基本能符合需求的开发要求,可惜开源博主在Issues中说我只专注打印开发,如果需要直接下载可以用别的插件很好支持,这边就专注于打印功能
。 很显然有点满足不了我多表格区分下载的实现。他这个只支持于单个pdf导出打印预览,有实现过的小伙伴
欢迎评论给出兼容
的解决方案【【根据HTML可解决直接下载多个PDF】】
javascript
// 与html2Pdf.js 区别在的是样式需要单独配置进插件中,无法识别html里的样式,
// 如果需要分页可以根据踩坑三中的样式控制操作,并且图片无需转成base64,
// 我要处理的图片出现跨域问题,在这个插件是不存在这个问题,直接自动处理网络图片
// 附上实现方案
setTimeout(() => {
printJS({
printable: 'print', // 要打印的id
type: 'html',
header: '',
style: `@page{size:auto;margin: 0cm 1cm 0cm 1cm;}
.store-img-stock {
display:block;
padding:20px;
width: 260px;
height: 260px;
}
.s-placeholder{ visibility: hidden; }
@media print {
body {
-webkit-print-color-adjust: exact;
-moz-print-color-adjust: exact;
-ms-print-color-adjust: exact;
print-color-adjust: exact;
}
}
.hidden-border-bottom {
border-bottom: none;
border-top: none;
}
.thead-th {
background-color: #333586 !important;
color: #fff !important;
}
.empty-height {
max-height: 50px;
}
.height-20 {
height: 16px;
}
.store-table-a1 {
margin-bottom: 20px;
page-break-before: always;
}
.store-table-a1 td {
min-width: 60px;
text-align: center;
word-wrap: break-word;
word-break: break-all;
border: 1px solid #000;
}
.store-table th {
height: 35px;
border: 1px solid #000;
}
.hidden-border {
border: none !important;
}
` // 去除页眉页脚
})
}, 500)