Using iTextSharp, how can I insert a new page at the beginning of the page, when the PdfWriter has been writing pages already? Suppose the case of an index page which should be the first page of the document, but you wouldn't know its contents until you write the whole document. Particularly, on which page is each section/chapter written.
You can't go back to the first page while you're creating a document, but there are different ways to solve your problem.
If you don't expect to have many pages, you could consider the solution that is explained in chapter 5 of iText in Action - Second Edition, more specifically in the MovieHistory1.java example.
In this example, we reorder the pages right before we close the document:
// step 1
Document document = new Document();
// step 2
PdfWriter writer
= PdfWriter.getInstance(document, new FileOutputStream(RESULT));
// IMPORTANT: set linear page mode!
writer.setLinearPageMode();
// step 3
document.open();
// step 4
// Add all your content
// Create a new order for the pages
int total = writer.reorderPages(null);
// change the order
int[] order = new int[total];
for (int i = 0; i < total; i++) {
order[i] = i + toc;
if (order[i] > total)
order[i] -= total;
}
// apply the new order
writer.reorderPages(order);
// step 5
document.close();
Why do I only recommend this for documents with a limited number of pages? For this functionality to work we need to create a linear page tree:
writer.setLinearPageMode();
A linear page tree is not really a tree (it's a tree without any branches) and that is not optimal in PDF.
It is better to reorder the pages in a second go. This is explained in two questions that are bundled in The Best iText Questions on StackOverflow (a free ebook).
The questions were:
Create Index File(TOC) for merged pdf using itext library in java
PDF Page re-ordering using itext
I know that having redundant info on SO is not ideal, but this is the code you'd need:
PdfReader reader = new PdfReader(baos.toByteArray());
int n = reader.getNumberOfPages();
reader.selectPages(String.format("%d, 1-%d", n, n-1));
PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(filename));
stamper.close();
Related
i want to align the Chunk Left and Right side. Also the each Chunk have different format you can see in image.
i try the below code:
Chunk invoiceid = new Chunk("Invoice ID: ", font9BoldDARK_GRAY);
Chunk invoiceidvalue = new Chunk("value from database", font10NoramlBlack);
Chunk inoicdate = new Chunk("Invoice Date: ", font9BoldDARK_GRAY);
Chunk inoicedatevalue = new Chunk(new SimpleDateFormat("MMMM dd yyyy").format(new Date()), font10NoramlBlack);// get From database
Paragraph invoiceParagraph = new Paragraph();
invoiceParagraph.setTabSettings(new TabSettings(325f));
invoiceParagraph.add(invoiceid);
invoiceParagraph.add(invoiceidvalue);
invoiceParagraph1.add(Chunk.TABBING);
invoiceParagraph1.add(inoicdate1);
invoiceParagraph1.add(inoicedatevalue1);
invoiceParagraph1.setAlignment(Element.ALIGN_JUSTIFIED);
pdfdocument.add(invoiceParagraph1);
which gives me result the Right side Chunk not in well format.
but i want align the like
can you please help me.
The correct way to do this, is to use iText 7. Read chapter 3 of the building blocks tutorial to discover how to create a PDF that looks like this:
The code to achieve this, is amazingly simple:
public void createPdf(String dest) throws IOException {
// create a low-level document
PdfDocument pdf = new PdfDocument(new PdfWriter(dest));
// create a high-level document
Document document = new Document(pdf);
// create a TabStop array
List<TabStop> tabstops = new ArrayList<TabStop>();
// don't forget to make a tab stop that aligns to the right
tabstops.add(new TabStop(325, TabAlignment.RIGHT));
// add paragraphs with Tab objects to the high-level document
document.add(new Paragraph().addTabStops(tabstops)
.add("Text to the left").add(new Tab()).add("Text to the right"));
document.add(new Paragraph().addTabStops(tabstops)
.add("ABCD").add(new Tab()).add("EFGH"));
document.add(new Paragraph().addTabStops(tabstops)
.add("01234").add(new Tab()).add("56789"));
document.add(new Paragraph().addTabStops(tabstops)
.add("iText 5 is old").add(new Tab()).add("iText 7 is new"));
// close the document
document.close();
}
Before you say I don't recognize that code, let me tell you that you are right: iText was completely rewritten. The code is now more intuitive to create, and easier to read.
Update: you are using the old iText 5 version that is no longer supported for free users (only for paying customers). As explained in the 2009 book "iText in Action - Second Edition", you created glue like this:
Chunk glue = new Chunk(new VerticalPositionMark())
You then used this glue in a Paragraph like this:
Paragraph p = new Paragraph();
p.add("Text to the left");
p.add(glue);
p.add("Text to the right");
This way, you can indeed avoid having to use tabs in iText 5.
this work for me:
Paragraph p = new Paragraph("some Text");
p.setAlignment(Element.ALIGN_RIGHT);
I've spent much time to no avail on this issue. My PDF pages are automatically numbered 'Page 1 of 0' when creating a PDF as follows:
using (MemoryStream ms = new MemoryStream())
using (Document document = new Document(PageSize.A4, 10, 10, 25, 25))
using (PdfWriter writer = PdfWriter.GetInstance(document, ms))
{
writer.PageEvent = new TextEvents();
document.Open();
document.NewPage();
document.Add(new Phrase("Hello World!"));
document.Close();
writer.Close();
var docout = ms.ToArray();
ms.Close();
return docout;
}
How do I stop this behaviour? I do not want a page numberer.
In this line
writer.PageEvent = new TextEvents();
you tell itext to send page events to an instance of your own TextEvents class. As no other part of the code you show adds page numbers, it must be this class of yours that does.
You can test this by removing the code line quoted above.
Beware: probably that TextEvents class does something else, too, probably something you want. Instead of completely removing that line above, therefore, you might eventually have to analyse your TextEvents class and only remove the unwanted behaviour.
To add to the above answer, TextEvents() should be extending PdfPageEventHelper which has an onEndPage() method where you will find the code that adds page x of n.
Hi I recently posted a question here :
IText PDFImage seems to shrink or disappear during new pages after upgrade from 2.1.7 to 5.5.5 (Java .jars)
But I think it is not the problem with the library but more of a missing setting sort of problem. I am wondering if there is a way to control what element gets drawn on the existing page verses pushing to a new page
I want to do the following
-create document
-create pdfPTable
-create a bunch of image element for each PdfPCells
-add to pdfPTable then write to document
Result: It seems that some images get shrink near the end/beginng of the page or is missing ( seems like its trying to fit on to the page )
Sample code again for visibility
ByteArrayOutputStream baos = createTemporaryOutputStream();
Document doc = newDocument();
PdfWriter writer = newWriter(doc, baos);
writer.setViewerPreferences(PdfWriter.ALLOW_PRINTING | PdfWriter.PageLayoutSinglePage);
//create page rectangle landscape
Rectangle page = new Rectangle(PageSize.A4.rotate());
doc.setPageSize(page);
doc.setMargins((float)36.0, (float)36.0, (float)36.0, (float)36.0);
doc.open();
//create element pdf table.
PdfPTable table = new PdfPTable(new float[]{(float) 770.0});
table.setWidthPercentage(100);
table.setSplitRows(true);
table.setSplitLate(false);
table.setHeaderRows(0);
// in my case I used 5 800*600 images (same picture)
//then I loop through them and create pdfcell
//and then add it to table which then gets added to the document
List<Image> hi = (List<Image>) model.get("images");
for (Image image : hi) {
com.itextpdf.text.Image pdfImage = com.itextpdf.text.Image.getInstance(image.getBytes());
pdfImage.scalePercent((float) (0.8642384 * 100));
PdfPCell cell = new PdfPCell(pdfImage, false);
table.addCell(cell);
}
doc.add(table);
doc.close();
thank you for your time. Any insight as to what my problem is would be helpful
I have a pdf which include text written in Type 3 Font.
I want to get some text from it and write it into other pdf in exactly same shape.
I am using itext. Please give me a tip.
edit: I attached my code.
DocumentFont f = renderInfo.getFont();
String str = renderInfo.getText();
x = renderInfo.getBaseline().getStartPoint().get(Vector.I1);
In this code, I want to write str into x value position.
In Type 3 Font, is it work?
You can copy parts of one page to a new one using code like this:
InputStream resourceStream = getClass().getResourceAsStream("from.pdf");
PdfReader reader = new PdfReader(new FileOutputStream("from.pdf"));
Rectangle pagesize = reader.getPageSizeWithRotation(1);
Document document = new Document(pagesize);
PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream("areaOfFrom.pdf"));
document.open();
PdfContentByte content = writer.getDirectContent();
PdfImportedPage page = writer.getImportedPage(reader, 1);
content.saveState();
content.rectangle(0, 350, 360, 475);
content.clip();
content.newPath();
content.addTemplate(page, 0, 0);
content.restoreState();
document.close();
reader.close();
This turns your
into
Unfortunately, though, that hidden content is merely... hidden... but it is still there. You can especially mark the lines with that hidden text and try to copy&paste them.
If you want to completely remove that hidden text (or start out by merely copying the desired text), you have to inspect the content of the imported page and filter it. I'm afraid iText does not yet explicitly support something like that. It can be done using the iText lowlevel API but it is quite some work.
I want to create a PdfWriter Object and set Events for Header and Footer.
The problem is it works if I create a new PDF. But my problem is I already have a PDF in Output Stream. Please find my sample code below.
Document document = new Document();
try {
// step 2:
FileInputStream is = new FileInputStream("D://2.pdf");
int nRead;
byte[] data = new byte[16384];
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
while ((nRead = is.read(data, 0, data.length)) != -1) {
buffer.write(data, 0, nRead);
}
buffer.flush();
PdfWriter writer = PdfWriter.getInstance(document,buffer);
writer.setViewerPreferences(PdfWriter.PageLayoutTwoColumnLeft);
writer.setPageEvent(new DossierPortalUtil());
document.setMargins(36, 36, 54, 72);
// step 3:
document.open();
document.add( new Chunk("testing"));
} catch (Exception de) {
de.printStackTrace();
}
finally{
document.close();
}
If I comment the line
document.add( new Chunk("testing"));
I get an exception
Exception in thread "main" ExceptionConverter: java.io.IOException: The document has no pages.
Without commenting there are no exceptions but it doesnt add the Header and Footer. Any clues are highly appreciated.
Regards,
Tina
enter code here
Yep.
You're trying to modify an existing PDF with PdfWriter, when you should be using PdfStamper.
Adding text with a stamper is Far Less Trivial than doing so with PdfWriter and a Document.
You need to create a ColumnText object, and get a PdfContentByte by calling myStamper.getOverContent(pageNum).
You add the paragraphs/chunks/etc to the ColumnText, and pass it the PdfContentByte (and some positional parameters) to draw the text.
Alternatively, you can create a separate PDF with your text (and anything else), then use PdfStamper & PdfImportedPage to import those pages and write them over top of the existing ones. PDF page backgrounds are transparent until you draw something over them, so the text (and stuff) will appear over top of the existing page. This is noticeably less efficient, as the second document has to be converted to a byte array in PDF syntax (if you're using a ByteArrayOutputStream instead of writing to a file, which would be even slower), parsed again, and then added to the original doc and written out a second time.
It's worth a little extra effort to use ColumnText.
You'll also need to write your header and footer directly with PdfContentByte calls, but you have to do that already within your PdfPageEvent, so those changes should be quite simple.