Itext Paragraph alignment issue in Android - java

I am creating PDF outfile file using itext library in android but Paragraph is not centered align while similar code is Java desktop application creates output with center align.
I have also checked by using Element.ALIGN_CENTER and Paragraph.ALIGN_CENTER but no success in android.
Android Code
Here is my code in android for creating centered align Paragraph.
Paragraph prefaceX = new Paragraph();
prefaceX.setAlignment(Element.ALIGN_CENTER);
addEmptyLine(preface, 1);
prefaceX.add(new Paragraph(getString(R.string.report_title), catFont));
prefaceX.add(new Paragraph(getString(R.string.disclaimer), smallBoldMM));
document.add(prefaceX);
where addEmptyLine is as follow
private static void addEmptyLine(Paragraph paragraph, int number) {
for (int i = 0; i < number; i++) {
paragraph.add(new Paragraph(" "));
}
}
Output PDF in android
Java Desktop application code
Paragraph prefaceX = new Paragraph();
prefaceX.setAlignment(Paragraph.ALIGN_CENTER);
prefaceX.add(new Paragraph("Dummy Text", catFont));
prefaceX.add(new Paragraph("* Dummy Details ", smallBoldMM));
document.add(prefaceX);
Output PDF in Java Desktop
Font (catFont and smallBoldMM) are custom font and both are same as follow
private static Font catFont = new Font(Font.FontFamily.TIMES_ROMAN, 18,
Font.BOLD);
private static Font smallBoldMM = new Font(Font.FontFamily.TIMES_ROMAN, 7,
Font.ITALIC)
Please don't suggest to use tables.

I guess that the difference between your Android application and your Desktop application is the version of iText that is used.
You can get the same behavior by using Paragraph the way one would expect when talking about a paragraph.
Paragraph prefaceX = new Paragraph();
prefaceX.setAlignment(Element.ALIGN_CENTER);
document.add(prefaceX);
document.add(Chunk.NEWLINE);
document.add(new Paragraph(getString(R.string.report_title), catFont));
document.add(new Paragraph(getString(R.string.disclaimer), smallBoldMM));
There is no reason why you'd want to put all the different Paragraph objects into one big Paragraph.
If you take a look at iText 7 (but you're using iText 5 or earlier), you'll notice that we make a distinction between the Paragraphobject (single paragraphs) and the Div object (that can contain several Paragraph and other objects).

Related

itext pdf change default font size in Paragraph not working

while using itext5 in android to display pdf from XHTML am trying to change the font size but it's not reflecting.
I would like to know the substitutes(or hack) for CSS as itext5 is not supporting CSS.
preparedText = output.toString("UTF-8");
list = XMLWorkerHelper.parseToElementList(preparedText, null);
// URL path =Thread.currentThread().getContextClassLoader().getResource("fontname");
// FontFactory.register(path.toString(), "test_font");
Font titleFont = FontFactory.getFont(FontFactory.HELVETICA_BOLD,7f);
paragraph.setFont(titleFont);
paragraph.addAll(list);
publishProgress(88);
// write to document
document.open();
document.newPage();
Paragraph p= new Paragraph(paragraph);
p.setFont(titleFont);
document.add(p);
document.close();
The font you set in a paragraph applies to all text added to the paragraph afterwards, it does not change the previously added text. To set the font of the text you add to a paragraph in the constructor, there is a constructor that also accepts a font parameter.
Thus, instead of
Paragraph p= new Paragraph(paragraph);
p.setFont(titleFont);
use
Paragraph p = new Paragraph(paragraphText, titleFont);
or
Paragraph p = new Paragraph();
p.setFont(titleFont);
p.add(paragraphText);

Why is the Gujarati-Indian text not rendered correctly using Arial Unicode MS?

This is a follow-up on this question How to export fonts in Gujarati-Indian Language to pdf?, #amedee-van-gasse, QA Engineer at iText asked me to post a question specific to itext with relevant mcve.
Why is this sequence of unicode \u0ab9\u0abf\u0aaa\u0acd\u0ab8 not rendered correctly?
It should be rendered like this:
હિપ્સ , also tested with unicode-converter
However this code (example adapted form iText: Chapter 11: Choosing the right font)
public class FontTest {
/** The resulting PDF file. */
public static final String RESULT = "fontTest.pdf";
/** the text to render. */
public static final String TEST = "\u0ab9\u0abf\u0aaa\u0acd\u0ab8";
public void createPdf(String filename) throws IOException, DocumentException {
Document document = new Document();
PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(filename));
document.open();
BaseFont bf = BaseFont.createFont(
"ARIALUNI.TTF", BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
Font font = new Font(bf, 20);
ColumnText column = new ColumnText(writer.getDirectContent());
column.setSimpleColumn(36, 730, 569, 36);
column.addElement(new Paragraph(TEST, font));
column.go();
document.close();
System.out.println("DONE");
}
public static void main(String[] args) throws IOException, DocumentException {
new FontTest().createPdf(RESULT);
}
}
Generates this result:
That looks different from
હિપ્સ
I have test with itextpdf-5.5.4.jar,itextpdf-5.5.9.jar and also itext-2.1.7.js3.jar (distributed with jasper-reports)
The font used it the one distributes with MS Office ARIALUNI.TTF and it can be download from here Arial Unicode MS *Maybe there are some legal issues downloading see Mike 'Pomax' Kamermans comment
Neither iText5 nor iText2 (which is a very outdated version by the way) support rendering of Indic scripts, no matter which font you select.
Rendering Indic scripts is not similar to any Latin scripts, because a long series of additional actions should be taken to get the correct result, e.g. some characters need to be reordered first according to the language rules.
This is a known issue to iText company.
There is a stub implementation for Gujaranti in iText5 called GujaratiLigaturizer, but the implementation is really poor and you cannot expect to get correct results with it.
You can try to process your string with this ligaturizer and then output the resultant string in the following way:
IndicLigaturizer g = new GujaratiLigaturizer();
String processed = g.process(inputString);
// proceed with the processed string
Build your application using latest typography jar file that
Will solve your problem of Gujarati font rendering in pdf
In itext.

Icepdf special character rendering issue

I use itext library for creating PDF file because has very detailed rendering functions for PDF creation. When user click the button i write a template and fill the blank cells from DB everytime.
Than i use Icepdf library for show to user and taking output of the created pdf file.
But Icepdf has some character encoding problem i think. When PDf created and callled by Icepdf one of Turkish character looks as square. Turkish characters can be seen at this link. All characters rendered succesfully but eighth character at the picture is not.
When i go to filepath of created pdf file (created by itext library) and open it manually with Adobe Acrobat Reader all characters showing correctly. But if programaticly Icepdf open the file and show to user, eighth character at the picture looks as square.
I need change character encoding of Icepdf but i can't yet. Reading many articles about character and Font encoding of Icepdf but i have not yet succeeded. If i solve this character problem my application ready to deploy.
The generated PDF file can be downloaded here.
When I open this file with Adobe Acrobat it looks like this:
When I open the file with IcePDF programaticly it looks like thi:
Also i read some questions and answers about this on Stackoverflow but none of them have an accepted answer/help.
Code used to create the file path:
File fUrl = new File(CreateAndViewPdf
.class
.getProtectionDomain()
.getCodeSource()
.getLocation()
.getPath()
);
String path = fUrl
.toString()
.substring(0,fUrl.toString().lastIndexOf(File.separator))
.replace("%20", " ") + "\\hello.pdf";
Code for the createPdf() method:
public void createPdf()throws DocumentException, IOException {
BaseFont bf = BaseFont.createFont(BaseFont.HELVETICA, "ISO-8859-9", BaseFont.EMBEDDED);
Document document = new Document(PageSize.A5);
PdfWriter.getInstance(document, new FileOutputStream(path));
document.setMargins(10, 10, 10, 10);
document.setMarginMirroring(true);
document.open();
Font font = new Font( bf );
PdfPCell cell;
PdfPTable table = new PdfPTable(2);
font = new Font( bf );
font.setSize(15);
font.setStyle("bold");
cell = new PdfPCell(new Phrase("Sender\n"+"Information", font));
cell.setPaddingBottom(7);
cell.setHorizontalAlignment(Element.ALIGN_CENTER);
cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
table.addCell(cell);
font = new Font( bf );
font.setSize(12);
font.setStyle("normal");
cell = new PdfPCell(new Phrase("â ç ğ ı İ î ö ş ü û\n\n"+"Â Ç Ğ I İ Î Ö Ş Ü Û",font));
cell.setPaddingBottom(7);
cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
cell.setHorizontalAlignment(Element.ALIGN_CENTER);
table.addCell(cell);
table.setWidths(new int[]{50,200});
table.setWidthPercentage(100);
table.setSpacingAfter(10);
table.setSpacingBefore(10);
document.add(table);
document.close();
}
Code for the viewPdf() method:
public void viewPdf(String fileP)throws IOException, InterruptedException {
String filePath = fileP;
SwingController controller = new SwingController();
SwingViewBuilder factory = new SwingViewBuilder(controller);
JPanel viewerComponentPanel = factory.buildViewerPanel();
controller.getDocumentViewController().setAnnotationCallback(
new org.icepdf.ri.common.MyAnnotationCallback(
controller.getDocumentViewController()));
Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
CreateAndViewPdf.this.getContentPane().add(viewerComponentPanel);
CreateAndViewPdf.this.setSize(new Dimension(screen.width/2,screen.height));
CreateAndViewPdf.this.setLocationRelativeTo(null);
controller.openDocument(filePath);
}
--- SOLVED ---
Firstly, thanks for the router comment to #Mike 'Pomax' Kamermans
After reading him/her comments begin investigating " how can i embed the spesific font file to PDF with iText " After 1-2 days later, i found solution just like below;
Going to Windows Control Panel\Appearance and Personalization\Fonts and copy the times.ttf (which tested all special characters supported font) file to my Java Application resources container.
Than i add below lines to top of my createPDF method.
Font fontBase = FontFactory.getFont("/resources/times.ttf",
BaseFont.IDENTITY_H,
BaseFont.EMBEDDED,
0.8f, Font.NORMAL,
BaseColor.BLACK);
BaseFont bf = fontBase.getBaseFont();
After this, viewPdf() method get the document to screen with all special characters truely rendering.

iText Android - Adding text to existing PDF

we have a PDF with some fields in order to collect some data, and I have to fill it programmatically with iText on Android by adding some text in those positions. I've been thinking about different ways to achieve this, with little success in each one.
Note: I'm using the Android version of iText (iTextG 5.5.4) and a Samsung Galaxy Note 10.1 2014 (Android 4.4) for most of my tests.
The approach I took from the start was to "draw" the text on a given coordinates, for a given page. This has some problems with the management of the fields (I have to be aware of the length of the strings, and it could be hard to position each text in the exact coordinate of the pdf). But most importantly, the performance of the process is really slow in some devices/OSVersions (it works great in Nexus 5 with 5.0.2, but takes several minutes with a 5MB Pdf on the Note 10.1).
pdfReader = new PdfReader(is);
document = new Document();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
pdfCopy = new PdfCopy(document, baos);
document.open();
PdfImportedPage page;
PdfCopy.PageStamp stamp;
for (int i = 1; i <= pdfReader.getNumberOfPages(); i++) {
page = pdfCopy.getImportedPage(pdfReader, i); // First page = 1
stamp = pdfCopy.createPageStamp(page);
for (int i=0; i<10; i++) {
int posX = i*50;
int posY = i*100;
Phrase phrase = new Phrase("Example text", FontFactory.getFont(FontFactory.HELVETICA, 12, BaseColor.RED));
ColumnText.showTextAligned(stamp.getOverContent(), Element.ALIGN_CENTER, phrase, posX, posY, 0);
}
stamp.alterContents();
pdfCopy.addPage(page);
}
We though about adding "forms fields" instead of drawing. That way I can configure a TextField and avoid managing the texts myself. However, the final PDF shouldn't have any annotations, so I would need to copy it into a new Pdf without annotations and with those "forms fields" drawn. I don't have an example of this because I wasn't able to perform this, I don't even know if this is possible/worthwhile.
The third option would be to receive a Pdf with the "forms fields" already added, that way I only have to fill them. However I still need to create a new Pdf with all those fields and without annotations...
I'd like to know what's be the best way in performance to do this process, and any help about achieving it. I am really newbie with iText and any help would be really appreciated.
Thanks!
EDIT
At the end I used the third option: a PDF with editable fields that we fill, and then we use the "flattening" to create a non-editable PDF with all texts already there.
The code is as follows:
pdfReader = new PdfReader(is);
FileOutputStream fios = new FileOutputStream(outPdf);
PdfStamper pdfStamper = new PdfStamper(pdfReader, fios);
//Filling the PDF (It's totally necessary that the PDF has Form fields)
fillPDF(pdfStamper);
//Setting the PDF to uneditable format
pdfStamper.setFormFlattening(true);
pdfStamper.close();
and the method to fill the forms:
public static void fillPDF(PdfStamper stamper) throws IOException, DocumentException{
//Getting the Form fields from the PDF
AcroFields form = stamper.getAcroFields();
Set<String> fields = form.getFields().keySet();
for(String field : fields){
form.setField("name", "Ernesto");
form.setField("surname", "Lage");
}
}
}
The only thing about this approach is that you need to know the name of each field in order to fill it.
There is a process in iText known as 'flattening', which takes the form fields, and replaces them with the text that the fields contain.
I haven't used iText in a few years (and not at all on Android), but if you search the manual or online examples for 'flattening', you should find how to do it.

PdfPcell empty output of Arabic strings

I have that part of code:
//Staff
// Title font
BaseFont titleBf = null;
try {
titleBf = BaseFont.createFont(BaseFont.TIMES_ROMAN,BaseFont.CP1252, BaseFont.EMBEDDED);
} catch (IOException e) {
System.out.println(e.getMessage());
}
com.itextpdf.text.Font titleFont = new com.itextpdf.text.Font(titleBf,24);
titleFont.setColor(new BaseColor(0, 0, 204));
/*
* Pdf creation
*/
Document document = new Document();
PdfWriter.getInstance(document,new FileOutputStream(fc.getSelectedFile() + ".pdf"));
document.open();
/*
* Title
*/
Paragraph p = new Paragraph("مرحبا بكم",titleFont);
p.setSpacingAfter(20);
p.setAlignment(1); // Center
document.add(p);
//Staff
document.close();
The output was empty.
Even when I tried to add simple pdfpcell, I got same result, here is the way:
com.itextpdf.text.Font fontNormal = FontFactory.getFont(
("arialuni.ttf"), BaseFont.CP1252, BaseFont.EMBEDDED,
8, com.itextpdf.text.Font.NORMAL);
Chunk chunkArabic = new Chunk("مرحبا العالم", fontNormal);
infoTab.addCell(new PdfPCell(new Phrase(chunkArabic)));
document.add(infoTab);
Different problems may be at play.
Encoding: You are putting Arabic text in your source code. If you save your Java file using the wrong encoding, that text will become corrupt. If you compile your Java file using the wrong encoding, that text will become corrupt. And so on. I hope you get the idea. Store literal text like this: "\u0644\u0648\u0631\u0627\u0646\u0633 \u0627\u0644\u0639\u0631\u0628" to avoid problems like this.
As documented in Chapter 11 of my book, right-to-left writing and Arabic ligatures are only supported in the context of PdfPCell and ColumnText. I see that you're using PdfPCell, but I don't see you using cell.setRunDirection(PdfWriter.RUN_DIRECTION_RTL); anywhere. That's wrong.
You are using an object fontNormal, but you're not telling us which font you're actually using. For instance: if you're using the standard Type1 font Helvetica, no text will show up, because Helvetica doesn't know how to render Arabic text.
Amendment: You've now updated your question, showing that you're using "arialuni.ttf". However, you are using the wrong encoding: CP1252 is the encoding for the Latin Alphabet. You should use BaseFont.IDENTITY_H.
Update: looking at the update of your question as well as the extra comment, I see two major errors.
You are assuming that the name of the font is "arialuni.ttf". That's the font file, but not the font name. Also: you are asking the FontFactory for this font, but did you tell the FontFactory where to look for fonts? Are you sure the FontFactory can locate c:/windows/fonts/ or whatever directory the file arialuni.ttf is stored.
You are declaring a font, but you're not using it: Paragraph p = new Paragraph("\u062D\u064A\u0633\u0648"); creates a Paragraph using the default font.
This is code that works:
BaseFont bf = BaseFont.createFont(
"c://windows/fonts/arialuni.ttf", BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
Font font = new Font(bf, 8);
PdfPTable table = new PdfPTable(1);
PdfPCell cell = new PdfPCell(new Phrase("\u062D\u064A\u0633\u0648", font));
cell.setRunDirection(PdfWriter.RUN_DIRECTION_RTL);
table.addCell(cell);
document.add(table);
The result looks like this (zoomed in):

Categories

Resources