第一步安装
//页面转换成图片
npm install --save html2canvas
//图片转换成pdf
npm install jspdf --save
第二步在src目录下创建文件夹utils,里面创建exportPdf.js文件,把以下代码放进去
// 导出页面为PDF格式
import html2Canvas from 'html2canvas'
import JsPDF from 'jspdf'
export function getPdf(title,id){
html2Canvas(document.querySelector(`#${id}`), {
allowTaint: true
}).then(function (canvas) {
let contentWidth = canvas.width
let contentHeight = canvas.height
let pageHeight = contentWidth / 592.28 * 841.89
let leftHeight = contentHeight
let position = 0
let imgWidth = 595.28
let imgHeight = 592.28 / contentWidth * contentHeight
let pageData = canvas.toDataURL('image/jpeg', 1.0)
let PDF = new JsPDF('', 'pt', 'a4')
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()
}
}
}
PDF.save(title + '.pdf')
})
}
第三步导出pdf完整代码
衣帽震小人,言语压君子,先敬罗衣后敬人。
上面的方法不够完美只适用于导出一页pdf,无法解决分页内容被隔断问题,接下来提供更加完美的解决方法。
第一步
把导出的pdf页面复制一份封装成组件,在原页面中引入组件,加上定位然后top:-99999px,让组件保证在引入情况下不在可视范围之内。这样的话你想要什么样式只需要改组件中的样式即可,无需动原页面中的样式。
第二步
在子组件中引入
import html2canvas from "html2canvas"
import jsPDF from "jspdf"
在子组件中写入方法
son() {
let that = this;
document.body.scrollTop = document.documentElement.scrollTop = 0;
let el = document.querySelector("#pdfHtmls");
html2canvas(el, {
allowTaint: true,
useCORS: true,
dpi: 120, // 图片清晰度问题
background: "#FFFFFF", //如果指定的div没有设置背景色会默认成黑色,这里是个坑
y: 0
}).then((canvas) => {
var currentPage = 1;
//未生成pdf的html页面高度
var leftHeight = canvas.height;
var a4Width = 576;
var a4Height = 772.89; //A4大小,210mm x 297mm,四边各保留10mm的边距,显示区域190x277
//一页pdf显示html页面生成的canvas高度;
var a4HeightRef = Math.floor((canvas.width / a4Width) * a4Height);
//pdf页面偏移
var position = 0;
var pageData = canvas.toDataURL("image/jpeg", 1.0);
var pdf = new jsPDF("p", "pt", "a4"); //A4纸,纵向
var index = 1,
canvas1 = document.createElement("canvas"),
height;
pdf.setDisplayMode("fullwidth", "continuous", "FullScreen");
function createImpl(canvas) {
console.log(leftHeight, a4HeightRef);
if (leftHeight > 0) {
index++;
var checkCount = 0;
if (leftHeight > a4HeightRef) {
var i = position + a4HeightRef;
for (i = position + a4HeightRef; i >= position; i--) {
var isWrite = true;
for (var j = 0; j < canvas.width; j++) {
var c = canvas
.getContext("2d")
.getImageData(j, i, 1, 1).data;
if (c[0] != 0xff || c[1] != 0xff || c[2] != 0xff) {
isWrite = false;
break;
}
}
if (isWrite) {
checkCount++;
if (checkCount >= 10) {
break;
}
} else {
checkCount = 0;
}
}
height =
Math.round(i - position) || Math.min(leftHeight, a4HeightRef);
if (height <= 0) {
height = a4HeightRef;
}
} else {
height = leftHeight;
}
canvas1.width = canvas.width;
canvas1.height = height;
var ctx = canvas1.getContext("2d");
ctx.drawImage(
canvas,
0,
position,
canvas.width,
height,
0,
0,
canvas.width,
height
);
var pageHeight = Math.round((a4Width / canvas.width) * height);
if (position != 0) {
pdf.addPage();
}
pdf.addImage(
canvas1.toDataURL("image/jpeg", 1.0),
"JPEG",
10,
40,
a4Width,
(a4Width / canvas1.width) * height
);
leftHeight -= height;
position += height;
if (leftHeight > 0) {
setTimeout(createImpl, 500, canvas);
} else {
pdf.save(that.title + ".pdf");
}
}
}
let targetPage = pdf.internal.getNumberOfPages();
//当内容未超过pdf一页显示的范围,无需分页
if (leftHeight < a4HeightRef) {
pdf.addImage(
pageData,
"JPEG",
10,
40,
a4Width,
(a4Width / canvas.width) * leftHeight
);
pdf.save(that.title + ".pdf");
} else {
try {
pdf.deletePage(0);
setTimeout(createImpl, 500, canvas);
} catch (err) {
}
}
})
}
第三步
在父页面中调用子组件的方法即可
exportPDF() {
this.$refs.child.son()
}