安装依赖
npm install html2canvas--save
npm install jspdf --save
html2canvas 通过获取HTML的dom元素,然后生成Canvas,保存为图片
jsPDF 生成 PDF 文档
创建utils/htmlToPdf.js
import html2Canvas from 'html2canvas'
import JsPDF from 'jspdf'
export default {
install(Vue, options) {
/**
*
* @param {*} reportName 下载时候的标题
* @param {*} isDownload 是否下载默认为下载,传false不下载
*/
Vue.prototype.getPdf = function (reportName, isDownload = true) {
return new Promise((resolve, reject) => {
// 特别重要:当页面超过一页,出现滚动条,滚动的部分生成的图片为空白
window.pageYoffset = 0
document.documentElement.scrollTop = 0
document.body.scrollTop = 0
var title = reportName;
html2Canvas(document.querySelector('#pdfDom'), {
allowTaint: true,
background: '#FFF',
}).then((canvas) => {
let contentWidth = canvas.width
let contentHeight = canvas.height
//一页pdf显示html页面生成的canvas高度;
let pageHeight = contentWidth / 592.28 * 841.89
//未生成pdf的html页面高度
let leftHeight = contentHeight
//页面偏移
let position = 0
//a4纸的尺寸[595.28,841.89],html页面生成的canvas在pdf中图片的宽高
let imgWidth = 592.28
let imgHeight = 592.28 / contentWidth * contentHeight
let pageData = canvas.toDataURL('image/jpeg', 1.0)
let PDF = new JsPDF('', 'pt', 'a4')
//有两个高度需要区分,一个是html页面的实际高度,和生成pdf的页面高度(841.89)
//当内容未超过pdf一页显示的范围,无需分页
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()
}
}
}
if (isDownload) {
PDF.save(title + '.pdf')
}
// 删除本地存储的base64字段
var pdfData = PDF.output('datauristring')
resolve(pdfData)
}
)
})
}
}
}
main.js引入
import htmlToPdf from "./utils/htmlToPdf.js"
Vue.use(htmlToPdf)
组件使用
<div id="pdfDom">
<div class="pdf-dom">
// ... 分割dom
</div>
<div class="pdf-dom">
// ... 分割dom
</div>
<div class="pdf-dom">
// ... 分割dom
</div>
</div>
<van-button type="primary" @click="toGetPdf('pdf名称', false)">PDF</van-button>
// 直接导出download = true即可
toGetPdf(tile = "", download = false) {
Toast.loading('请稍候...')
let vm = this;
vm.pdfPrint = true // 打印的pdf样式加载
const A4_WIDTH = 592.28;
const A4_HEIGHT = 841.89;
vm.$nextTick(() => {
// dom的id
let target = document.getElementById('pdfDom');
let pageHeight = target.scrollWidth / A4_WIDTH * A4_HEIGHT;
// 获取分割dom,此处为class类名,避免分页处图片文字被截断
let lableListID = document.getElementsByClassName('pdf-dom');
// 进行分割操作,当dom内容已超出a4的高度,则将该dom前插入一个空dom,把他挤下去,分割
for (let i = 0; i < lableListID.length; i++) {
let multiple = Math.ceil((lableListID[i].offsetTop + lableListID[i].offsetHeight) / pageHeight);
if (vm.isSplit(lableListID, i, multiple * pageHeight)) {
let divParent = lableListID[i].parentNode; // 获取该div的父节点
let newNode = document.createElement('div');
newNode.className = 'emptyDiv';
newNode.style.background = '#ffffff';
let _H = multiple * pageHeight - (lableListID[i].offsetTop + lableListID[i].offsetHeight);
newNode.style.height = _H + 80 + 'px';
newNode.style.width = '100%';
let next = lableListID[i].nextSibling; // 获取div的下一个兄弟节点
// 判断兄弟节点是否存在
// console.log(123,next);
if (next) {
// 存在则将新节点插入到div的下一个兄弟节点之前,即div之后
divParent.insertBefore(newNode, next);
} else {
// 不存在则直接添加到最后,appendChild默认添加到divParent的最后
divParent.appendChild(newNode);
}
}
}
this.pdfBtn = true
vm.getPdf(tile, download).then((res) => {
// 获取base64Pdf
this.UploadPdf(res);
});
})
},