jsPDF - 包含其他pdf

8

我正在尝试使用jsPDF解决以下问题:

我有一个存储在服务器上的PDF文件。我正在使用jsPDF生成另一个PDF,并尝试将其附加到已存在的PDF文件(如上所述)作为另一页。

我搜索了一下,但找不到任何帮助。我还在stackoverflow上找到了这个问题,但情况不同 - 将现有的Pdf附加到Jspdf

我该如何使其正常工作?还是有其他插件或其他方法可以实现此功能?

3个回答

10
很遗憾,目前(2018年)jsPDF不支持此功能。 替代方案 但是你可以使用免费的PHP库,如FPDI在服务器端进行编辑。使用FPDI甚至可以编辑PDF文档、提取某些页面并将它们添加到新的PDF文档中。如何操作请参考这里
您可以通过AJAX向服务器发送请求,服务器执行操作并返回一个新的PDF文件。

更新

现在是2020年7月,jsPDF不支持该功能。但是一些用户创建了pull request来添加(复制)来自同一PDF文档的页面。在此链接中,您可以找到如何使用他的函数的示例代码。但是它不能添加来自其他PDF的页面。您可以在这里找到他的函数代码。

使用JavaScript PDF-lib的替代解决方案

您可以使用JavaScript "PDF-lib"实现此功能。源代码和其他信息可以在GitHub页面上找到。您可以在其项目页面上找到此库的许多演示

"PDF-lib" 可以在任何 JavaScript 环境中创建和修改 PDF 文档。它被设计用于在任何现代 JavaScript 运行时环境下工作,已在 Node.JS、浏览器、Deno 和 React Native 环境中进行了测试。
API 文档可在项目网站上找到: https://pdf-lib.js.org/docs/api/ 示例 "Create PDF with Embed PDF Pages":

const { PDFDocument } = PDFLib;

async function embedPdfPages()
{
    // Fetch American flag PDF
    const flagUrl = 'https://pdf-lib.js.org/assets/american_flag.pdf',
        // Fetch U.S. constitution PDF
        constitutionUrl = 'https://pdf-lib.js.org/assets/us_constitution.pdf',
        flagPdfBytes = await fetch(flagUrl).then((res) => res.arrayBuffer()),
        constitutionPdfBytes = await fetch(constitutionUrl).then((res) => res.arrayBuffer()),
        // Create a new PDFDocument
        pdfDoc = await PDFDocument.create();
    
    // Add a blank page to the document
    var page = pdfDoc.addPage();
    
    // Embed the first page of the American flag PDF
    const [americanFlag] = await pdfDoc.embedPdf(flagPdfBytes),
        // Load the constitution PDF into a PDFDocument
        usConstitutionPdf = await PDFDocument.load(constitutionPdfBytes),
        // Embed the first page of the constitution
        firstPageOfConstitution = await pdfDoc.embedPage(usConstitutionPdf.getPages()[0]);

    // Draw the American flag page
    page.drawPage(americanFlag);
    
    //add a blank new page to the document
    page = pdfDoc.addPage();
    // Draw the first page of the constitution
     page.drawPage(firstPageOfConstitution);
    
    // Serialize the PDFDocument to bytes (a Uint8Array)
    const pdfBytes = await pdfDoc.save();
    // Trigger the browser to download the PDF document
    download(pdfBytes, "pdf-lib_pdf_page_embedding_example.pdf", "application/pdf");
}
body {
  width: 100vw;
  height: 100vh;
  display: flex;
  justify-content: center;
  align-items: center;
  flex-direction: column;
}

p {
  font-family: helvetica;
  font-size: 24px;
  text-align: center;
  margin: 25px;
}

.small {
  font-family: helvetica;
  font-size: 18px;
  text-align: center;
  margin: 25px;
}

button {
  background-color: #008CBA;
  border: none;
  color: white;
  padding: 15px 32px;
  text-align: center;
  font-size: 16px;
}
<script src="https://unpkg.com/pdf-lib@1.4.0"></script>
<script src="https://unpkg.com/downloadjs@1.4.7"></script>
<p>Click the button to embed PDF pages with <code>pdf-lib</code></p>
<button onclick="embedPdfPages()">Create PDF</button>
<p class="small">(Your browser will download the resulting file)</p>


示例:“使用JPEG和其他PDF作为附件创建PDF”

const { PDFDocument, rgb } = PDFLib

async function addAttachments()
{
    // Define attachment URLs
    const jpgUrl = 'https://pdf-lib.js.org/assets/cat_riding_unicorn.jpg',
        pdfUrl = 'https://pdf-lib.js.org/assets/us_constitution.pdf',
        // Fetch attachments
        jpgAttachmentBytes = await fetch(jpgUrl).then(res => res.arrayBuffer()),
        pdfAttachmentBytes = await fetch(pdfUrl).then(res => res.arrayBuffer()),

        pdfDoc = await PDFDocument.create();

    // Add the JPG attachment
    await pdfDoc.attach(jpgAttachmentBytes, 'cat_riding_unicorn.jpg',
    {
        mimeType: 'image/jpeg',
        description: 'Cool cat riding a unicorn!',
        creationDate: new Date('2019/12/01'),
        modificationDate: new Date('2020/04/19')
    });
    // Add the PDF attachment
    await pdfDoc.attach(pdfAttachmentBytes, 'us_constitution.pdf',
    {
        mimeType: 'application/pdf',
        description: 'Constitution of the United States',
        creationDate: new Date('1787/09/17'),
        modificationDate: new Date('1992/05/07')
    });

    // Add a page with some text
    const page = pdfDoc.addPage();
    page.drawText('This PDF has two attachments. Note that only some appropriated PDF readers can view attachments. For example the Adobe Reader.', {x: 135, y: 415});

    // Serialize the PDFDocument to bytes (a Uint8Array)
    const pdfBytes = await pdfDoc.save();

    // Trigger the browser to download the PDF document
    download(pdfBytes, "pdf-lib_add_attachments.pdf", "application/pdf");
}
body {
  width: 100vw;
  height: 100vh;
  display: flex;
  justify-content: center;
  align-items: center;
  flex-direction: column;
}

p {
  font-family: helvetica;
  font-size: 24px;
  text-align: center;
  margin: 25px;
}

.small {
  font-family: helvetica;
  font-size: 18px;
  text-align: center;
  margin: 25px;
}

button {
  background-color: #008CBA;
  border: none;
  color: white;
  padding: 15px 32px;
  text-align: center;
  font-size: 16px;
}
blockquote
{
    background-color: rgba(255,229,100,.3);
    border-left: 8px solid #ffe564;
    padding: 15px 30px 15px 15px;
}
<script src="https://unpkg.com/pdf-lib@1.7.0"></script>
<script src="https://unpkg.com/downloadjs@1.4.7"></script>
<br><br><br>
<p>Click the button below to create a document and attach a JPEG image and PDF file with <code>pdf-lib</code></p>
<blockquote>Note that only some PDF readers can view attachments. This includes Adobe Reader, Foxit Reader, and Firefox.</blockquote>
<button onclick="addAttachments()">Create PDF</button>
<p class="small">(Your browser will download the resulting file)</p>

有用的链接:


请注意,要阅读/打开加密的PDF文件,您需要获取FPDI的付费版本,这使得在现有PDF文件中添加内容时使用免费版本相当不实用。 - Gavin Simpson
1
FPDI不支持导入加密的PDF文档,因为生成的文档是全新的文档,可以重新加密或不加密,所以这没有任何意义。使用FPDI_Protection类可以加密生成的文档,这是免费的FPDF_Protection类(而不是FPDI_Protection类)的增强版本。在这个类中,我们可以看到如何加密PDF。 - Bharata

2
jsPDF无法实现这一点,但是可以。您可以将两者结合使用,或仅使用。要在中加载现有的pdf,请执行以下操作:

async function loadPdf(){
  const response = await fetch('existing.pdf');
  const buffer = await response.arrayBuffer();
  const existingPdfDocBytes = new Uint8Array(buffer);
  const pdfDoc = PDFLib.PDFDocumentFactory.load(existingPdfDocBytes);
  return pdfDoc;
}

-1
我没有代码,但我有一个想法: https://www.npmjs.com/package/pdf-merger-js, pdf-merger-js可以合并blob pdf文件,您可以在doc.output('blob')上获取jspdf的blob url,然后从您的服务器获取文件并将其转换为blob,然后合并它们。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接