Second page for PDFContentByte - itext

I'm pretty sure I'm missing something simple, but since I've been breaking my head on this for a while, I'm just going to ask.
I'm using JavaScript to access the iText (Java) library to take a filable PDF and serve it up via a browser. The process has worked for my first one, and now I'm doing one where the original fillable PDF has 2 pages. I've been trying to get the second page for a while now. I'm using the PdfContentByte to get it to the browser, and it works except I can't seem to get the PdfContentByte to have a second page. My relevant code is below. When I add the second template (page2) they way I do, it moves what I'm writing, but I'm still just getting one (US letter) page.
This may not be the most efficient code, but like I said, I've been trying a few things on this. If someone has a pointer, I would be very grateful.
var cb:com.itextpdf.text.pdf.PdfContentByte = writer.getDirectContent();
var cb2:com.itextpdf.text.pdf.PdfContentByte = writer.getDirectContent();
var reader2:com.itextpdf.text.pdf.PdfReader = new com.itextpdf.text.pdf.PdfReader(os.toByteArray());
var page:com.itextpdf.text.pdf.PdfImportedPage = writer.getImportedPage(reader2, 1);
cb.addTemplate(page, 0, 0); //this works as expected
var page2:com.itextpdf.text.pdf.PdfImportedPage = writer.getImportedPage(reader2, 2);
// this will add, and with the 100 do an offset, but the
// "physical size" of the paper is the same
cb2.addTemplate(page2, 0, 100);

Have a look at chapter 6 of iText in Action, 2nd edition, especially at subsection 6.4.1: Concatenating and splitting PDF documents.
Listing 6.22, ConcatenateStamp.java, shows you how you should create a PDF from copies of pages of multiple other PDFs; the sample actually additionally adds a new "Page X of Y" footer which you may keep or remove from the sample.

Related

itext placeholder on top of every new page

i try to print invoices on a pre defined template on a piece of paper.
Because of that template i need some placeholders before the invoice is printed to avoid overplap. Sometimes the invoices get a little bit longer so that i need a second invoice page. If the invoice just has one page everything works fine.
My issue:
If the invoice gets longer (second page) the placeholder has to be on the beginning of the second page as well. I was not able to figure out how to do this.
Here is how i do it on first page:
PdfPTable placeholderTable = new PdfPTable(1);
placeholderTable.setHorizontalAlignment(PdfPTable.ALIGN_RIGHT);
placeholderTable.setWidthPercentage(91f);
PdfPCell placeholderCell = new PdfPCell(new Phrase(" ", font4GroßFett));
placeholderCell.setBorder(0);
placeholderTable.addCell(placeholderCell);
document.add(placeholderTable);
I tried a lot of things but especially i think the following is important (maybe i just use it in a wrong way)
writer.setPageEvent(new PdfPageEventHelper() {
#Override
public void onStartPage(final PdfWriter writer, final Document document) {
//add the placeholder here?
}
});
This seemed to be the best solution but i cant add elements to the document in this method (see offical documentation of itext)
My question is now: How can i set some placeholders (space) to the top of EVERY new page?
Thank you very much for helping!

is it posible to include page numbers with onendpage events

I am working through some more examples from the new itextpdf website...(good job by the way) I normally add page numbers in headers and footers as a second pass over the document once it is completed.
Is there a way to add the page number dynamically in a header or footer as an onendpage event?
Clearly this could be done by using a counter with document.addPage(), but text may create new pages all by itself when given a large text block so this would then not work.
Thank you very much for your comment on the new web site!
You can indeed get the current page number in the onEndPage() method and add it to the document. Please take a look at the MovieHistory2 example, or better yet: the MovieCountries1 example.
Allow me to simplify the onEndPage() method of these examples:
public void onEndPage(PdfWriter writer, Document document) {
Rectangle rect = writer.getPageSize();
ColumnText.showTextAligned(writer.getDirectContent(),
Element.ALIGN_CENTER, new Phrase(
String.format("page %d", writer.getPageNumber())),
(rect.getLeft() + rect.getRight()) / 2, rect.getBottom() - 18, 0);
}
In this snippet, writer.getPageNumber() will give you the current page number. I add it to the page at the bottom-middle.

iTextSharp - Continuing ordered list on second page with a number other than '1'

I am fairly new to iTextSharp. I create PDFs by adding variable data (text/barcodes/images) to existing PDF documents/templates (think boiler plate). Most commonly, I have to place various sections of text in specific places. I know how to create an ordered list, but I have come across a situation where the list begins with #1 on the first page and then #2-4 on the top of the second page. I use two different templates for p1 and p2.
I am currently creating the document by creating ColumnTexts, placing SimpleColumns with specific coordinates, and then placing phrases inside. I am not sure if this is the best way or not, so I am open for alternative solutions.
I have checked out several places including http://www.mikesdotnetting.com/article/83/lists-with-itextsharp but I see nothing that describes how to start a list at a number other than '1'. None of the 6 overloads provide a parameter for starting number.
Thanks!
There are two answers to your question. The first one is to point you to the official documentation. There is a method setFirst() that (I quote) sets the number that has to come first in the list.
You are using the C# port of iText, so if you want the list to start counting at 10, you need to do something like:
list.First = 10;
The second answer takes more time, but it is probably the better one.You don't need two List objects, one for the first page and one for the second page. It's better to add the List to a ColumnText object and then distribute the column over two pages.
Take a look at the ListInColumn example. It takes an existing PDF (with the text "Hello World Hello People") and it adds a list using ColumnText: list_in_column.pdf
This is how it's done:
PdfReader reader = new PdfReader(src);
PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(dest));
List list = new List(List.ORDERED);
for (int i = 0; i < 10; i++) {
list.add("...");
}
ColumnText ct = new ColumnText(stamper.getOverContent(1));
ct.addElement(list);
Rectangle rect = new Rectangle(250, 400, 500, 806);
ct.setSimpleColumn(rect);
int status = ct.go();
if (ColumnText.hasMoreText(status)) {
ct.setCanvas(stamper.getOverContent(2));
ct.setSimpleColumn(rect);
ct.go();
}
stamper.close();
To add the content on the first page, I use:
ColumnText ct = new ColumnText(stamper.getOverContent(1));
You are probably using similar code.
The content is added using the line:
int status = ct.go();
If not all the content was added, I change the canvas to add the rest of the content on the second page:
ct.setCanvas(stamper.getOverContent(2));
The rest of the code is pretty standard.
I think the setCanvas() method is the missing piece in your puzzle, although in your case, you'll need:
ct.Canvas = stamper.GetOverContent(2);

Zend Framework PDF Page resize (scale) / rotate (page not an element)

is there any possibility to resize an Zend_Pdf_Page Object from (e.g.) DIN-A4 to DIN-A6 (or any other size)?
i would like to merge 4 PDF (1 page) files to 1 pdf file (1 page). in each edge should be one of the 4 pdf files.
positioning, grid, e.g. is no problem... but how can i change the document size (of an existing pdf file) and how can i rotate the whole document?
i work with ZF1, but if the only way to fix this problem is to use an external library - no problem.
PS: sorry for my bad english (hope it is enough to understand my problem)
edit : 14:49 05/12/2014
also tried with imagick to convert pdf to image, but quality is too bad for printing as those small thumbs... :-(
Technically your requirements could be done by transforming the page into a so called form XObject which can be place on a new created page. That's how FPDI works: http://www.setasign.com/products/fpdi/demos/thumbnails/ (maybee an alternative for you).
I just checked the code of ZendPdf but I cannot find any method that may allow this.
Rotation can be done with FPDF/FPDI too: http://fpdf.org/en/script/script2.php
In your code, if you have something like $page = new Zend_Pdf_Page(); you can set here the desired dimensions.
For example, you can write $page = new Zend_Pdf_Page('297:420'); for A6 format (if I'm not mistaken).
To represent an A4 page in landscape (wide) orientation, you can write
$page = new Zend_Pdf_Page('a4-landscape');
or
$page = new Zend_Pdf_Page(Zend_Pdf_Page::SIZE_A4_LANDSCAPE);
You can look at the documentation or the source code of the constructor of the Zend_Pdf_Page class for more information.
I hope it will help you. :)

Inserting a table into multiple PDF pages with columnText

I am trying to insert a table into a PDF template. It is successful when the table fits on the page. However, if it is too big then we lose data. I basically just want it to paste what is left of the ColumnText to a next page which looks like page # 5.
Here is my current code, it is creating a blank white page in front of page #4 and it is writing the remaining ColumnText data over where it already pasted the first time.
PdfImportedPage templatePage = stamper.GetImportedPage(pdfReader, 5);
int pageNum = 5;
while (true)
{
ct.SetSimpleColumn(-75, 50, PageSize.A4.Height + 25, PageSize.A4.Width - 200);
if (!ColumnText.HasMoreText(ct.Go()))
break;
pageNum++;
stamper.InsertPage(pageNum, new Rectangle(792f, 612f));
stamper.GetOverContent(pageNum).AddTemplate(templatePage, 0, 0);
}
I've created a small code sample named AddLongTable that you can use to complete your code. The reason why all the content is added to the same page is simple. You forgot this line:
ct.setCanvas(stamper.getOverContent(pageNum));
Note that my example is written in Java, but I'm sure you'll know how to adapt it to C#. If you post your fix in a comment, I'll update my answer, adding the C# version of the solution.