`---
主题使用方法:github.com/xitu/juejin…
theme: juejin highlight: juejin ---`
只有一页的
export const html2pdf = function (
title = '文档',
selector = '#pdfDom',
isUpload,
) {
return new Promise((resolve, reject) => {
html2Canvas(document.querySelector(selector), {
}).then(function (canvas) {
const loading = Loading.service({
lock: true,
text: '加载中……',
background: 'rgba(0, 0, 0, 0.7)',
});
const contentWidth = canvas.width;
const contentHeight = canvas.height;
const pageHeight = (contentWidth / 592.28) * 841.89;
let leftHeight = contentHeight;
let position = 0;
const imgWidth = 595.28;
const imgHeight = (592.28 / contentWidth) * contentHeight;
const pageData = canvas.toDataURL('image/jpeg', 1.0);
const 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();
}
}
}
if (isUpload) {
const pdfData = PDF.output('datauristring'); //获取base64Pdf
const file = dataURLtoFile(pdfData, title);
resolve(file);
loading.close();
} else {
PDF.save(`${title}.pdf`);
loading.close();
}
});
});
};`
多页 分页内容会被截断处理
export function downlaodReport(
title = '文档',
selector = '#pdfDom',
isUpload,
isDownload,
) {
return new Promise((resolve, reject) => {
html2Canvas(document.querySelector(selector), {
useCORS: true,
dpi: 120, // 图片清晰度问题
background: '#FFFFFF', //如果指定的div没有设置背景色会默认成黑色,这里是个坑
}).then(canvas => {
const loading = Loading.service({
lock: true,
text: '加载中……',
background: 'rgba(0, 0, 0, 0.7)',
});
//未生成pdf的html页面高度
let leftHeight = canvas.height;
const a4Width = 595.28;
const a4Height = 841.89; //A4大小,210mm x 297mm,四边各保留10mm的边距,显示区域190x277
//一页pdf显示html页面生成的canvas高度;
const a4HeightRef = Math.floor((canvas.width / a4Width) * a4Height);
//pdf页面偏移
let position = 0;
const pageData = canvas.toDataURL('image/jpeg', 1.0);
const pdf = new JsPDF('p', 'pt', 'a4'); //A4纸,纵向
let index = 1,
canvas1 = document.createElement('canvas'),
height;
pdf.setDisplayMode('fullwidth', 'continuous', 'FullScreen');
const pdfName = title;
function createImpl(canvas) {
if (leftHeight > 0) {
index++;
let checkCount = 0;
if (leftHeight > a4HeightRef) {
let i = position + a4HeightRef;
for (i = position + a4HeightRef; i >= position; i--) {
let isWrite = true;
for (let j = 0; j < canvas.width; j++) {
const 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;
const ctx = canvas1.getContext('2d');
ctx.drawImage(
canvas,
0,
position,
canvas.width,
height,
0,
0,
canvas.width,
height,
);
const pageHeight = Math.round((a4Width / canvas.width) * height);
if (position !== 0) {
pdf.addPage();
}
pdf.addImage(
canvas1.toDataURL('image/jpeg', 1.0),
'JPEG',
10,
10,
a4Width,
(a4Width / canvas1.width) * height,
);
leftHeight -= height;
position += height;
if (leftHeight > 0) {
setTimeout(createImpl, 500, canvas);
} else if (isUpload) {
const pdfData = pdf.output('datauristring'); //获取base64Pdf
const file = dataURLtoFile(pdfData, pdfName);
resolve(file);
loading.close();
if (isDownload) {
pdf.save(`${pdfName}.pdf`);
loading.close();
}
} else {
pdf.save(`${pdfName}.pdf`);
loading.close();
}
}
}
//当内容未超过pdf一页显示的范围,无需分页
if (leftHeight < a4HeightRef) {
pdf.addImage(
pageData,
'JPEG',
0,
0,
a4Width,
(a4Width / canvas.width) * leftHeight,
);
if (isUpload) {
const pdfData = pdf.output('datauristring'); //获取base64Pdf
const file = dataURLtoFile(pdfData, pdfName);
resolve(file);
if (isDownload) {
pdf.save(`${pdfName}.pdf`);
loading.close();
}
} else {
pdf.save(`${pdfName}.pdf`);
loading.close();
}
} else {
try {
pdf.deletePage(0);
setTimeout(createImpl, 500, canvas);
} catch (err) {}
}
});
});
}
内容放置一页 避免截断
// 将所有内容放置一页,避免内容截断问题
export function downloadOnePage(
title = '文档',
selector = '#pdfDom',
isUpload,
isDownload,
) {
return new Promise((resolve, reject) => {
const loading = Loading.service({
lock: true,
text: '加载中……',
background: 'rgba(0, 0, 0, 0.7)',
});
html2Canvas(document.querySelector(selector), {
// allowTaint: true,
useCORS: true,
dpi: 120, // 图片清晰度问题
background: '#FFFFFF',
// scale: 2, // 提升画面质量,但是会增加文件大小
}).then(canvas => {
// 得到canvas画布的单位是px 像素单位
const contentWidth = canvas.width;
const contentHeight = canvas.height;
// 将canvas转为base64图片
const pageData = canvas.toDataURL('image/jpeg', 1.0);
// 设置pdf的尺寸,pdf要使用pt单位 已知 1pt/1px = 0.75 pt = (px/scale)* 0.75
// 2为上面的scale 缩放了2倍
const pdfX = ((contentWidth + 10) / 2) * 0.75;
const pdfY = ((contentHeight + 500) / 2) * 0.75; // 500为底部留白
// 设置内容图片的尺寸,img是pt单位
const imgX = pdfX;
const imgY = (contentHeight / 2) * 0.75; //内容图片这里不需要留白的距离
// 初始化jspdf 第一个参数方向:默认''时为纵向,第二个参数设置pdf内容图片使用的长度单位为pt,第三个参数为PDF的大小,单位是pt
const PDF = new JsPDF('', 'pt', [pdfX, pdfY]);
// 将内容图片添加到pdf中,因为内容宽高和pdf宽高一样,就只需要一页,位置就是 0,0
PDF.addImage(pageData, 'jpeg', 0, 0, imgX, imgY);
// PDF.save(`${title}.pdf`);
if (isUpload) {
const pdfData = PDF.output('datauristring'); //获取base64Pdf
const file = dataURLtoFile(pdfData, title);
resolve(file);
loading.close();
if (isDownload) {
PDF.save(`${title}.pdf`);
loading.close();
}
} else {
PDF.save(`${title}.pdf`);
loading.close();
}
});
});
}
有跨域图片时候需要将允许污染去掉 可在图片url添加时间戳 将图片属性crossOrigin 设置为 "Anonymous";