需求:项目里有个打印的功能,需要把打印的内容转换成图片或者pdf传给后端,后端拿来推送邮件。
技术:vue3 + html2canvas + printJS。
实现方法:通过html2canvas获取到base64,然后把base64转换成二进制流,然后调取上传接口。
问题:内容里的列表很多,有几百条,甚至几千条,生成不出base64,直接报错了,最多只能100条左右才可以。请问各位前端大佬有什么方法可以解决这个问题?
需求:项目里有个打印的功能,需要把打印的内容转换成图片或者pdf传给后端,后端拿来推送邮件。
技术:vue3 + html2canvas + printJS。
实现方法:通过html2canvas获取到base64,然后把base64转换成二进制流,然后调取上传接口。
问题:内容里的列表很多,有几百条,甚至几千条,生成不出base64,直接报错了,最多只能100条左右才可以。请问各位前端大佬有什么方法可以解决这个问题?
最多能生成 100 多条,可能是内存占用过大了,试试看分批生成吧
每轮只生成 100 条:
import html2canvas from 'html2canvas';
import printJS from 'print-js';
// 待打印的内容数组
const content = [
// ...
];
// 定义每组的数量
const batchSize = 100;
// 分批生成并上传内容
async function generateAndUploadContent() {
const totalBatches = Math.ceil(content.length / batchSize);
for (let i = 0; i < totalBatches; i++) {
const startIdx = i * batchSize;
const endIdx = Math.min(startIdx + batchSize, content.length);
const batchContent = content.slice(startIdx, endIdx);
try {
// 生成 base64
const canvas = await html2canvas(batchContent);
const base64Data = canvas.toDataURL();
// 转换成二进制流
const binaryData = atob(base64Data.split(',')[1]);
// ArrayBuffer 填充
const arrayBuffer = new ArrayBuffer(binaryData.length);
const view = new Uint8Array(arrayBuffer);
for (let j = 0; j < binaryData.length; j++) {
view[j] = binaryData.charCodeAt(j);
}
const blob = new Blob([arrayBuffer], { type: 'application/octet-stream' });
// 调用上传接口将 Blob 传给后端
await uploadToServer(blob);
} catch (error) {
console.error('生成并上传内容出错: ', error);
}
}
}
function uploadToServer(blob) {
// 调用上传接口
// ...
}4 回答924 阅读✓ 已解决
1 回答876 阅读
分片截图: 你可以试试把大的 DOM 分成小块,每块单独截图,然后把这些小图像合并成一个大图。合并图像在服务端完成,因为客户端做会有性能问题