reactjs 在React中将base64字符串转换为PDF?

ki0zmccv  于 2023-06-22  发布在  React
关注(0)|答案(2)|浏览(299)

我有Base64字符串,想转换成pdf。我的函数工作的小base64字符串像文本图像,表情符号和所有,但当我添加超过50kb的图片(不确定)base64字符串,然后我的函数不能将base64字符串转换为pdf。
我尝试过许多以前的Stack Overflow解决方案,但似乎没有任何工作。

const ConverToPdf = (b64) =>{
    const base64String = b64
    const byteCharacters = window.atob(base64String);
    const byteArrays = [];

    for (let offset = 0; offset < byteCharacters.length; offset += 512) {
      const slice = byteCharacters.slice(offset, offset + 512);

      const byteNumbers = new Array(slice.length);
      for (let i = 0; i < slice.length; i++) {
        byteNumbers[i] = slice.charCodeAt(i);
      }

      const byteArray = new Uint8Array(byteNumbers);
      byteArrays.push(byteArray);
    }

    const pdfFile = new Blob(byteArrays, { type: 'application/pdf' });
    const pdfUrl = URL.createObjectURL(pdfFile);

    // Create a download link
    const downloadLink = document.createElement('a');
    downloadLink.href = pdfUrl;
    downloadLink.download = 'converted.pdf';

    // Simulate click to trigger the download
    downloadLink.click();

    // Cleanup
    URL.revokeObjectURL(pdfUrl);
    document.body.removeChild(downloadLink);
}
wb1gzix0

wb1gzix01#

您在JavaScript中遇到了window.atob()的已知问题。对于大于65536字节的base64字符串,此函数将失败。这是因为它试图为解码的字符串分配单个连续的内存块,并且分配的大小可能不总是可能的,特别是对于较大的base64字符串。
一个很好的替代方法是使用TextEncoderTextDecoder API来执行转换,这些API对于较大的字符串更可靠。
以下是如何修改函数:

const ConverToPdf = (b64) =>{
    const binaryString = Uint8Array.from(atob(b64), c => c.charCodeAt(0));
    
    const byteArrays = [];

    for (let offset = 0; offset < binaryString.length; offset += 512) {
      const slice = binaryString.slice(offset, offset + 512);
      byteArrays.push(slice);
    }

    const pdfFile = new Blob(byteArrays, { type: 'application/pdf' });
    const pdfUrl = URL.createObjectURL(pdfFile);

    // Create a download link
    const downloadLink = document.createElement('a');
    downloadLink.href = pdfUrl;
    downloadLink.download = 'converted.pdf';

    // Simulate click to trigger the download
    document.body.appendChild(downloadLink);  // Append the link to the body before click
    downloadLink.click();

    // Cleanup
    URL.revokeObjectURL(pdfUrl);
    document.body.removeChild(downloadLink);
}

这个函数应该可以解决window.atob()在较大的base64字符串上失败的问题。TextEncoderTextDecoder API为大型字符串提供了更好的性能和可靠性,在这些情况下应该是首选。
此功能还具有下载链接的创建和触发的修正。在模拟单击之前,您应该将链接附加到文档正文。一旦模拟点击并触发下载,您就可以从正文中删除链接。

g6ll5ycj

g6ll5ycj2#

使用pdf-lib库,我可以转换任何大小的base64到pdf,但想解决这个没有任何库

import { PDFDocument } from "pdf-lib";
export const makeDownloadToPDF = async (b64, height, width) => {
  
    try {
      const binaryString = window.atob(b64);
  
      const pdfDoc = await PDFDocument.create();
      const imageBytes = Uint8Array.from([...binaryString].map((char) => char.charCodeAt(0)));
  
      const image = await pdfDoc.embedPng(imageBytes);
      const page = pdfDoc.addPage([image.width, image.height]);
      page.drawImage(image, {
        x: 0,
        y: 0,
        width: image.width,
        height: image.height,
      });
  
      const pdfBytes = await pdfDoc.save();
  
      const pdfBlob = new Blob([pdfBytes], { type: 'application/pdf' });
  
      // Create a download link
      const downloadLink = document.createElement('a');
      downloadLink.href = URL.createObjectURL(pdfBlob);
      downloadLink.download = 'converted.pdf';
  
      // Simulate click to trigger the download
      document.body.appendChild(downloadLink);
      downloadLink.click();
  
      // Cleanup
      URL.revokeObjectURL(downloadLink.href);
      document.body.removeChild(downloadLink);
    } catch (error) {
      console.error('Error converting image to PDF:', error);
    }
}

相关问题