Hi I'm trying to position a table to desired (x,y) location. While doing research, writeSelectedRows is used to position a table at a specific place.
However I'm trying, the table is stuck a (0, 0) position, I cannot change it. I'm stuck!
Could you please help me out try and figure how to position a table where I really would have wanted?
Here is the code:
public static void main(String[] args) {
Card card = new Card("Some Card");
Document d = new Document(PageSize.A4, 65f, 0, 0 , 0);
d.setMarginMirroringTopBottom(true);
float height = d.getPageSize().getHeight();
float width = d.getPageSize().getWidth();
try {
//initiation
PdfWriter writer = PdfWriter.getInstance(d, new FileOutputStream("HeaderTry4.pdf"));
d.open();
//initiation end
//logo
Image logo = Image.getInstance(card.logoPath);
logo.scaleToFit(card.dimensions.LOGO_WIDTH, card.dimensions.LOGO_HEIGHT);
logo.setAbsolutePosition(card.dimensions.LOGO_X, card.dimensions.LOGO_Y);
writer.getDirectContent().addImage(logo);
//logo end
//card
Image cardGraphic = Image.getInstance(card.cardPath);
cardGraphic.scaleToFit(card.dimensions.CARD_TYPE_WIDTH, card.dimensions.CARD_TYPE_HEIGHT);
cardGraphic.setAbsolutePosition(card.dimensions.CARD_TYPE_X, card.dimensions.CARD_TYPE_Y);
writer.getDirectContent().addImage(cardGraphic);
//card end
//Card info
PdfContentByte canvas = writer.getDirectContent();
PdfPTable cInfo = new PdfPTable(2);
cInfo.setTotalWidth(new float [] {124f, 80f});
cInfo.setLockedWidth(true);
cInfo.setHorizontalAlignment(Element.ALIGN_LEFT);
PdfPCell header = new PdfPCell(new Paragraph(card.summaryCardInfo.card_info_table_header[0], card.summaryCardInfo.headerFont));
header.setColspan(2);
header.setBorderWidth(0f);
header.setBorderWidthBottom(2f);
header.setBorderWidthTop(1f);
header.setPadding(4f);
header.setHorizontalAlignment(Element.ALIGN_LEFT);
PdfPCell clientNumberDescr = new PdfPCell(new Paragraph(card.summaryCardInfo.client_no[0], card.summaryCardInfo.valuesFont));
clientNumberDescr.setHorizontalAlignment(Element.ALIGN_LEFT);
clientNumberDescr.setBorderWidth(0f);
PdfPCell clientNumberValue = new PdfPCell(new Paragraph(card.summaryCardInfo.client_no[2] = "501988", card.summaryCardInfo.valuesFont));
clientNumberValue.setHorizontalAlignment(Element.ALIGN_LEFT);
clientNumberValue.setBorderWidth(0f);
cInfo.addCell(header);
cInfo.addCell(clientNumberDescr);
cInfo.addCell(clientNumberValue);
cInfo.writeSelectedRows(0, -1, 100, 100, writer.getDirectContent());
d.add(cInfo);
//Card info end
d.close();
writer.close();
}catch (Exception e){
e.printStackTrace();
}
}
Related
How to add an external link in PDF and redirect to the webpage.
.
.
.
example image describe below
On click on Goolge,user should redirect to webpage https://www.google.com
here is my code
private void createPDFiText() {
int margin = getResources().getDimensionPixelSize(R.dimen._5sdp);
Document document = new Document(PageSize.A4, margin, margin, margin, margin);
try {
PdfWriter.getInstance(document, getOutputStream());
document.open();
for (int i = 12; i <= 17; i++) {
Phrase phrase = new Phrase("Open ");
Phrase phrase1 = new Phrase(" on Click On it.");
Font anchorFont = new Font(Font.FontFamily.UNDEFINED, 25);
anchorFont.setColor(BaseColor.BLUE);
anchorFont.setStyle(Font.FontStyle.UNDERLINE.getValue());
Anchor anchor = new Anchor("Google", anchorFont);
anchor.setReference("www.google.com");
phrase.add(anchor);
phrase.add(phrase1);
document.add(phrase);
}
document.close();
} catch (DocumentException | IOException e) {
e.printStackTrace();
}
}
I am referring to this answer. Have a look. Modifying existing pdf file using iText 5.5.13.2 is complicated. But the referred solution is more easier.
iText 7 has handier way to modify existing pdf.
There are several other ways. Like PdfStamper etc.
From referred answer, add following code to make an anchor.
Phrase phrase = new Phrase("Open ");
Phrase phrase1 = new Phrase(" on Click On it.");
Font anchorFont = new Font(Font.FontFamily.UNDEFINED, 11);
anchorFont.setColor(BaseColor.BLUE);
anchorFont.setStyle(Font.FontStyle.UNDERLINE.getValue());
Anchor anchor = new Anchor("Google", anchorFont);
anchor.setReference("www.google.com");
phrase.add(anchor);
phrase.add(phrase1);
document.add(phrase);
Change the font and colors based on your needs.
Full code:
try {
PdfReader reader = new PdfReader("test.pdf"); //src pdf path (the pdf I need to modify)
Document document = new Document();
PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream("test2.pdf")); // destination pdf path
document.open();
PdfContentByte cb = writer.getDirectContent();
PdfImportedPage page = writer.getImportedPage(reader, 1);
document.newPage();
document.setPageSize(reader.getPageSize(1));
cb.addTemplate(page, 0, 0);
Phrase phrase = new Phrase("Open ");
Phrase phrase1 = new Phrase(" on Click On it.");
Font anchorFont = new Font(Font.FontFamily.UNDEFINED, 11);
anchorFont.setColor(BaseColor.BLUE);
anchorFont.setStyle(Font.FontStyle.UNDERLINE.getValue());
Anchor anchor = new Anchor("Google", anchorFont);
anchor.setReference("https://www.google.com");
phrase.add(anchor);
phrase.add(phrase1);
document.add(phrase);
document.close();
} catch (IOException e) {
e.printStackTrace();
} catch (DocumentException e) {
e.printStackTrace();
}
}
Hi I am trying to create an PDF using itextpdf.
It is working fine when tested locally.
But after aws deployment I am getting 406 Not Acceptable with java.io.IOException: The document has no pages excpetion.
Many answers are there but those are not related to deployment issues.
Do I need to check any network configuration or problem lies in the pdf generation code?
Following is my code implementation:
Please suggest some solution.
public byte[] createPdf(List<Participant> participantList) throws IOException,
DocumentException, com.google.zxing.WriterException {
Document document = new Document();
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
PdfWriter.getInstance(document, byteArrayOutputStream);
document.open();
document.add(createMainTable(participantList));
document.close();
return byteArrayOutputStream.toByteArray();
}
public static PdfPTable createMainTable(List<Participant> optionalParticipant) throws BadElementException,
IOException, com.google.zxing.WriterException {
PdfPTable table = new PdfPTable(2);
logger.info("Main Table was created");
for (int i = 0; i < optionalParticipant.size(); i++) {
PdfPCell cell1 = new PdfPCell();
cell1.setBorderWidth(0);
cell1.setPadding(10f);
cell1.addElement(createSubTable(optionalParticipant.get(i)));
table.addCell(cell1);
}
return table;
}
public static PdfPTable createSubTable(Participant participant) throws BadElementException,
IOException, com.google.zxing.WriterException {
BaseColor baseColor = new BaseColor(150, 150, 150);
PdfPTable table = new PdfPTable(2);
table.setWidthPercentage(100);
PdfPCell cell, cell1, cell2;
Font font = new Font();
font.setSize(10f);
font.setColor(BaseColor.WHITE);
String participantName = participant.getFirstName() + " " + participant.getLastName();
Chunk chunk = new Chunk(participantName, font);
Paragraph head = new Paragraph(" "+chunk);
head.setFont(font);
cell = new PdfPCell(head);
cell.setColspan(2);
cell.setBackgroundColor(baseColor);
cell.setPadding(2f);
table.addCell(cell);
String qrData = participant.getQrCodeData();
Image img = getQRCodeImage(qrData);
font = new Font();
font.setSize(5f);
chunk = new Chunk("\n" + "Event ID: " + participant.getEvent().getEventId() +
"\n\n" + "Unique ID: " + participant.getUniqueId() +
"\n\n" + "Email ID: " + participant.getEmail(), font);
Paragraph body = new Paragraph(chunk);
cell1 = new PdfPCell(body);
cell1.setBorderWidthRight(0);
cell1.setPadding(10f);
cell2 = new PdfPCell();
cell2.addElement(img);
cell2.setBorderWidthLeft(1);
cell2.setPadding(10f);
table.addCell(cell1);
table.addCell(cell2);
logger.info("Sub Table was created");
return table;
}
Please check participantList is not null and contains elements. You can use logger to print size of list before start using it.
logger.info("No of participants: "+participantList.size());
Also, Immediately after opening document, always add an empty chunk to document so that you can avoid this exception.
document.open();
document.add(new Chunk(""));
This problem has been choking me for quite some time now precisely more than a month now.i tried developing a small Javafx application and I used ITEXT 5.3 version and everything works just fine where i used icepdf for displaying the generated PDF in netbean.perfectly works fine in netbeans .But once I tried running the executable jar program outside netbean it does not generate the PDF.i tried packaging it using advanced installer and the pdf did not generate too.I tried some solutions with this pdf not generated by itext library from java application but it didn't help.
Every assistance would be truly appreciated
Here is my source code for the PDF generation:
#FXML
private void generatereportforresistance(ActionEvent event) throws IOException {
XYSeries powerSeries = new XYSeries("Power_Speed relation");
for (double i=0;i<getValue(13);i=i+0.01){
double p=getPower(i)*0.51444;
powerSeries.add(i, p);
}
XYDataset xyDataset = new XYSeriesCollection(powerSeries);
JFreeChart chart = ChartFactory.createXYLineChart(
"Effective Power V.S Speed", "Speed[knots]", "Power[KW]", xyDataset,
PlotOrientation.VERTICAL, true, true, true);
//Render the frame
ChartFrame chartFrame = new ChartFrame("Power V.S speed Charts", chart);
chartFrame.setIconImage(Toolkit.getDefaultToolkit().getImage("app_icon.png"));
//chartFrame.setVisible(true);
//chartFrame.setSize(800, 800);
StandardChartTheme st = (StandardChartTheme)org.jfree.chart.StandardChartTheme.createJFreeTheme();
st.setTitlePaint(Color.decode("#4572a7"));
st.setRangeGridlinePaint( Color.decode("#C0C0C0"));
st.setPlotBackgroundPaint( Color.white );
st.setChartBackgroundPaint( Color.white );
st.setGridBandPaint( Color.red );
st.setAxisLabelPaint( Color.decode("#666666") );
st.apply( chart );
double a_aa = r_a(getValue(14),getValue(13),getValue(17),getValue(2),getValue(18),getValue(0),getValue(3),getValue(8),getValue(7),getValue(9),getValue(10));
double b_bb=r_tr(getValue(13),getValue(14),getValue(11),getValue(2),getValue(10));
double c_cc=r_b(getValue(13),getValue(14),getValue(7),getValue(3),getValue(10),getValue(2),getValue(8),getValue(16));
double d_dd=r_w(getValue(13),getValue(14),getValue(7),getValue(5),getValue(11),getValue(3),getValue(18),getValue(10),getValue(6),getValue(17),getValue(0),getValue(9),getValue(2),getValue(8),getValue(16));
double e_ee=r_app(getValue(14),getValue(13),getValue(0),getValue(15),getValue(12));
double f_ff=r_f(getValue(14),getValue(13),getValue(0),getValue(15),getValue(2),getValue(10),getValue(17),getValue(7),getValue(18),getValue(9),getValue(6));
double totoal =f_ff+a_aa+b_bb+c_cc+d_dd+e_ee;
double p_e =totoal *getValue(13)*0.51444;
double p_s =p_e/getValue(19);
//double values of parameters para = new
double[] val = new double[9];
val[0]=a_aa; val[1]=b_bb; val[2]=c_cc; val[3]=d_dd; val[4]=e_ee; val[5]=f_ff; val[6]=totoal; val[7]=p_e; val[8]=p_s;
//string values of units and parameters namings
String [] para = new String[9];
para[0]="Model_Ship Correlation Resistance";para[1]="Additional Pressure Resisitance of immersed Transom";para[2]="Additional pressure resistance of bulbous bow near water surface";
para[3]="Wave Resistance";para[4]="Resistance due to Appendages";para[5]="Frictional resistance";para[6]="Total resistance";
para[7]="Effective Power";para[8]="Shaft Power";
String [] units = new String[9];
units[0]="KN"; units[1]="KN"; units[1]="KN"; units[2]="KN"; units[3]="KN"; units[4]="KN"; units[5]="KN"; units[6]="KN"; units[7]="KW"; units[8]="KW";
//generating the report
PdfWriter wr = null;
Document doc = new Document();
try{
//fos = new FileOutputStream(new File(filename));
PdfPTable table = new PdfPTable(new float[] { 3, 2, 1 });
table.getDefaultCell().setHorizontalAlignment(Element.ALIGN_CENTER);
table.addCell("Resistance and Powering parameter");
table.addCell("Values");
table.addCell("Units");
table.setHeaderRows(1);
PdfPCell[] cells = table.getRow(0).getCells();
for (int j=0;j<cells.length;j++){
cells[j].setBackgroundColor(BaseColor.GRAY);
}
for (int i=0;i<9;i++){
table.addCell(new PdfPCell(new Paragraph(String.valueOf(para[i]))));
table.addCell(new PdfPCell(new Paragraph(String.valueOf(val[i]))));
table.addCell(new PdfPCell(new Paragraph(String.valueOf(units[i]))));
}
wr=PdfWriter.getInstance(doc, new FileOutputStream("report.pdf"));
doc.open();
Image in = Image.getInstance("app_icon.png");
in.scaleToFit(100,100);
//in.setAbsolutePosition(500,500);
doc.add(in);
doc.addTitle("Resistance and powering report");
doc.addCreationDate();
float w =520;//PageSize.A4.getWidth();
float h =380;//*PageSize.A4.getHeight();
//doc.add(new Paragraph("Resistance and powering report",FontFactory.getFont(FontFactory.TIMES_BOLD, 19,Font.BOLD,BaseColor.RED)));
//doc.add(new Paragraph(new Date().toString()));
doc.add(new Paragraph("Resistance and powering report",FontFactory.getFont(FontFactory.TIMES_ROMAN,18,Font.BOLD,BaseColor.ORANGE)));
doc.add(new Paragraph(new Date().toString()));
doc.add(new Paragraph("**********************************************************************************************"));
doc.add(table);
//doc.newPage();
doc.add(new Paragraph("The effective power graph against the speed is shown below",FontFactory.getFont(FontFactory.TIMES_ITALIC,14,Font.ITALIC)));
PdfContentByte tem = wr.getDirectContent();
PdfTemplate tl = tem.createTemplate(w,h);
Graphics2D gd =new PdfGraphics2D(tl,w,h,new DefaultFontMapper());
Rectangle2D r = new Rectangle2D.Double(0,0,w,h);
chart.draw(gd, r);
gd.dispose();
Image im = Image.getInstance(tl);
doc.add(im);
/*Image inm = Image.getInstance("app_icon.png");
in.setAbsolutePosition(490,100);
wr.getDirectContent().addImage(in);
doc.add(inm);*/
doc.close(); }catch(Exception ex){
}
try{
SwingController con= new SwingController();
SwingViewBuilder fac = new SwingViewBuilder(con);
JPanel jp =fac.buildViewerPanel();
con.getDocumentViewController().setAnnotationCallback(
new org.icepdf.ri.common.MyAnnotationCallback(con.getDocumentViewController()));
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(jp);
con.openDocument("report.pdf");
frame.setIconImage(Toolkit.getDefaultToolkit().getImage("app_icon.png"));
frame.pack();
frame.setVisible(true);
}
catch(Exception ex){
ex.printStackTrace();
}
// Desktop.getDesktop().open(new File("report.pdf"));
}
Well, i know it's an older question but for those who struggle with this problem. Execute your jar file on the therminal with the command java -jar YouJarFile.jar and look what the problem is. For me the problem was that i saved the file on an relativ path. When i changed the location to an absolute path the problem for me was solved.
Good Morning,
I've been following the Merge with TOC examples and not having any luck getting the PdfActions to respond. Here is my snippet:
PdfReader finalReader = new PdfReader(viewableStream.toByteArray());
Document finalDoc = new Document(PageSize.LETTER);
PdfCopy finalPdfCopy = new PdfCopy(finalDoc,stream);
PdfCopy.PageStamp finalPdfStamp;
finalDoc.open();
int finalNumPages = finalReader.getNumberOfPages();
for(int finalPageIndex = 1;finalPageIndex <= finalNumPages;finalPageIndex++) {
PdfImportedPage finalImpPage = finalPdfCopy.getImportedPage(finalReader,finalPageIndex);
finalPdfStamp = finalPdfCopy.createPageStamp(finalImpPage);
if (finalPageIndex == tocPage) {
new TOCCustomizer().generateLinks(finalDoc, finalPdfCopy, finalPdfStamp, finalImpPage, vApp.getBookBuildContext(), book);
}
finalPdfStamp.alterContents();
finalPdfCopy.addPage(finalImpPage);
}
finalDoc.close();
finalPdfCopy.close();
stream.flush();
stream.close();
generateLinks method:
public void generateLinks(Document finalDoc,PdfCopy finalPdfCopy,PdfCopy.PageStamp stamp,PdfImportedPage srcPage,BookBuilderContext context, Book book) throws Exception
{
finalDoc.setMargins(0.75f * 72, 0.75f * 72, 0.75f * 72, 0.75f * 72);
finalDoc.add(new Paragraph(" "));
File fontFile = new File(context.getResourcePath(), "ProximaNova-Reg.otf");
BaseFont bfRegular = BaseFont.createFont(
fontFile.getAbsolutePath(),
BaseFont.CP1252,
BaseFont.EMBEDDED
);
Font font1 = new Font(bfRegular,14, Font.NORMAL, Colors.SLATE_GREY);
// create a table for the content
PdfPTable table = new PdfPTable(3);
table.setTotalWidth(7.5f*72);
table.setWidths(new float[]{32f,458f,50f});
int currentPage = 1;
for (int i = 0; i < book.getNumSections(); i++)
{
v.bookmodel.Section s = book.getSection(i);
String itemNbr = s.getItemNbr();
// don't add excluded sections
if (s.isIncluded() && !TOC_EXCLUDE.contains(itemNbr))
{
PdfPCell sectNumCell = new PdfPCell(new Phrase(i+". ",font1));
sectNumCell.setBorder(0);
sectNumCell.setHorizontalAlignment(PdfPCell.ALIGN_RIGHT);
sectNumCell.setPaddingLeft(5);
sectNumCell.setPaddingBottom(10);
sectNumCell.setPaddingTop(15);
table.addCell(sectNumCell);
Chunk sectChunk = new Chunk(s.getSectionName());
sectChunk.setFont(font1);
// sectChunk.setAction(PdfAction.gotoLocalPage(currentPage, new PdfDestination(PdfDestination.FITH), finalPdfCopy));
sectChunk.setAction(new PdfAction(PdfAction.FIRSTPAGE));
Phrase sectPhrase = new Phrase(sectChunk);
PdfPCell sectDescCell = new PdfPCell(sectPhrase);
sectDescCell.setBorder(0);
sectDescCell.setHorizontalAlignment(PdfPCell.ALIGN_LEFT);
sectDescCell.setPaddingLeft(5);
sectDescCell.setPaddingBottom(10);
sectDescCell.setPaddingTop(15);
table.addCell(sectDescCell);
PdfPCell sectPageCell = new PdfPCell(new Phrase(currentPage+"",font1));
sectPageCell.setBorder(0);
sectPageCell.setHorizontalAlignment(PdfPCell.ALIGN_RIGHT);
sectPageCell.setPaddingLeft(5);
sectPageCell.setPaddingBottom(10);
sectPageCell.setPaddingTop(15);
table.addCell(sectPageCell);
int sectionPages = s.getSectionTotalPages();
currentPage+=sectionPages;
} else if (s.isIncluded() && TOC_SECTIONS.contains(itemNbr)) {
int sectionPages = s.getSectionTotalPages();
currentPage+=sectionPages;
}
}
The document is getting created, but the TOC links will not go back to the first page. I did convert this to use PdfWriter instead of PdfCopy and this worked for the links, but I can't use PdfWriter due to the different original pdf boxing. I think there's something simple that I'm missing, but struggling to see what it is. Any help would be greatly appreciated. I'm currently using version 2.0.7 on this project.
Thanks In Advance,
-Jeff
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;
}