使用 PDF-LIB 在 React 中渲染 PDF

cpp*_*ick 9 javascript pdf reactjs

我正在尝试使用PDF-LIB来在我的 React 应用程序中实现 PDF 功能。目的是呈现表单的 PDF 版本,并允许用户编辑字段,然后保存进度。

出于这个原因,我决定使用 PDF-LIB 而不是像 React-pdf 这样的替代品,因为这似乎是最强大的。

我对处理 PDF 的过程的理解如下: Fetch PDF & convert to byte array--> Load PDF data and make changes-->Save updated PDF as byte array

我正在尝试调整此处找到的示例

这是我的代码:

const LoadPDF = () => {
  const [pdfInfo, setPdfInfo] = useState([]);

  useEffect(() => {
    modifyPdf();
  }, []);

  const modifyPdf = async () => {
    const existingPdfBytes = await fetch(
      "https://pdf-lib.js.org/assets/with_update_sections.pdf"
    ).then((res) => res.arrayBuffer());

    const pdfDoc = await PDFDocument.load(existingPdfBytes);
    const helveticaFont = await pdfDoc.embedFont(StandardFonts.Helvetica);

    const pages = pdfDoc.getPages();
    const firstPage = pages[0];
    
    // Get the width and height of the first page
    const { width, height } = firstPage.getSize();
    firstPage.drawText("This text was added with JavaScript!", {
      x: 5,
      y: height / 2 + 300,
      size: 50,
      font: helveticaFont,
      color: rgb(0.95, 0.1, 0.1),
      rotate: degrees(-45),
    });

    const pdfBytes = await pdfDoc.save();
    const docUrl = URL.createObjectURL(
      new Blob(pdfBytes, { type: "application/pdf" })
    );
    setPdfInfo(docUrl);
  };
  
  return (
    <>{<iframe title="test-frame" src={pdfInfo} type="application/pdf" />}</>
  );
};

export default LoadPDF;
Run Code Online (Sandbox Code Playgroud)

文档表明我应该能够在 iframe 中渲染 PDF。我尝试创建一个 iframe 元素并将其从函数中返回modifypdf。我也尝试将修改后的PDF数据设置为pdfInfoin状态。我尝试的第三件事是创建图像然后渲染它。

此时我迷路了。考虑到我希望用户能够编辑文档并能够保存,在 iFrame 中渲染 PDF 对我来说是最佳选择吗?我在以所需格式获取数据和将其渲染到屏幕之间存在脱节。我知道我需要重构它,但我试图了解这个库的工作原理,然后致力于解决问题的其他部分。

2020 年 9 月 29 日更新:

我意识到我拥有带有 PDF 修订版的字节数组,因此const pdfBytes = await pdfDoc.save();我习惯URL.createObjectURL将数据转换为 URL,以便在渲染 iframe 时在源中使用。该部分不再损坏,但 PDF 仍然无法在 iframe 中呈现。

我已经包含了上面编辑过的代码。

小智 7

添加这些行似乎可以修复我的代码:

    
const bytes  = new Uint8Array( pdfBytes ); 
const blob   = new Blob( [ bytes ], { type: "application/pdf" } );
const docUrl = URL.createObjectURL( blob );
setPdfInfo( docUrl );

Run Code Online (Sandbox Code Playgroud)

或者直接使用:

return <iframe src={docUrl} type="application/pdf" />
Run Code Online (Sandbox Code Playgroud)


小智 1

我所做的和工作的:我添加了对 iframe 实例的引用:

import React, { useState, useEffect, useRef } from 'react';

const LoadPDF = () => {
...
const viewer = useRef(null);

const modifyPDF = async () => {
...
};

return (
        <>{<iframe title="test-frame" src={pdfInfo} ref={viewer} type="application/pdf" />}</>
      );
}
Run Code Online (Sandbox Code Playgroud)