I need to position different text before I generate the pdf using IText. I've been thinking of using Chunks, but I don't know how to position them separately. I also tried using PdfContentByte but it doesn't generate any PDF File.
Why don't you use tables combined with Chunks for your layout. ex:
PdfPTable headerTable = new PdfPTable(2);
float[] headerTableWidths = { 80f, 20f };
headerTable.setWidthPercentage(100f);
headerTable.setWidths(headerTableWidths);
headerTable.getDefaultCell().setBorderWidth(0);
headerTable.getDefaultCell().setPadding(2);
headerTable.getDefaultCell().setBorderColor(BaseColor.BLACK);
headerTable.getDefaultCell().setFixedHeight(90f);
PdfPCell infoCell = new PdfPCell();
infoCell.setHorizontalAlignment(Element.ALIGN_CENTER);
infoCell.setVerticalAlignment(Element.ALIGN_TOP);
infoCell.addElement("test");
infoCell.addElement("text");
table.addCell(infoCell);
Related
I want to make a pdf report with English and Arabic texts. I have many tables/phrases across the page. I want to display Arabic text also along with English. I have seen the Arabic example in iText doxument also, using ColumnText. I couldn't help myself with that. My doubt is how to set canvas.setSimpleColumn(36, 750, 559, 780), the arguments in this method for tables/phrases at different positions. I have referred below questions also.Still I have issues.
Writing Arabic in pdf using itext,
http://developers.itextpdf.com/examples/font-examples/language-specific-exampleshe
Below is my code..
private static final String ARABIC = "\u0627\u0644\u0633\u0639\u0631 \u0627\u0644\u0627\u062c\u0645\u0627\u0644\u064a";
private static final String FONT = "resources/fonts/ARIALUNI.TTF";
Document document = new Document();
PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream("test.pdf"));
document.open();
Font f = FontFactory.getFont(FONT, BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
PdfPTable table = new PdfPTable(3);
Phrase phrase = new Phrase();
Chunk chunk = new Chunk("test value", inlineFont);
phrase.add(chunk);
// I want to add Arabic text also here..but direction is not //correct.also coming as single alphabets
p.add(new Chunk(ARABIC, f));
PdfPCell cell1 = new PdfPCell(phrase);
cell1.setFixedHeight(50f);
table.addCell(cell1);
document.add(table);
document.close();
Your code is kind of sloppy.
For example:
you define a PdfPTable with 3 columns, but you only add a single cell. That table will never be rendered.
you define a Phrase with name phrase, but later in your code you use p.add(...). There is no variable with name p in your code.
...
This lack of respect for the StackOverflow reader can result in not getting an answer, because you are expecting the reader not only to fix the actual problem –not being able to use English and Arabic text in a single PdfPCell—, but also to fix all the other (avoidable) errors in your code.
This is a working example:
public static final String FONT = "resources/fonts/NotoNaskhArabic-Regular.ttf";
public static final String ARABIC = "\u0627\u0644\u0633\u0639\u0631 \u0627\u0644\u0627\u062c\u0645\u0627\u0644\u064a";
public void createPdf(String dest) throws IOException, DocumentException {
Document document = new Document();
PdfWriter.getInstance(document, new FileOutputStream(dest));
document.open();
Font f = FontFactory.getFont(FONT, BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
PdfPTable table = new PdfPTable(1);
Phrase phrase = new Phrase();
Chunk chunk = new Chunk("test value");
phrase.add(chunk);
phrase.add(new Chunk(ARABIC, f));
PdfPCell cell = new PdfPCell(phrase);
cell.setUseDescender(true);
cell.setRunDirection(PdfWriter.RUN_DIRECTION_RTL);
table.addCell(cell);
document.add(table);
document.close();
}
The result looks like this:
As you can see, both the English and the Arabic text can be read fine. You may be surprised by the alignment and the order of the text. As we are working in the Right-to-Left writing system, left and right are switched. By default, text is left aligned, but as soon as we introduce the RTL run direction, this changes to right aligned.
In your code, you add the English text first, followed by the Arabic text. Text in Arabic is read from right to left. That's why you see the English text to the right, and why the Arabic text is added to the left of the English text.
All of this has been improved in iText 7. iText 7 has an extra pdfCalligraph module that takes care of other writing systems in a transparent way.
I'm using the lowagie.text.pdf library to create a PDF document from within my java application, however I have realised that strings with double spacing in them i.e. "DOUBLE SPACE" aren't preserved.Is this a .PDF limitation or have I overlooked something else ?
Font font = FontFactory.getFont(FontFactory.HELVETICA, 8);
float[] columnWidths = new float[columnCount];
PdfPCell headerCell = new PdfPCell(new Phrase(gridColumn.getCaption(), font));
PdfPTable table = new PdfPTable(columnWidths);
table.getDefaultCell().setBorderWidth(0.5f);
table.getDefaultCell().setBorderColor(Color.LIGHT_GRAY);
table.setHeaderRows(1);
for (PdfPCell headerCell : headerCells) {
table.addCell(headerCell);
}
String value = "DOUBLE SPACED";
table.addCell(new Phrase(value, font));
Document pdfDocument = new Document(PageSize.A4.rotate(), 0, 0, 0, 0);
ByteArrayOutputStream pdfStream = new ByteArrayOutputStream();
PdfWriter.getInstance(pdfDocument, pdfStream);
pdfDocument.addTitle(caption);
pdfDocument.open();
pdfDocument.add(table);
pdfDocument.close();'
Thanks.
I have realised that strings with double spacing in them i.e. "DOUBLE SPACE" aren't preserved
That depends on what you mean by being preserved.
I extended you sample a bit to print a single, a double, and a triple space
table.addCell(new Phrase("SINGLE SPACED", new Font(BaseFont.createFont(), 36)));
table.addCell(new Phrase("DOUBLE SPACED", new Font(BaseFont.createFont(), 36)));
table.addCell(new Phrase("TRIPLE SPACED", new Font(BaseFont.createFont(), 36)));
and furthermore updated the used classes to current iText 5.5.x variants.
If you look into the generated PDF internal instructions, you'll see
(SINGLE SPACED) Tj
...
(DOUBLE SPACED) Tj
...
(TRIPLE SPACED) Tj
Thus, iText does literally preserve the spaces.
The visual result:
As you see the gap is growing and growing. Thus, double and triple spaces are preserved in the visual representation of the PDF!
On the other hand, if you copy and paste using Adobe Reader, you get:
SINGLE SPACED
DOUBLE SPACED
TRIPLE SPACED
Thus, the current Adobe Reader does not copy&paste the space characters as they are inside the PDF but collapses multiple ones to a single one.
So:
Is this a .PDF limitation
This neither is a PDF limitation nor an iText limitation, it is a quirk of Adobe Reader (and some other PDF viewers, too).
I'm currently creating a system that generates a PDF. However, I cannot put two - three images in a single cell. I tried for-looping it but it has borders. What should i do?
Please take a look at the ImagesInCell example. It uses three images:
public static final String IMG1 = "resources/images/brasil.png";
public static final String IMG2 = "resources/images/dog.bmp";
public static final String IMG3 = "resources/images/fox.bmp";
These are the image instances:
Image img1 = Image.getInstance(IMG1);
Image img2 = Image.getInstance(IMG2);
Image img3 = Image.getInstance(IMG3);
The easiest way to add multiple images to a single cell is by using addElement multiple times:
PdfPTable table = new PdfPTable(1);
table.setWidthPercentage(50);
table.addCell("Different images, one after the other vertically:");
PdfPCell cell = new PdfPCell();
cell.addElement(img1);
cell.addElement(img2);
cell.addElement(img3);
table.addCell(cell);
document.add(table);
The result looks like this:
As you can see, the images were scaled automatically, to fit the width of the cell. If that isn't what you want, you have to improve your question, because you only claim that you can't add three images to the same cell, whereas this simple example proves the exact opposite.
Maybe you want something that looks like this:
In the first row with images, we use the same addElement() method as before, but we change the width percentage of the image to 20%:
cell = new PdfPCell();
img1.setWidthPercentage(20);
cell.addElement(img1);
img2.setWidthPercentage(20);
cell.addElement(img2);
img3.setWidthPercentage(20);
cell.addElement(img3);
table.addCell(cell);
In the second row with images, we use a different approach: we have wrapped the images inside Chunk objects, so that we can put them next to each other:
Paragraph p = new Paragraph();
img1.scalePercent(30);
p.add(new Chunk(img1, 0, 0, true));
p.add(new Chunk(img2, 0, 0, true));
p.add(new Chunk(img3, 0, 0, true));
cell = new PdfPCell();
cell.addElement(p);
table.addCell(cell);
Observe that I scaled the first image. The three images wouldn't fit next to each other if that image kept its original size.
Wrapping an image inside a Chunk has the advantage that we can mix images and text:
p = new Paragraph("The quick brown ");
p.add(new Chunk(img3, 0, 0, true));
p.add(" jumps over the lazy ");
p.add(new Chunk(img2, 0, 0, true));
cell = new PdfPCell();
cell.addElement(p);
table.addCell(cell);
I am trying to add some text with a bar code in a table cell using itext as per the following code but it does not show in the pdf file. i tried adding chunks and paragraph. Any help on this would be appreciated.
Barcode128 barcode = new Barcode128();
//barcode.setCodeType(Barcode.EAN8);
barcode.setCode(code);
PdfPCell cell = new PdfPCell(barcode.createImageWithBarcode(writer.getDirectContent(), BaseColor.BLACK, BaseColor.GRAY), true);
Paragraph paragraph = new Paragraph("Hello World");
cell.addElement(paragraph);
cell.setPadding(10);
You are probably confused by text vs. composite mode.
When using the PdfPCell(Image) constructor, you create a cell in text mode. Any subsequent call to addElement(Element) will then switch the cell to composite mode, removing all content previously entered in the constructor.
You'll have to change your code that way:
PdfPCell cell = new PdfPCell();
Barcode128 barcode = new Barcode128();
barcode.setCode(code);
Image barcodeImage = barcode.createImageWithBarcode(writer.getDirectContent(), BaseColor.BLACK, BaseColor.GRAY);
cell.addElement(barcodeImage);
Paragraph paragraph = new Paragraph("Hello World");
cell.addElement(paragraph);
I am trying to read one PDF and copy its data into another PDF. The first PDF contains some text and images and I wish to write an image in the second PDF exactly where the text ends(which is basically the end of the PDF file). RIght now it just prints at the top. How can I make this change?
PdfReader reader = null;
reader = new PdfReader(Var.input);
Document document=new Document();
PdfWriter writer = null;
writer = PdfWriter.getInstance(document,new FileOutputStream(Var.output));
PdfImportedPage page = writer.getImportedPage(reader, 1);
reader.close();
document.open();
PdfContentByte cb = writer.getDirectContent();
// Copy first page of existing PDF into output PDF
document.newPage();
cb.addTemplate(page, 0, 0);
// Add your new data / text here
Image image = null;
image = Image.getInstance (Var.qr);
document.add(image);
document.close();
Try this:
First get the location/co-ords of where the image needs to go, then simply add the second line from below to your code so the image is inserted at that location "X, Y"
Image image = Image.getInstance(String RESOURCE);
image.setAbsolutePosition(X, Y);
writer.getDirectContent().addImage(image);
Take a look here for some examples in iText 5: https://itextpdf.com/en/resources/examples/itext-5-legacy/chapter-3-adding-content-absolute-positions
You should use a PdfStamper instead of a PdfWriter with imported pages. Your approach throws away all interactive contents. You can use sorifiend's idea there, too.
To determine where the text on the given page ends, have a look at the iText in Action, 2nd edition example ShowTextMargins which parses a PDF and ads a rectangle showing the text margin.