纯前端HTML转PDF下载(html2canvas + jsPdf 实现) 最近的一个需求,需要将页面的内容转为PDF并且下载,通过搜索终于实现了想要的效果,以下是一些笔记内容。
实现过程 我们会用到html2Canvas和JsPDF去实现。 1.html2Canvas会将html页面截屏并转为canvas 2.然后利用JsPDF将canvas图片排版后下载保存。
安装好html2canvas和jspdf html2canvas官网 和 jspdf官网
npm insatll --save html2canvas jspdf
jspdf参数
// jspdf部分源码
constructor(orientation?:any, // 方向
unit?:string,// 单位
format?:string|Array<Number>,// 格式(字符串'a4'或数组[100,200])
compressPdf?:number);// 压缩Pdf
//添加页面(用于换页)
addPage(format?: string | number[], orientation?: 'p'|'portrait'|'l'|'landscape'): jsPDF;//格式,方向
//保存/下载页面
save(filename:string, options: {returnPromise: boolean}): Promise<any>;//文件名,是否返回promise(可用于判断下载是否完成)
let PDF = new JsPDF('', 'pt', [imgWidth, imgHeight])// 方向,单位,格式,压缩Pdf
应用 首先我们在 utils 中创建 htmlToPdf.js 文件,封装一个getPdf 方法,并挂载到Vue原型上
// 导出页面为PDF格式
// 引入依赖
import html2Canvas from 'html2canvas'
import JsPDF from 'jspdf'
export default {
install(Vue, options) {
Vue.prototype.getPdf = async (title) => {
let result
var element = document.querySelector('#pdfDom') // 这个dom元素是要导出pdf的div容器
var w = element.offsetWidth // 获得该容器的宽
var h = element.offsetHeight // 获得该容器的高
var canvas = document.createElement('canvas')
canvas.width = w * 4 // 将画布宽&&高放大两倍
canvas.height = h * 4
var scale = 4 // 数值和上面一样,数字越大越清晰
var opts = {
scale: scale,
canvas: canvas,
width: w,
height: h,
useCORS: true,
background: '#FFF'
}
await html2Canvas((element), {
...opts,
allowTaint: false,
taintTest: false
}).then(function (canvas) {
let contentWidth = canvas.width
let contentHeight = canvas.height
let pageHeight = (contentWidth - 10) / 592.28 * 841.89
let leftHeight = contentHeight
// let position = 10
let imgWidth = 595.28
let imgHeight = 592.28 / contentWidth * contentHeight
let pageData = canvas.toDataURL('image/jpeg', 1.0)
let PDF = new JsPDF('', 'pt', [imgWidth, imgHeight])// 可以自定义宽度,也可以用a4,a3等等
if (leftHeight < pageHeight) {
PDF.addImage(pageData, 'JPEG', 0, 0, imgWidth, imgHeight)
} else {
while (leftHeight > 0) {
PDF.addImage(pageData, 'JPEG', 0, position, imgWidth, imgHeight)
leftHeight -= pageHeight
position -= 841.89
if (leftHeight > 0) {
PDF.addPage()
}
}
}
result = PDF.save(title + '.pdf', { returnPromise: true })//返回promise用于判断是否下载完成,便于实现局部loading哦~
}
)
return result //最后返回这个promise啦,在外面用then就可以接收res咯
}
}
}
几个应用的点
自定义页面大小
let PDF = new JsPDF('', 'pt', [imgWidth, imgHeight])
1
页面边距设置
PDF.addImage(pageData, 'JPEG', 0, 0, imgWidth, imgHeight) //设置左边距和上边距
1
如何监听下载完成
//通过设置options{ returnPromise: true },返回一个promise,通过判断promise的状态可以实现监听效果
PDF.save(title + '.pdf', { returnPromise: true })