Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merge/Concatenate Multiple Forms into one PDF document #309

Open
JaneSjs opened this issue Mar 22, 2024 · 1 comment
Open

Merge/Concatenate Multiple Forms into one PDF document #309

JaneSjs opened this issue Mar 22, 2024 · 1 comment
Labels
enhancement New feature or request user issue An issue or bug reported by users.

Comments

@JaneSjs
Copy link
Contributor

JaneSjs commented Mar 22, 2024

@JaneSjs JaneSjs added enhancement New feature or request user issue An issue or bug reported by users. labels Mar 22, 2024
@JaneSjs
Copy link
Contributor Author

JaneSjs commented Mar 22, 2024

In the meantime, it is possible to merge multiple PDF documents into a single document using third-party libraries. The following demo shows how to merge two surveys using the pdf-lib library: View Demo.

import React from "react";
import { SurveyPDF } from "survey-pdf";
import "survey-core/defaultV2.min.css";
import "./index.css";
import { json3, json4, data3, data4 } from "./json";
import { PDFDocument } from "pdf-lib";

async function mergePdfs(pdfsToMerges) {
  const mergedPdf = await PDFDocument.create();
  const actions = pdfsToMerges.map(async (pdfBuffer) => {
    const pdf = await PDFDocument.load(pdfBuffer);
    const copiedPages = await mergedPdf.copyPages(pdf, pdf.getPageIndices());
    copiedPages.forEach((page) => {
      //page.setWidth(210);
      mergedPdf.addPage(page);
    });
  });
  await Promise.all(actions);
  const mergedPdfFile = await mergedPdf.save();

  // Convert ArrayBuffer to Blob
  const mergedPdfBlob = new Blob([mergedPdfFile], { type: "application/pdf" });

  // Create a URL for the Blob
  const mergedPdfUrl = URL.createObjectURL(mergedPdfBlob);

  // Create a download link
  const downloadLink = document.createElement("a");
  downloadLink.href = mergedPdfUrl;
  downloadLink.download = "merged.pdf";

  // Append the download link to the body and click it programmatically
  document.body.appendChild(downloadLink);
  downloadLink.click();

  // Clean up by removing the download link and revoking the URL
  document.body.removeChild(downloadLink);
  URL.revokeObjectURL(mergedPdfUrl);
}

async function createSurveyPdfModel(surveyJsons, responses) {
  let options = {
    fontSize: 14,
    margins: {
      left: 10,
      right: 10,
      top: 10,
      bot: 10,
    },
    format: [210, 297],
  };
  const surveyPDF1 = new SurveyPDF(surveyJsons[0], options);
  surveyPDF1.data = responses[0];
  const surveyPDF2 = new SurveyPDF(surveyJsons[1], options);
  surveyPDF2.data = responses[1];

  // Load PDF documents and wait for both to be loaded
  const [pdf1Content, pdf2Content] = await Promise.all([
    loadPDFContent(surveyPDF1),
    loadPDFContent(surveyPDF2),
  ]);

  if (pdf1Content && pdf2Content) {
    await mergePdfs([pdf1Content, pdf2Content]);
  } else {
    console.error("Error: One or both PDF buffers are empty.");
  }
}

async function loadPDFContent(surveyInstance) {
  try {
    const blob = await surveyInstance.raw("blob");
    const reader = new FileReader();
    reader.readAsArrayBuffer(blob);
    return await new Promise((resolve, reject) => {
      reader.onload = () => {
        resolve(reader.result);
      };
      reader.onerror = reject;
    });
  } catch (error) {
    console.error("Error loading PDF content:", error);
    return null;
  }
}

function SurveyPdfComponent() {
  return (
    <button
      onClick={() => createSurveyPdfModel([json3, json4], [data3, data4])}
    >
      Export Merged Surveys
    </button>
  );
}

export default SurveyPdfComponent;
//...
export const json3 = {
  title: "Sample Survey 1",
  mode: "display",
  pages: [
    {
      name: "page1",
      elements: [
        {
          type: "boolean",
          name: "question1",
        },
      ],
    },
  ],
};
export const json4 = {
  title: "Sample Survey 2",
  mode: "display",
  pages: [
    {
      name: "page1",
      elements: [
        {
          type: "boolean",
          name: "question2",
          title: "My Survey",
        },
      ],
    },
  ],
};
export const data3 = {
  question1: true,
};
export const data4 = {
  question2: false,
};

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request user issue An issue or bug reported by users.
Projects
None yet
Development

No branches or pull requests

1 participant