html2canvas内容太多生成不了base64或用file-saver也不行?

需求:项目里有个打印的功能,需要把打印的内容转换成图片或者pdf传给后端,后端拿来推送邮件。
技术:vue3 + html2canvas + printJS。
实现方法:通过html2canvas获取到base64,然后把base64转换成二进制流,然后调取上传接口。
问题:内容里的列表很多,有几百条,甚至几千条,生成不出base64,直接报错了,最多只能100条左右才可以。请问各位前端大佬有什么方法可以解决这个问题?

阅读 4.6k
4 个回答

分片截图: 你可以试试把大的 DOM 分成小块,每块单独截图,然后把这些小图像合并成一个大图。合并图像在服务端完成,因为客户端做会有性能问题

试试开源的 jsPDF,直接将生成pdf给后端。

最多能生成 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) {
  // 调用上传接口
  // ...
}

比较简单,后端接入这个服务:https://www.uscreenshot.com/,由后端去生成一个 PDF,然后前端就不用管了,后端拿到 PDF 后调用发邮件的方法就行

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进