This commit is contained in:
2026-03-11 15:00:25 +08:00
parent 8441e66e93
commit 03cb6fd92b

View File

@@ -2213,102 +2213,122 @@
requestAnimationFrame(function () {
requestAnimationFrame(function () {
try {
html2canvas(pageEl, {
scale: 1.5,
useCORS: true,
allowTaint: false,
backgroundColor: "#ffffff",
scrollX: 0,
scrollY: 0,
windowWidth: pageEl.scrollWidth,
windowHeight: pageEl.scrollHeight,
onclone: function (clonedDoc, node) {
var body = clonedDoc.body;
if (body) {
body.style.backgroundColor = "#ffffff";
body.style.overflow = "visible";
}
var clonePage = clonedDoc.querySelector(".page");
if (clonePage) {
clonePage.style.overflow = "visible";
clonePage.style.backgroundColor = "#ffffff";
}
},
})
.then(function (canvas) {
if (!canvas.width || !canvas.height) {
console.error("截图为空,宽或高为 0");
(function () {
var scale = 1.25;
var pdf = new jspdf.jsPDF("p", "mm", "a4");
var pageWidthMm = pdf.internal.pageSize.getWidth();
var pageHeightMm = pdf.internal.pageSize.getHeight();
// 以元素宽度为基准,计算每一页对应的像素高度(避免生成超长大图导致 jsPDF 白页)
var targetWidthPx = Math.max(
1,
Math.floor(pageEl.scrollWidth),
);
var pageHeightPx = Math.max(
1,
Math.floor((targetWidthPx * pageHeightMm) / pageWidthMm),
);
var totalHeightPx = Math.max(
1,
Math.floor(pageEl.scrollHeight),
);
var offsetY = 0;
var pageIndex = 0;
function renderSlice() {
var sliceHeight = Math.min(
pageHeightPx,
totalHeightPx - offsetY,
);
if (sliceHeight <= 0) {
// 结束,保存
var fileName = "企业全景报告.pdf";
if (
reportData &&
reportData.entName &&
typeof reportData.entName === "string"
) {
fileName =
reportData.entName +
"_企业全景报告.pdf";
}
pdf.save(fileName);
restoreBtn();
return;
}
// 调试:确认截图是否全白/是否有内容
try {
var ctx2d = canvas.getContext("2d");
if (ctx2d) {
var p = ctx2d.getImageData(0, 0, 1, 1).data;
console.info(
"PDF截图信息",
{
w: canvas.width,
h: canvas.height,
firstPixel: Array.prototype.slice.call(p),
},
html2canvas(pageEl, {
scale: scale,
useCORS: true,
allowTaint: false,
backgroundColor: "#ffffff",
x: 0,
y: offsetY,
width: targetWidthPx,
height: sliceHeight,
scrollX: 0,
scrollY: 0,
windowWidth: targetWidthPx,
windowHeight: sliceHeight,
onclone: function (clonedDoc) {
var body = clonedDoc.body;
if (body) {
body.style.backgroundColor = "#ffffff";
body.style.overflow = "visible";
}
var clonePage = clonedDoc.querySelector(".page");
if (clonePage) {
clonePage.style.overflow = "visible";
clonePage.style.backgroundColor = "#ffffff";
}
},
})
.then(function (canvas) {
if (!canvas.width || !canvas.height) {
console.error("分片截图为空,宽或高为 0", {
offsetY: offsetY,
sliceHeight: sliceHeight,
});
restoreBtn();
return;
}
// 调试:输出每页分片信息
console.info("PDF分片截图信息", {
page: pageIndex + 1,
w: canvas.width,
h: canvas.height,
offsetY: offsetY,
sliceHeight: sliceHeight,
totalHeightPx: totalHeightPx,
});
var imgData = canvas.toDataURL("image/jpeg", 0.9);
if (pageIndex > 0) pdf.addPage();
pdf.addImage(
imgData,
"JPEG",
0,
0,
pageWidthMm,
pageHeightMm,
);
}
} catch (e) {
console.warn("读取截图像素失败(可能被跨域资源污染)", e);
}
var imgData = canvas.toDataURL(
"image/jpeg",
0.95,
);
var pdf = new jspdf.jsPDF("p", "mm", "a4");
var pageWidth = pdf.internal.pageSize.getWidth();
var pageHeight = pdf.internal.pageSize.getHeight();
var imgWidth = pageWidth;
var imgHeight =
(canvas.height * imgWidth) / canvas.width;
var position = 0;
var heightLeft = imgHeight;
pdf.addImage(
imgData,
"JPEG",
0,
position,
imgWidth,
imgHeight,
);
heightLeft -= pageHeight;
while (heightLeft > 0) {
position = heightLeft - imgHeight;
pdf.addPage();
pdf.addImage(
imgData,
"JPEG",
0,
position,
imgWidth,
imgHeight,
);
heightLeft -= pageHeight;
}
var fileName = "企业全景报告.pdf";
if (
reportData &&
reportData.entName &&
typeof reportData.entName === "string"
) {
fileName =
reportData.entName +
"_企业全景报告.pdf";
}
pdf.save(fileName);
restoreBtn();
})
.catch(function (e) {
console.error("生成 PDF 失败", e);
restoreBtn();
});
pageIndex += 1;
offsetY += sliceHeight;
// 给 UI 一点喘息,避免长任务卡死
setTimeout(renderSlice, 0);
})
.catch(function (e) {
console.error("生成 PDF 失败(分片截图阶段)", e);
restoreBtn();
});
}
renderSlice();
})();
} catch (e) {
console.error("触发生成 PDF 失败", e);
restoreBtn();