一、需求:
页面上某一部分内容需要生成pdf并下载
二、技术方案:
使用html2canvas和jsPDF插件
三、js代码
// 页面导出为pdf格式
import html2Canvas from "html2canvas";
import jsPDF from "jspdf";
import { uploadImg } from '@/api/public';
const htmlToPdf = {
getPdf(title, id) {
html2Canvas(document.querySelector(id), {
allowTaint: false,
taintTest: false,
logging: false,
useCORS: true,
dpi: window.devicePixelRatio * 4, //将分辨率提高到特定的DPI 提高四倍
scale: 4, //按比例增加分辨率
}).then((canvas) => {
var pdf = new jsPDF("p", "mm", "a4"); //A4纸,纵向
var ctx = canvas.getContext("2d"),
a4w = 190,
a4h = 272, //A4大小,210mm x 297mm,四边各保留10mm的边距,显示区域190x277
imgHeight = Math.floor((a4h * canvas.width) / a4w), //按A4显示比例换算一页图像的像素高度
renderedHeight = 0;
while (renderedHeight < canvas.height) {
var page = document.createElement("canvas");
page.width = canvas.width;
page.height = Math.min(imgHeight, canvas.height - renderedHeight); //可能内容不足一页
//用getImageData剪裁指定区域,并画到前面创建的canvas对象中
page
.getContext("2d")
.putImageData(
ctx.getImageData(
0,
renderedHeight,
canvas.width,
Math.min(imgHeight, canvas.height - renderedHeight)
),
0,
0
);
pdf.addImage(
page.toDataURL("image/jpeg", 1.0),
"JPEG",
10,
10,
a4w,
Math.min(a4h, (a4w * page.height) / page.width)
); //添加图像到页面,保留10mm边距
renderedHeight += imgHeight;
if (renderedHeight < canvas.height) {
pdf.addPage(); //如果后面还有内容,添加一个空页
}
// delete page;
}
console.log(pdf)
// pdf.save(title + ".pdf"); // PDF.save() 此方法可以将pdf直接保存本地
let pdfData = pdf.output('datauristring') // 获取base64Pdf
let files = dataURLtoFile(pdfData, '封面.pdf') // 将base64文件转化为流,上传oss
uploadFiles(files)
});
},
};
function dataURLtoFile(dataurl, filename) {
let arr = dataurl.split(',')
let mime = arr[0].match(/:(.*?);/)[1]
let bstr = atob(arr[1])
let n = bstr.length
let u8arr = new Uint8Array(n)
while (n--) {
u8arr[n] = bstr.charCodeAt(n)
}
return new File([u8arr], filename, { type: mime })
}
function uploadFiles(files) {
let data = new FormData()
data.append('file', files)
uploadImg(data).then(res => {
console.log(res)
if (res.data.code == 0) {
// formData.value.qrcode = res.data.data.res.url
}
})
}
export default htmlToPdf;
四、使用步骤:
1. 使用之前需要先按照2个npm包
npm install html2canvas -S --registry=https://registry.npmmirror.com/
npm install jspdf -S --registry=https://registry.npmmirror.com/
2. 在页面引用
import htmlToPdf from "@/utils/htmlToPDF";
3. 调用方法
const printReport = () => {
htmlToPdf.getPdf('测试pdf',"#db-test-report");
}
4. 记得给指定容器加id
五:注意事项:
1. 如果要打印的内容是iframe里面的,因为无法直接拿到dom元素,需要跟iframe通讯,拿到dom元素,放到当前页面;如果样式没带过来,特殊处理一下
const iframe = document.getElementById("myIframe");
// 向iframe发送消息
iframe.contentWindow.postMessage("getElement", tooltipUrl.value);
// 收到iframe的回复才能生成pdf
window.addEventListener("message", function (e) {
console.log("iframe回复的消息");
console.log(e);
if (e.origin === iframeOrigin.value && e.data.type === "element") {
// 处理获取到的元素
var container = document.getElementById("pdf-iframe");
container.innerHTML = e.data.html;
hasIframePdf = true
getPdf("xxx下载", "#pdf-xxx-xxx");
}
});