记录工作实践
运用到的插件:html2Canvas,JsPDF
源码如下:
import html2Canvas from 'html2canvas';
import JsPDF from 'jspdf';
export default {
install(Vue, options) {
Vue.prototype.getPdf = function (title, domId) {
// 导出之前将dom的overflow:auto设置成visible
var sourceDom = document.querySelector('.sourceDom');
sourceDom.style.overflow = 'visible';
sourceDom.style.height = 'auto';
// pdf文件名
var title = title;
// 不填的时候导出id是pdfDom的
domId = domId ? domId : '#pdfDom'
//需要转pdf的网页对象
var container = document.querySelector(domId);
//创建画布
var c = document.createElement('canvas');
// html2canvas配置项
var opts = {
scale: 2, //设置放大倍数 window.devicePixelRatio(根据设备像素比进行缩放)
canvas: c,
x: window.scrollX,
logging: true,
useCORS: true, //表示允许跨域资源共享,注意不能与 allowTaint 同时配置为 true
allowTaint: false,
width: container.offsetWidth, // 传入节点原始宽
height: container.offsetHeight // 传入节点原始高
};
//画布的宽
c.width = container.offsetWidth * 2;
//画布的高
c.height = container.offsetHeight * 2;
//将页面转换成图片
html2Canvas(container, opts).then(function (canvas) {
var contentWidth = canvas.width;
var contentHeight = canvas.height;
// 一页pdf显示html页面生成的canvas高度
var pageHeight = Math.floor((contentWidth / 595.28) * 841.89);
// 未生成pdf的html页面高度
var leftHeight = contentHeight;
// pdf页面偏移
var position = 0;
// a4纸的尺寸[595.28,,841.89],html页面生成的canvas在pdf中图片的宽高
var imgWidth = 595.28;
var imgHeight = (595.28 / contentWidth) * contentHeight;
//网页的内容
var pageData = canvas.toDataURL('image/jpeg', 1.0);
var pdf = new JsPDF('x', 'pt', 'a4');
var canvas1 = document.createElement('canvas');
var height;
pdf.setDisplayMode('fullwidth', 'continuous', 'FullScreen');
// 创建canvas元素(水印)
const can = document.createElement('canvas')
can.width = 400 // 宽度
can.height = 400 // 高度
const cans = can.getContext('2d') // 获取canvas画布
cans.rotate(-20 * Math.PI / 180) // 逆时针旋转π/9
cans.font = '20px Vedana' // 设置字体
cans.fillStyle = 'rgba(200, 200, 200, 0.3)' // 设置字体的颜色
cans.textAlign = 'center' // 文本对齐方式
cans.textBaseline = 'Middle' // 文本基线
cans.fillText('XXXXXX股份有限公司', can.width/ 5, can.height/ 2) // 绘制文字
// 将Canvas内容导出为DataURL格式的字符串
var dataUrl = can.toDataURL();
// 提取Base64编码部分,可以使用正则表达式或者split函数
var base64Code = dataUrl.replace(/^data:image\/\w+;base64,/, '');
// 加图片水印
function addWaterMark(doc) {
var totalPages = doc.internal.getNumberOfPages();
for (let i = 1; i <= totalPages; i++) {
doc.setPage(i);
doc.addImage(base64Code, 'PNG', imgWidth/ 7, imgHeight/ 8, imgWidth, imgHeight);
}
return doc;
}
//判断分页的地方,在间隙时才分页
function createYmpl(canvas) {
if (leftHeight > 0) {
var checkCount = 0;
if (leftHeight > pageHeight) {
var i = position + pageHeight;
// 默认取pdf标准所在canvas网页高度,倒着循环,推断分页位置
// 推断canvas.width整行是否有内容,如果有内容直接退出,
// checkCount为0,如果整行没有内容则累加checkCount值,直到checkCount值大于等于约定分页
for (i = position + pageHeight; i >= position; i--) {
var isWrite = true;
for (var j = 0; j < canvas.width; j++) {
var cdata = canvas.getContext('2d').getImageData(j, i, 1, 1).data;
if (cdata[0] !== 0xff || cdata[1] !== 0xff || cdata[2] !== 0xff) {
isWrite = false;
break;
}
}
if (isWrite) {
checkCount++;
if (checkCount >= 25) {
break;
}
} else {
checkCount = 0;
}
}
height = Math.round(i - position) || Math.min(leftHeight, pageHeight);
if (height <= 0) {
height = pageHeight;
}
} else {
height = leftHeight;
}
canvas1.width = contentWidth;
canvas1.height = height;
var ctx = canvas1.getContext('2d');
// 【重要】关闭抗锯齿 这部分也是为了强化清晰度
ctx.mozImageSmoothingEnabled = false;
ctx.webkitImageSmoothingEnabled = false;
ctx.msImageSmoothingEnabled = false;
ctx.imageSmoothingEnabled = false;
ctx.drawImage(canvas, 0, position, contentWidth, height, 0, 0, contentWidth, height);
console.log('canvas图片是:',can,canvas);
if (position !== 0) {
pdf.addPage();
}
pdf.addImage(
canvas1.toDataURL('image/jpeg', 1.0),
'JPEG',
0,
0,
imgWidth,
(imgWidth / canvas1.width) * height
);
leftHeight -= height;
position += height;
if (leftHeight > 0) {
createYmpl(canvas);
} else {
// 导出pdf文件命名
pdf = addWaterMark(pdf)
pdf.save(title + '-' + new Date().getTime() + '.pdf');
}
}
}
// 有两个高度需要区分,一个是html页面的实际高度,和生成pdf的页面高度(841.89)
// 当内容未超过pdf一页显示的范围,无需分页
if (leftHeight < pageHeight) {
pdf.addImage(pageData, 'JPEG', 0, 0, imgWidth, imgHeight);
// 导出pdf文件命名
pdf = addWaterMark(pdf)
pdf.save(title + '-' + new Date().getTime() + '.pdf');
} else {
createYmpl(canvas);
}
});
// 导出成功后,将dom原来的属性设置回去
cardDom.style.overflow = 'auto';
cardDom.style.height = '100%';
};
}
};