1.使用npm下载两个插件
a.将html页面转换成图片
npm install --save html2canvas
b.将图片生成pdf
npm install jspdf --save
2.在utils文件夹中创建一个名字叫个htmlToPdf.js的文件,内容如下:
// 导出页面为PDF格式
import html2Canvas from 'html2canvas'
import JsPDF from 'jspdf'
export default {
install(Vue, options) {
Vue.prototype.getPdf = function (title) {
var title = title
var c = document.createElement("canvas")
var opts = {
scale: 1,
canvas: c,
logging: true,
width: document.querySelector('#pdfDom').offsetWidth,
height: document.querySelector('#pdfDom').offsetHeight
};
c.width = document.querySelector('#pdfDom').offsetWidth * 2
c.height = document.querySelector('#pdfDom').offsetHeight * 2
c.getContext("2d").scale(2, 2);
html2Canvas(document.querySelector('#pdfDom'), opts).then(function (canvas) {
// let getPixelRatio = function (context) {
// let backingStore = context.backingStorePixelRatio ||
// context.webkitBackingStorePixelRatio ||
// context.mozBackingStorePixelRatio ||
// context.msBackingStorePixelRatio ||
// context.oBackingStorePixelRatio ||
// context.backingStorePixelRatio || 1;
// return (window.devicePixelRatio || 1) / backingStore;
// };
let pdf = new JsPDF('', 'pt', 'a4')
let ctx = canvas.getContext('2d')
// var ratio = getPixelRatio(ctx);
// console.log(ratio);
// canvas.width = canvas.width * ratio;
// canvas.width = canvas.height * ratio;
// ctx.scale(2, 2);
let a4w = 495 //A4大小,210mm x 297mm,像素是 595*842 的边距,左右各50px 上下各60px,显示区域495*722
let a4h = 722
let imgHeight = Math.floor(a4h * canvas.width / a4w) //按A4显示比例换算一页图像的像素高度
let splitPage = function ($dom) {
const pageOffsetTop = $dom.offsetTop
const pageOffsetWidth = $dom.offsetWidth
const pageOffsetHeight = $dom.offsetHeight
const $unitElements = $dom.querySelectorAll('.el-row')
const peerPageHeight = pageOffsetWidth / a4w * a4h // 获取缩放后的一页页面高度
const pages = [
[
{
top: 0, // 起点初始化
offsetTop: 0
}
]
]
// 遍历最小单元格
// 获取单元格底部距离顶部的高度 top,以及 offsetTop
// 根据 top 值,算出该单元格的页码,放入数组 pages
$unitElements.forEach($element => {
const offsetTop = $element.offsetTop - pageOffsetTop
const top = offsetTop + $element.offsetHeight
const pageIndex = parseInt(top / peerPageHeight)
// 新的一页
if (typeof pages[pageIndex] === 'undefined') {
pages[pageIndex] = []
}
pages[pageIndex].push({
top,
offsetTop
})
})
console.log(pages)
return pages
}
let pages = splitPage(document.querySelector('#pdfDom'))
pages.forEach((page, index) => {
const { offsetTop } = page[0]
const { top } = page[page.length - 1]
let imgHeight1 = (top - offsetTop) * 2
let pageA = document.createElement("canvas");
pageA.width = canvas.width;
// pdf.addImage(pageData, 'JPEG', 50, 60, a4w, top)
pageA.height = Math.min(imgHeight1, canvas.height - offsetTop * 2);//可能内容不足一页
if (index > 0) {
pdf.addPage()
}
//用getImageData剪裁指定区域,并画到前面创建的canvas对象中
pageA.getContext('2d').putImageData(ctx.getImageData(0, offsetTop * 2, canvas.width, Math.min(imgHeight1, canvas.height - offsetTop * 2)), 0, 0);
pdf.addImage(pageA.toDataURL('image/jpeg', 1.0), 'JPEG', 50, 60, a4w, Math.min(a4h, a4w * pageA.height / pageA.width)); //添加图像到页面,保留左右各50px 上下各60px边距
})
pdf.save(title + '.pdf')
})
}
}
}
3. 在main.js中注册我们自定义的插件htmlToPdf.js
import htmlToPdf from '@/components/utils/htmlToPdf'
Vue.use(htmlToPdf)
4.在按钮上直接绑定getPdf方法,即可实现导出功能
//这里面的内容是我们要导出的部分 id为"pdfDom",和上面"htmlToPdf.js"文件中的id必须一致.此部分将就是pdf显示的部分
//getPdf()是我们在main.js中绑定在Vue中的,固定名称,直接调用即可下载,无需在methods中写方法
export default { //
data () {
return {
htmlTitle: '页面导出PDF文件名' //这个也是固定写法,pdf文件下载的名称
}
}
}
参考:候鸟与暖风的将Vue页面导出为pdf格式并进行下载