I use itext.dll for generating a PDF using ASP.NET and I want a footer in my document? - itext

I use itext.dll for genrating a PDF using ASP.NET and I want a footer in my document in the form of:
Page 1 of 6
HeaderFooter footer = new HeaderFooter(new Phrase("Page"), new Phrase(" of 6"));
footer.setBorder(Rectangle.NO_BORDER);
footer.setAlignment(Element.ALIGN_CENTER);
document.setFooter(footer);
Is this possible without hardcoding the total number of pages? I.e. is there a method to get the total number pages in a document?

I have found that there are (at least) 2 ways of doing this.
One is to create the document without the footer and after that use PdfStamper to stamp the page numbers with total on it. But that raised some problems with me when I output the stampers product to MemoryStream and there seems to be no way of closing the stamper without closing the stream at the same time.
The other way is to create one instance of PdfTemplate that will represent the total page count and add that to every page to footer or where ever you want it.
Next you can use your own PdfPageEventHelper class and implement OnCloseDocument method where you can fill the template with total page count:
public override void OnCloseDocument(PdfWriter writer, Document document)
{
PageCountTemplate.BeginText();
PageCountTemplate.SetFontAndSize(HeaderFont.BaseFont, HeaderFont.Size);
PageCountTemplate.ShowText((writer.CurrentPageNumber - 1).ToString());
PageCountTemplate.EndText();
}
I personally also use OnOpenDocument to create the template and OnEndPage to write it on each page.
EDIT:
To answer Jan's question, OnCloseDocument is called only once when the whole doc has been written. When Doc.Close() is called I mean.

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);

Removing newlines when continuing a column on a new page

I am using iTextSharp to generate a PDF on the fly. I am using the ColumnText class in text mode using the ColumnText.SetColumns() method to define column boundaries using code like the following:
myColumnText.SetColumns(leftCoords, rightCoords)
myColumnText.AddText(New Chunk("Lorem ipsum..."))
myColumnText.AddText(Chunk.NEWLINE))
myColumnText.AddText(Chunk.NEWLINE))
myColumnText.AddText(New Chunk("Lorem ipsum..."))
myColumnText.AddText(Chunk.NEWLINE))
myColumnText.AddText(Chunk.NEWLINE))
As you can see, I emit a block of text and then two Chunk.NEWLINEs to add whitespace between paragraphs.
I then use ColumnText.Go to emit the content, creating new pages as needed, like so:
While ColumnText.HasMoreText(myColumnText.Go())
myDocument.NewPage()
myColumnText.SetColumns(leftCoords, rightCoords)
End While
The problem I am running into is that depending on the content in the ColumnText object a page break might occur right at the end of a chunk of text but before the Chunk.NEWLINEs, meaning that the content on the next page starts with two Chunk.NEWLINEs rather than at the top of the page.
Is there a way to somehow suppress Chunk.NEWLINEs if they are the first things emitted on a new page? My thought was that if I could somehow see the text that was about to be emitted by ColumnText.Go I could see if I was about to emit a Chunk.NEWLINE and remove it from the content stream or something...
Thanks

Table of contents with page number - how to implement

Is it possible to implement Table of contents with page number on first page of the PDF report?
I've read the below links and refered in google:
1) http://community.jaspersoft.com/questions/541300/table-contents-ireport
2) http://community.jaspersoft.com/questions/529040/generation-page-numbers-table-content
On first link, They are using scriptlets for this. I want Table of contents with page number on the first page of pdf report. But I do not understand where to start. Any ideas?
I would recommend you checking this sample from the original documentation.
There is no way (or at least I don't know/haven't found how) to generate the Table of Contents at the beginning (since there is no way to know the pages numbers). So you will have to generate it at the end (in the summary band) and move it afterwards to where you want to place it. To move it use JasperPrint class, methods getPages, addPage, removePage.
I guess you will have subreports, if so, you need to pass the JRBeanCollectionDataSource you will be filling during runtime to each subreport (and return the value back to the master report).
Hope that helps.