My application parses html and put the content in pdf, now it needs to support multiple fonts ex: Myanmar and Chinese.
I am able to do this with phrases but not with html even for single font family
Working Code
Document document = new Document();
PdfWriter.getInstance(document, new FileOutputStream("/home/a2.pdf"));
Font font = FontFactory.getFont("KozMinPro-Regular", "UniJIS-UCS2-H", false);
Font font1 = FontFactory.getFont("/home/mm3.ttf", BaseFont.IDENTITY_H, false);
FontSelector fs = new FontSelector();
fs.addFont(font);
fs.addFont(font1);
Phrase phrase = fs.process("長");
phrase.add(fs.process("၀န္ထမ္းလစလႊာ( လ )"));
phrase.add(fs.process("123aab"));
document.open();
document.add(phrase);
document.close();
Tried with XMLWorker but it didn't work:
final MyFontFactory fontFactory = new MyFontFactory();
FontFactory.register("/home/Downloads/mm3.ttf");
FontFactory.setFontImp(fontFactory);
final HtmlPipelineContext htmlContext = new HtmlPipelineContext(new CssAppliersImpl(fontFactory));
final CSSResolver cssResolver = XMLWorkerHelper.getInstance().getDefaultCssResolver(true);
Document document = new Document();
PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream("/home/a2.pdf"));
document.open();
String str="<span style=\"font-family: "Open Sans", sans-serif; white-space: pre-wrap; background-color: rgb(255, 255, 255);\">Deduc၀န္ထမ္းလစာေပးေခ်လႊာ( လစာငွေ )tions哈罗</span> ";
XMLWorkerHelper worker = XMLWorkerHelper.getInstance();
InputStream is = new ByteArrayInputStream(str.getBytes(StandardCharsets.UTF_8));
worker.parseXHtml(writer, document, is, Charset.forName("UTF-8"));
// step 5
document.close();
Related
I created a PDF file in Java using OpenPDF and inserted a paragraph. The problem is that I want to place it in the middle, not on the left. How can this be done?
Second question: How can I place a word with specific formatting in the test?
For example: "Hello and welcome" (welcome should be bold)
This is my code:
Document document = new Document();
String PDFPath = "output.pdf";
PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(PDFPath));
Font font_bold = new Font(Font.TIMES_ROMAN, 16, Font.BOLD, Color.BLACK);
Font font_normal = new Font(Font.TIMES_ROMAN, 15, Font.NORMAL, Color.BLACK);
Paragraph p1 = new Paragraph("Ordonnance", font_bold);
document.open();
document.add(p1);
document.close();
You need to define the alignment if you want to have the paragraph centred:
p1.setAlignment(Element.ALIGN_CENTER);
To apply formatting to some parts of the text, you can divide it into several chunks. A Chunk in OpenPDF is a string with a certain Font. Instead of adding a String (unformatted) to the paragraph, you add a Chunk-object like new Chunk("Hello and ", fontNormal) which defines the text and the font to be used.
Here is the code for what you want to do according to the question:
Document document = new Document();
PdfWriter.getInstance(document, new FileOutputStream("output.pdf"));
document.open();
Font fontNormal = new Font(Font.TIMES_ROMAN, 15, Font.NORMAL);
Font fontBold = new Font(Font.TIMES_ROMAN, 16, Font.BOLD);
Paragraph p1 = new Paragraph();
p1.setAlignment(Element.ALIGN_CENTER);
p1.add(new Chunk("Hello and ", fontNormal));
p1.add(new Chunk("welcome", fontBold));
document.add(p1);
document.close();
The result looks like this:
Your first line had some weird declaration, but this should work:
Document document = new Document();
String PDFPath = "D:\\test.pdf";
PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(PDFPath));
Font font_bold = new Font(Font.TIMES_ROMAN, 16, Font.BOLD, Color.BLACK);
Font font_normal = new Font(Font.TIMES_ROMAN, 15, Font.NORMAL, Color.BLACK);
Paragraph p1 = new Paragraph("Ordonnance", font_bold);
p1.setAlignment(Element.ALIGN_CENTER);
document.open();
document.add(p1);
document.close();
You just have to set the alignment of the paragraph
I am having trouble to display the Arabic Characters from HTML Content in PDF Generation as "?"
I am able to display the Arabic text from String variable. At the same time I am not able to generate the Arabic Text from the HTML String.
I want to display the PDF with two column, left side English and the right side Arabic Text.
when I use the following program to convert into pdf. Please help me in this regard.
try
{
Document document = new Document(PageSize.A4, 50, 50, 50, 50);
ByteArrayOutputStream out = new ByteArrayOutputStream();
PdfWriter writer = PdfWriter.getInstance(document, out);
BaseFont bf = BaseFont.createFont("C:\\arial.ttf", BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
Font font = new Font(bf, 8);
document.open();
BufferedReader br = new BufferedReader(new FileReader("C:\\style.css"));
StringBuffer fileContents = new StringBuffer();
String line = br.readLine();
while (line != null)
{
fileContents.append(line);
line = br.readLine();
}
br.close();
String styles = fileContents.toString(); //"p { font-family: Arial;}";
Paragraph cirNoEn = null;
Paragraph cirNoAr = null;
String htmlContentEn = null;
String htmlContentAr = null;
PdfPCell contentEnCell = new PdfPCell();
PdfPCell contentArCell = new PdfPCell();
cirNoEn = new Paragraph("Circular No. (" + cirEnNo + ")", new Font(bf, 14, Font.BOLD | Font.UNDERLINE));
cirNoAr = new Paragraph("رقم التعميم (" + cirArNo + ")", new Font(bf, 14, Font.BOLD | Font.UNDERLINE));
htmlContentEn = “< p >< span > Dear….</ span ></ p >”;
htmlContentAr = “< p >< span > رقم التعميم رقم التعميم </ p >< p > رقم التعميم ….</ span ></ p >”;
for (Element e : XMLWorkerHelper.parseToElementList(htmlContentEn, styles))
{
for (Chunk c : e.getChunks())
{
c.setFont(new Font(bf));
}
contentEnCell.addElement(e);
}
for (Element e : XMLWorkerHelper.parseToElementList(htmlContentAr, styles))
{
for (Chunk c:e.getChunks())
{
c.setFont(new Font(bf));
}
contentArCell.addElement(e);
}
PdfPCell emptyCell = new PdfPCell();
PdfPCell cirNoEnCell = new PdfPCell(cirNoEn);
PdfPCell cirNoArCell = new PdfPCell(cirNoAr);
cirNoEnCell.setHorizontalAlignment(Element.ALIGN_CENTER);
cirNoArCell.setHorizontalAlignment(Element.ALIGN_CENTER);
emptyCell.setBorder(Rectangle.NO_BORDER);
emptyCell.setFixedHeight(15);
cirNoEnCell.setBorder(Rectangle.NO_BORDER);
cirNoArCell.setBorder(Rectangle.NO_BORDER);
contentEnCell.setBorder(Rectangle.NO_BORDER);
contentArCell.setBorder(Rectangle.NO_BORDER);
cirNoArCell.setRunDirection(PdfWriter.RUN_DIRECTION_RTL);
contentArCell.setRunDirection(PdfWriter.RUN_DIRECTION_RTL);
contentEnCell.setNoWrap(false);
contentArCell.setNoWrap(false);
PdfPTable circularInfoTable = null;
emptyCell.setColspan(2);
circularInfoTable = new PdfPTable(2);
circularInfoTable.addCell(cirNoEnCell);
circularInfoTable.addCell(cirNoArCell);
circularInfoTable.addCell(emptyCell);
circularInfoTable.addCell(emptyCell);
circularInfoTable.addCell(emptyCell);
circularInfoTable.addCell(contentEnCell);
circularInfoTable.addCell(contentArCell);
circularInfoTable.addCell(emptyCell);
circularInfoTable.getDefaultCell().setBorder(PdfPCell.NO_BORDER);
circularInfoTable.setWidthPercentage(100);
document.add(circularInfoTable);
document.close();
}
catch (Exception e)
{
}
Please take a look at the ParseHtml7 and ParseHtml8 examples. They take HTML input with Arabic characters and they create a PDF with the same Arabic text:
Before we look at the code, allow me to explain that it's not a good idea to use non-ASCII characters in source code. For instance: this is not done:
htmlContentAr = “<p><span> رقم التعميم رقم التعميم</p><p>رقم التعميم ….</span></p>”;
You never know how a Java file containing these glyphs will be stored. If it's not stored as UTF-8, the characters may end up looking like something completely different. Versioning systems are known to have problems with non-ASCII characters and even compilers can get the encoding wrong. If you really want to stored hard-coded String values in your code, use the UNICODE notation. Part of your problem is an encoding problem, and you can read more about this here: Can't get Czech characters while generating a PDF
For the examples shown in the screen shots, I saved the following files using UTF-8 encoding:
This is what you'll find in the file arabic.html:
<html>
<body style="font-family: Noto Naskh Arabic">
<p>رقم التعميم رقم التعميم</p>
<p>رقم التعميم</p>
</body>
</html>
This is what you'll find in the file arabic2.html:
<html>
<body style="font-family: Noto Naskh Arabic">
<table>
<tr>
<td dir="rtl">رقم التعميم رقم التعميم</td>
<td dir="rtl">رقم التعميم</td>
</tr>
</table>
</body>
</html>
The second part of your problem concerns the font. It is important that you use a font that knows how to draw Arabic glyphs. It is hard to believe that you have arial.ttf right at the root of your C: drive. That's not a good idea. I would expect you to use C:/windows/fonts/arialuni.ttf which certainly knows Arabic glyphs.
Selecting the font isn't sufficient. Your HTML needs to know which font family to use. Because most of the examples in the documentation use Arial, I decided to use a NOTO font. I discovered these fonts by reading this question: iText pdf not displaying Chinese characters when using NOTO fonts or Source Hans. I really like these fonts because they are nice and (almost) every language is supported. For instance, I used NotoNaskhArabic-Regular.ttf which means that I need to define the font familie like this:
style="font-family: Noto Naskh Arabic"
I defined the style in the body tag of my XML, it's obvious that you can choose where to define it: in an external CSS file, in the styles section of the <head>, at the level of a <td> tag,... That choice is entirely yours, but you have to define somewhere which font to use.
Of course: when XML Worker encounters font-family: Noto Naskh Arabic, iText doesn't know where to find the corresponding NotoNaskhArabic-Regular.ttf unless we register that font. We can do this, by creating an instance of the FontProvider interface. I chose to use the XMLWorkerFontProvider, but you're free to write your own FontProvider implementation:
XMLWorkerFontProvider fontProvider = new XMLWorkerFontProvider(XMLWorkerFontProvider.DONTLOOKFORFONTS);
fontProvider.register("resources/fonts/NotoNaskhArabic-Regular.ttf");
There is one more hurdle to take: Arabic is written from right to left. I see that you want to define the run direction at the level of the PdfPCell and that you add the HTML content to this cell using an ElementList. That's why I first wrote a similar example, named ParseHtml7:
public void createPdf(String file) throws IOException, DocumentException {
// step 1
Document document = new Document();
// step 2
PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(file));
// step 3
document.open();
// step 4
// Styles
CSSResolver cssResolver = new StyleAttrCSSResolver();
XMLWorkerFontProvider fontProvider = new XMLWorkerFontProvider(XMLWorkerFontProvider.DONTLOOKFORFONTS);
fontProvider.register("resources/fonts/NotoNaskhArabic-Regular.ttf");
CssAppliers cssAppliers = new CssAppliersImpl(fontProvider);
// HTML
HtmlPipelineContext htmlContext = new HtmlPipelineContext(cssAppliers);
htmlContext.setTagFactory(Tags.getHtmlTagProcessorFactory());
// Pipelines
ElementList elements = new ElementList();
ElementHandlerPipeline pdf = new ElementHandlerPipeline(elements, null);
HtmlPipeline html = new HtmlPipeline(htmlContext, pdf);
CssResolverPipeline css = new CssResolverPipeline(cssResolver, html);
// XML Worker
XMLWorker worker = new XMLWorker(css, true);
XMLParser p = new XMLParser(worker);
p.parse(new FileInputStream(HTML), Charset.forName("UTF-8"));
PdfPTable table = new PdfPTable(1);
PdfPCell cell = new PdfPCell();
cell.setRunDirection(PdfWriter.RUN_DIRECTION_RTL);
for (Element e : elements) {
cell.addElement(e);
}
table.addCell(cell);
document.add(table);
// step 5
document.close();
}
There is no table in the HTML, but we create our own PdfPTable, we add the content from the HTML to a PdfPCell with run direction LTR, and we add this cell to the table, and the table to the document.
Maybe that's your actual requirement, but why would you do this in such a convoluted way? If you need a table, why don't you create that table in HTML and define some cells are RTL like this:
<td dir="rtl">...</td>
That way, you don't have to create an ElementList, you can just parse the HTML to PDF as is done in the ParseHtml8 example:
public void createPdf(String file) throws IOException, DocumentException {
// step 1
Document document = new Document();
// step 2
PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(file));
// step 3
document.open();
// step 4
// Styles
CSSResolver cssResolver = new StyleAttrCSSResolver();
XMLWorkerFontProvider fontProvider = new XMLWorkerFontProvider(XMLWorkerFontProvider.DONTLOOKFORFONTS);
fontProvider.register("resources/fonts/NotoNaskhArabic-Regular.ttf");
CssAppliers cssAppliers = new CssAppliersImpl(fontProvider);
HtmlPipelineContext htmlContext = new HtmlPipelineContext(cssAppliers);
htmlContext.setTagFactory(Tags.getHtmlTagProcessorFactory());
// Pipelines
PdfWriterPipeline pdf = new PdfWriterPipeline(document, writer);
HtmlPipeline html = new HtmlPipeline(htmlContext, pdf);
CssResolverPipeline css = new CssResolverPipeline(cssResolver, html);
// XML Worker
XMLWorker worker = new XMLWorker(css, true);
XMLParser p = new XMLParser(worker);
p.parse(new FileInputStream(HTML), Charset.forName("UTF-8"));;
// step 5
document.close();
}
There is less code needed in this example, and when you want to change the layout, it's sufficient to change the HTML. You don't need to change your Java code.
One more example: in ParseHtml9, I create a table with an English name in one column ("Lawrence of Arabia") and the Arabic translation in the other column ("لورانس العرب"). Because I need different fonts for English and Arabic, I define the font at the <td> level:
<table>
<tr>
<td>Lawrence of Arabia</td>
<td dir="rtl" style="font-family: Noto Naskh Arabic">لورانس العرب</td>
</tr>
</table>
For the first column, the default font is used and no special settings are needed to write from left to right. For the second column, I define an Arabic font and I set the run direction to "rtl".
The result looks like this:
That's much easier than what you're trying to do in your code.
I am trying to convert html file into pdf using iText lib(4.2.0). But the problem is it's not printing all the html content to pdf, its only partially printing some data. Here is the code to convert html to pdf.
InputStream il = new FileInputStream("/tmp/test.html");
// step 1
Document document = new Document();
// step 2
PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream("/tmp/pdf.pdf"));
writer.setInitialLeading(12.5f);
// step 3
document.open();
HtmlPipelineContext htmlContext = new HtmlPipelineContext(null);
htmlContext.setTagFactory(Tags.getHtmlTagProcessorFactory());
// CSS
CSSResolver cssResolver = new StyleAttrCSSResolver();
InputStream csspathtest =new FileInputStream("/tmp/test.css");
CssFile cssfiletest = XMLWorkerHelper.getCSS(csspathtest);
cssResolver.addCss(cssfiletest);
Pipeline<?> pipeline = new CssResolverPipeline(cssResolver,
new HtmlPipeline(htmlContext,
new PdfWriterPipeline(
document, writer)));
XMLWorker worker = new XMLWorker(pipeline, true);
XMLParser p = new XMLParser(worker);
p.parse(il);
// step
document.close();
Here is the sample html file http://codepaste.net/65kmhp
I m running this code block to convert html page to pdf document.But I did not see Turkish characters on 'result.pdf'.My work is:
try {
Rectangle pagesize = new Rectangle(800,1200);
final Document document = new Document(pagesize);
OutputStream os = new FileOutputStream("deneme.pdf");// ByteArrayOutputStream();
PdfWriter writer = PdfWriter.getInstance(document,os);
document.open();
HtmlCleaner cleaner = new HtmlCleaner();
CleanerProperties props = cleaner.getProperties();
TagNode rootNode = cleaner.clean("Source Html");
XmlSerializer serial = new PrettyXmlSerializer(props);
String htmlClean = serial.getAsString(rootNode);
System.out.println(htmlClean);//Tidy Html
CSSResolver cssResolver = XMLWorkerHelper.getInstance().getDefaultCssResolver(true);
/*
XMLWorkerFontProvider fontProvider = new XMLWorkerFontProvider();
// fontProvider.setUseUnicode(true);
fontProvider.isRegistered("Helvetica");
fontProvider.addFontSubstitute("Helvetica", "Arial");
CssAppliers cssAppliers = new CssAppliersImpl(fontProvider);
*/
// HTML
HtmlPipelineContext htmlContext = new HtmlPipelineContext(null);
htmlContext.setTagFactory(Tags.getHtmlTagProcessorFactory());
htmlContext.setImageProvider(new ImageProvider());
PdfWriterPipeline pdf = new PdfWriterPipeline(document, writer);
HtmlPipeline html = new HtmlPipeline(htmlContext, pdf);
CssResolverPipeline css = new CssResolverPipeline(cssResolver, html);
/*
BaseFont courier = BaseFont.createFont(BaseFont.HELVETICA, BaseFont.CP1252, BaseFont.EMBEDDED);
Font font = new Font(courier, 12, Font.NORMAL);
Chunk chunk = new Chunk("",font);
document.add(chunk);
*/
// XML Worker
XMLWorker worker = new XMLWorker(css, true);
XMLParser p = new XMLParser(worker);
p.parse(new ByteArrayInputStream(htmlClean.getBytes("utf-8")));
document.close();
} catch (Exception e) {
e.printStackTrace();
}
I tried codes in comment lines but result is same,wrong.
How can I change result with Turkish Characters??
when I tried that code block
BaseFont freeSans = BaseFont.createFont("FreeSans.ttf","Cp1254", true);
Font font = new Font(freeSans,12, Font.NORMAL);
Chunk chunk = new Chunk("ŞşĞğİıÖö",font);
document.add(chunk);
I saw 'ŞşĞğİıÖö' in 'result.pdf'
But how can I edit XmlParser before parsing ??
I have java code that writes arabic characters with the help of itext 5.5 and xmlworker jars, but its writing left to right even after writer.setRunDirection(PdfWriter.RUN_DIRECTION_RTL) is used.
Code used is:
public class CreateArabic extends DefaultHandler {
/** Paths to and encodings of fonts we're going to use in this example */
public static String[][] FONTS = {
{"C:/arialuni.ttf", BaseFont.IDENTITY_H},
{"C:/abserif4_5.ttf", BaseFont.IDENTITY_H},
{"C:/damase.ttf", BaseFont.IDENTITY_H},
{"C:/fsex2p00_public.ttf", BaseFont.IDENTITY_H}
};
/** Holds he fonts that can be used for the peace message. */
public FontSelector fs;
public CreateArabic() {
fs = new FontSelector();
for (int i = 0; i < FONTS.length; i++) {
fs.addFont(FontFactory.getFont(FONTS[i][0], FONTS[i][1], BaseFont.EMBEDDED));
}
}
public static void main(String args[]) {
try {
// step 1
Rectangle pagesize = new Rectangle(8.5f * 72, 11 * 72);
Document document = new Document();//pagesize, 72, 72, 72, 72);// step1
PdfWriter writer = PdfWriter.getInstance(document,
new FileOutputStream("c:\\report.pdf"));
writer.setInitialLeading(200.5f);
//writer.getAcroForm().setNeedAppearances(true);
//writer.setRunDirection(PdfWriter.RUN_DIRECTION_RTL);
document.open();
FontFactory.registerDirectories();
Font font = FontFactory.getFont("C:\\damase.ttf",
BaseFont.IDENTITY_H, true, 22, Font.BOLD);
// step 3
document.open();
// step 4
XMLWorkerHelper helper = XMLWorkerHelper.getInstance();
// CSS
CSSResolver cssResolver = new StyleAttrCSSResolver();
CssFile cssFile = helper.getCSS(new FileInputStream(
"D:\\Itext_Test\\Test\\src\\test.css"));
cssResolver.addCss(cssFile);
// HTML
XMLWorkerFontProvider fontProvider = new XMLWorkerFontProvider();
// fontProvider.addFontSubstitute("lowagie", "garamond");
CssAppliers cssAppliers = new CssAppliersImpl(fontProvider);
HtmlPipelineContext htmlContext = new HtmlPipelineContext(
cssAppliers);
htmlContext.setTagFactory(Tags.getHtmlTagProcessorFactory());
// // Pipelines
PdfWriterPipeline pdf = new PdfWriterPipeline(document, writer);
HtmlPipeline html = new HtmlPipeline(htmlContext, pdf);
CssResolverPipeline css = new CssResolverPipeline(cssResolver,
html);
writer.setRunDirection(PdfWriter.RUN_DIRECTION_RTL);
System.out.println("RUN DIRECTION --> "+writer.getRunDirection());
XMLWorker worker = new XMLWorker(css, true);
XMLParser p = new XMLParser(worker,Charset.forName("UTF-8"));
String htmlString2 = "<html><body style=\"color:red;\">Hello"+"??"+"</body></html>";
String htmlString = "<body style='font-family:arial;'>h"+"??"+"<p style='font-family:arial;' > ????? </p></body>";
String html1 ="<html><head></head><body>Hello <p style=\"color:red\" >oo ??</p> World! \u062a\u0639\u0637\u064a \u064a\u0648\u0646\u064a\u0643\u0648\u062f \u0631\u0642\u0645\u0627 \u0641\u0631\u064a\u062f\u0627 \u0644\u0643\u0644 \u062d\u0631\u0641 "+htmlString+"Testing</body></html>";
ByteArrayInputStream is = new ByteArrayInputStream(htmlString.getBytes("UTF-8"));
p.detectEncoding(is);
p.parse(is, Charset.forName("UTF-8"));//.parse(is, "UTF-8");//parse(is);//ASMO-708
// step 5
document.close();
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
Output file is also attached.
As documented, this is not supposed to work:
writer.setRunDirection(PdfWriter.RUN_DIRECTION_RTL);
Arabic (and Hebrew) can only be rendered correctly in the context of ColumnText and PdfPCell. In other words: if you want to use Arabic from XML Worker, you need to create an ElementList and then add the elments to a ColumnText object as is done here.
You need to set the run direction at the level of the ColumnText object.
//This solution works for me: :)
// document
Document document = new Document(PageSize.LEGAL);
//fonts
XMLWorkerFontProvider fontProvider = new XMLWorkerFontProvider(XMLWorkerFontProvider.DONTLOOKFORFONTS);
fontProvider.register("/Users/ibrahimbakhsh/Library/Fonts/tradbdo.ttf", BaseFont.IDENTITY_H);
fontProvider.register("/Users/ibrahimbakhsh/Library/Fonts/trado.otf", BaseFont.IDENTITY_H);
fontProvider.register("/Users/ibrahimbakhsh/Library/Fonts/tahoma.ttf", BaseFont.IDENTITY_H);
CssAppliers cssAppliers = new CssAppliersImpl(fontProvider);
HtmlPipelineContext htmlContext = new HtmlPipelineContext(cssAppliers);
htmlContext.setTagFactory(Tags.getHtmlTagProcessorFactory());
// CSS
CSSResolver cssResolver =
XMLWorkerHelper.getInstance().getDefaultCssResolver(true);
// Pipelines
ElementList elements = new ElementList();
ElementHandlerPipeline end = new ElementHandlerPipeline(elements, null);
HtmlPipeline html = new HtmlPipeline(htmlContext, end);
CssResolverPipeline css = new CssResolverPipeline(cssResolver, html);
// HTML
htmlContext.setTagFactory(Tags.getHtmlTagProcessorFactory());
htmlContext.autoBookmark(false);
// XML Worker
XMLWorker worker = new XMLWorker(css, true);
XMLParser p = new XMLParser(worker);
p.parse(new FileInputStream(HTML));
//writer
PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(file));
writer.setInitialLeading(12.5f);
writer.setRunDirection(PdfWriter.RUN_DIRECTION_RTL);
// step 4
document.open();
// step 5
for (Element e : elements) {
//out.println(e.toString());
if(e instanceof PdfPTable){
PdfPTable t = (PdfPTable) e;
t.setRunDirection(PdfWriter.RUN_DIRECTION_RTL);
ArrayList<PdfPRow> rows = t.getRows();
for(PdfPRow row:rows){
PdfPCell[] cells = row.getCells();
for(PdfPCell cell:cells){
cell.setRunDirection(PdfWriter.RUN_DIRECTION_RTL);
}
}
e = t;
}
document.add(e);
}
//try adding new table
PdfPTable table = new PdfPTable(1);
table.setRunDirection(PdfWriter.RUN_DIRECTION_RTL);
Font f = new Font(BaseFont.createFont("/Users/ibrahimbakhsh/Library/Fonts/trado.otf", BaseFont.IDENTITY_H, BaseFont.EMBEDDED));
PdfPCell cell = new PdfPCell(new Paragraph("تجربة نص عربي",f));
table.addCell(cell);
document.add(table);
// step 6
document.close();
For developers that need an straightforward solution
I used this trick and output is very clean and nice!
create a PDFPTable with 1 column
for every paragraph of your content, create a Paragraph object and set its alignment to Paragraph.ALIGN_JUSTIFIED (I don't know why but it causes to paragraph align to right of page!!!)
create a PDFPCell and remove its borders using setBorder(Rectangle.NO_BORDER) and add the paragraph to cell
add the cell to the table
here is a code sample to your convenience.
public void main(){
/*
* create and initiate document
* */
// repeat this for all your paragraphs
PdfPTable pTable = new PdfPTable(1);
Paragraph paragraph = getCellParagraph();
paragraph.add("your RTL content");
PdfPCell cell = getPdfPCellNoBorder(paragraph);
pTable.addCell(cell);
// after add all your content
document.add(pTable);
}
private Paragraph getCellParagraph() {
Paragraph paragraph = new Paragraph();
paragraph.setAlignment(Paragraph.ALIGN_JUSTIFIED);
// set other styles you need like custom font
return paragraph;
}
private PdfPCell getPdfPCellNoBorder(Paragraph paragraph) {
PdfPCell cell = new PdfPCell();
cell.setRunDirection(PdfWriter.RUN_DIRECTION_RTL);
cell.setPaddingBottom(8);
cell.setBorder(Rectangle.NO_BORDER);
cell.addElement(paragraph);
return cell;
}