Splitting a PDF into many new PDFs - (foreign) PDF document error
What were you trying to do?
Hello,
I have been trying to rework how I was using copyPages. Previously I had it in a loop (which is stated as being an anti-pattern), and it was working but it was eating up too much memory on the server and crashing the process. So I looked through the issues and saw alot of comments about how to do this correctly. After trying I get a ""A page passed to PDFDocument.addPage or PDFDocument.insertPage was from a different (foreign) PDF document. If you want to copy pages from one PDFDocument to another, you must use PDFDocument.copyPages(...) to copy the pages before adding or inserting them."," exception so I was wondering if anyone could guide me the correct way.
I think my issue is that I cant recreate 1 initial PDF to use for copy pages, I have to dynamically create one for each page, but who knows. Anywho thanks for your time!
How did you attempt to do it?
Before (incorrect but working) :
for(let i: number = 0; i < pageCount; i++) {
upsertPromises.push(
pdfLib.PDFDocument.create()
.then((newDocument) => {
return newDocument.copyPages(multiPDFDoc, [i])
.then((copiedPage) => {
newDocument.addPage(copiedPage[0]);
return newDocument.saveAsBase64()
.then((fileBase64) => {
return fileBase64;
});
});
})
);
}
New attempt after referencing https://github.com/Hopding/pdf-lib/issues/47#issuecomment-569315318 :
function copyPage(originalPage): PDFPage {
const cloneNode = originalPage.node.clone();
const { Contents } = originalPage.node.normalizedEntries();
if (Contents) cloneNode.set(PDFName.of('Contents'), Contents.clone());
const cloneRef = originalPage.doc.context.register(cloneNode);
const clonePage = PDFPage.of(cloneNode, cloneRef, originalPage.doc);
return clonePage;
}
......
return pdfLib.PDFDocument.load(fileBase64)
.then((multiPDFDoc) => {
return multiPDFDoc.copyPages(multiPDFDoc, multiPDFDoc.getPageIndices())
.then((copiedPages) => {
copiedPages.forEach((copiedPage) =>{
upsertPromises.push(
pdfLib.PDFDocument.create()
.then((newPDF) => {
newPDF.addPage(copyPage(copiedPage));
return newPDF.saveAsBase64()
.then((fileBase64) => {
return fileBase64;
});
})
);
});
........
What actually happened?
{
"message": "A `page` passed to `PDFDocument.addPage` or `PDFDocument.insertPage` was from a different (foreign) PDF document. If you want to copy pages from one PDFDocument to another, you must use `PDFDocument.copyPages(...)` to copy the pages before adding or inserting them.",
"success": false
}
What did you expect to happen?
PDFs to split accordingly into 1 file per each page from the initial PDF
How can we reproduce the issue?
in your copyPages example try a loop like I have, should reproduce.
Version
1.17.1
What environment are you running pdf-lib in?
Node
Checklist
- [X] My report includes a Short, Self Contained, Correct (Compilable) Example.
- [ ] I have attached all PDFs, images, and other files needed to run my SSCCE.
Additional Notes
No response
Hello,
Here is code that accomplishes the task you're aiming for. Note, you have to copy a single page at a time because you intend to put each page on it's own document.
Promise.all(multiPDFDoc.getPages().map(function(_, index) {
return PDFDocument.create().then(function(newDocument) {
return newDocument.copyPages(multiPDFDoc, [index]).then(function(copiedPages) {
newDocument.addPage(copiedPages[0]);
return newDocument;
});
}).then(function(newDocument) {
return newDocument.saveAsBase64()
});
}));
this will make a single promise that resolves with an array of all the individual page pdfs as their base64 equivalent
Facing the same error as well. Are there any updates on this?