galkahana / HummusJS

Node.js module for high performance creation, modification and parsing of PDF files and streams
http://www.pdfhummus.com
Other
1.14k stars 169 forks source link

add page number of X to new PDF, after pages have been created #232

Closed simonaberry closed 6 years ago

simonaberry commented 6 years ago

I am generating a new PDF from scratch, using hummus.createWriter using an in memory byte array custom stream

The number of pages is dynamic. How would I be able to go back over all pages at the end once I know the total pages, to add a footer like Page 1 of 10 ?

If I use hummus.createWriterToModify it looks like I need to have a new input Stream or save the file to fs ..? Is there not a way to create it directly from the writer generated by hummus.createWriter ?

chunyenHuang commented 6 years ago

Is it possible you just save all pdf information to an object and use hummus to write the pdf at the end? Unless you want to see the progress of generating pdf, or you don't need have to create the pdf before you gather all the information to write.

simonaberry commented 6 years ago

why didn't I think of that! Great idea, thanks

istvanpp commented 5 years ago

@chunyenHuang, please can you write a sample code to illustrate how to insert page number on each page like Page 1 of X? Thank you.

simonaberry commented 5 years ago

@istvanpp you have two options :

  1. If you are generating all the PDF content from non-pdf source (as per my original question), do a dry run as per @chunyenHuang suggestion :

    // pseudo code : 
    // first run
    load source information, set pageYCursor = 0, set numPages = 0
    loop through items to print to pdf, 
        determine how much space each item will take, incrementing pageYCursor 
        if pageYCursor > pageLength => numPages ++, pageYCursor = 0
    next item
    
    //final pass
    load source information, set pageYCursor = 0, set pageNumber = 0
    initialise hummus pdfWriter
    loop through items to print to pdf, 
        write actual data to PDF, incrementing pageYCursor 
        write footer : pageNumber of numPages
        if pageYCursor > pageLength => pageNumber ++, pageYCursor = 0
    next item
  2. If you have an existing PDF document that you just want to stamp the page numbers on, use something like :

    var copyContext = pdfWriter.createPDFCopyingContext();
    var numPages = copyContext.getSourceDocumentParser().getPagesCount();

  ///etc
istvanpp commented 5 years ago

@simonaberry Hello, I have the second option with an existing PDF file.

My sample code what is need to modify is working, but the page number is inserted on the same place and only on the first page. Probably I am using a wrong method:

var pdfInsertPageNumber = hummus.createWriterToModify('AppendPagesTest.pdf', {
            modifiedFilePath:'AppendPagesTestModif.pdf'
});
var pageModifier = new hummus.PDFPageModifier(pdfInsertPageNumber,0);
var getFont = pdfInsertPageNumber.getFontForFile('liberationregular.ttf');
var textOptions = {font:getFont, size:14, colorspace:'gray', color:'red'};
var totalPages = pdfInsertPageNumber.getModifiedFileParser().getPagesCount();
var pageNumber;

for (pageNumber = 1; pageNumber <= totalPages; pageNumber++) {
    pageModifier.startContext().getContext().writeText('Page ' + String(pageNumber) + 'of ' + String(totalPages), 75, 805, textOptions);
}
pageModifier.endContext().writePage();
pdfInserPageNumber.end();
simonaberry commented 5 years ago

I haven't checked the documentation, but my guess is :

var pageModifier = new hummus.PDFPageModifier(pdfInserPageNumber,0);

this gets a 'pointer' to page 0 (second argument)

then in your loop your keep writing to the same pageModifier object - i.e. to page 0

so you probably need to get a new pageModifier each time inside your loop, with the second parameter as (pageNumber-1)

istvanpp commented 5 years ago

Thank you, this works:

for (pageNumber = 1; pageNumber <= totalPages; pageNumber++) {
    pageModifier = new hummus.PDFPageModifier(pdfInsertPageNumber, pageNumber-1);
    pageModifier.startContext().getContext().writeText('Page ' + String(pageNumber) + ' of ' + String(totalPages), 75, 805, textOptions);
    pageModifier.endContext().writePage();
}