iText - PdfActions not working - java

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

Related

iText writeSelectedRows not doing anything

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();
}
}

java.io.IOException: The document has no pages. Working fine locally but not working after deploying in aws

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(""));

Non removable watermark on PDF file using iText in Java

We have a requirement where we need to add text watermark on magazines which has multiple rich images on each page. I tried com.itextpdf.jar version 5.0.6 to add the watermark but eventually I am able to remove it using Adobe Acrobat Pro.
I tried below option also but that too didn't work.
stamper.setFreeTextFlattening(true);
Is it possible with iText to add a watermark which can not be removed without much effort.
Below is my implementation.
public static void addWaterMark() throws IOException, DocumentException {
PdfReader reader = new PdfReader("C:/Trade-catalog/Catalog2017.pdf");
ByteArrayOutputStream outputPdf = new ByteArrayOutputStream();
PdfStamper stamper = new PdfStamper(reader, outputPdf);
String bodyWatermarkText = "12345 - John Smith";
String bodyWatermarkRotation = "35";
String footerWatermarkText = "Richard Parker";
BaseFont font = BaseFont.createFont("/fonts/micross.ttf", "Cp1250", BaseFont.EMBEDDED);
PdfGState state = new PdfGState();
state.setFillOpacity(0.3f);
for (int i = 1; i <= reader.getNumberOfPages(); i++) {
Rectangle thisPageSize = reader.getPageSize(i);
PdfPatternPainter bodyPainter = stamper.getOverContent(i).createPattern(thisPageSize.getWidth(),
thisPageSize.getHeight());
bodyPainter.setColorFill(new BaseColor(0, 0, 0));
bodyPainter.beginText();
bodyPainter.setTextRenderingMode(PdfPatternPainter.TEXT_RENDER_MODE_FILL);
bodyPainter.setFontAndSize(font, 60);
bodyPainter.showTextAlignedKerned(Element.ALIGN_CENTER, bodyWatermarkText, thisPageSize.getWidth() / 2,
thisPageSize.getHeight() / 2, Integer.valueOf(bodyWatermarkRotation));
bodyPainter.showTextAlignedKerned(Element.ALIGN_RIGHT, footerWatermarkText, thisPageSize.getWidth() * 0.97f,
thisPageSize.getHeight() * 0.015f, 0);
bodyPainter.endText();
PdfContentByte overContent = stamper.getOverContent(i);
overContent.setGState(state);
overContent.setColorFill(new PatternColor(bodyPainter));
overContent.rectangle(thisPageSize.getLeft(), thisPageSize.getBottom(), thisPageSize.getWidth(),
thisPageSize.getHeight());
overContent.fill();
overContent.setFlatness(100);
}
stamper.close();
FileOutputStream outputStream = new FileOutputStream(
"C:/Trade-catalog/output/TradeCatalog2017Watermarked_bodyPainter.pdf");
outputPdf.writeTo(outputStream);
outputPdf.close();
reader.close();
}

PDF-Checkbox - check one and uncheck another without JavaScript

in my project I need 3 checkboxes which should work like radiobuttons. But radiobuttons have some drawbacks with appearance in Adobe Reader. For this reason I have to use checkboxes. There is a very interesting answer, but I don't understand how this can be done with iText:
Java iText and custom Radiobutton behaviour
Can anybody -- especially Lonzak, the author of this posting -- help me in this case. Thanks and Kind regards, Dirk
I think the solution is to fix your current code. The following example creates 3 radiobuttons and all contain a cross. It was based on itext 5 and you may have to adapt it a bit for itext 7.
Document document = new Document(PageSize.A4, 50, 50, 50, 50);
PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream("output.pdf"));
document.open();
RadioCheckField bt = new RadioCheckField(writer, new Rectangle(261, 576, 279, 594), "radio", "value1");
bt.setCheckType(RadioCheckField.TYPE_CROSS);
bt.setBackgroundColor(BaseColor.WHITE);
//bt.setBorderStyle(PdfBorderDictionary.STYLE_SOLID);
bt.setBorderColor(BaseColor.BLACK);
bt.setTextColor(BaseColor.BLACK);
bt.setBorderWidth(BaseField.BORDER_WIDTH_THIN);
bt.setChecked(false);
PdfFormField f1 = bt.getRadioField();
bt.setOnValue("value2");
bt.setChecked(true);
bt.setBox(new Rectangle(287, 577, 305, 595));
PdfFormField f2 = bt.getRadioField();
bt.setChecked(false);
PdfFormField top = bt.getRadioGroup(true, false);
bt.setOnValue("value3");
bt.setBox(new Rectangle(314, 578, 332, 596));
PdfFormField f3 = bt.getRadioField();
top.addKid(f1);
top.addKid(f2);
top.addKid(f3);
writer.addAnnotation(top);
document.close();
Update: Here is your code with iText7 however there seems to be a bug so that the check style is not changed for radiobuttons. Maybe the itext guys can say more...
PdfDocument pdfDoc = new PdfDocument(new PdfWriter("output7.pdf"));
Document doc = new Document(pdfDoc);
PdfButtonFormField radioGroup = PdfFormField.createRadioGroup(pdfDoc, "ExampleGroup", "");
radioGroup.setPage(1);
pdfDoc.addNewPage();
PdfFormField field1 = PdfFormField.createRadioButton(pdfDoc, new Rectangle(261, 576, 18, 18), radioGroup, "value1");
field1.setCheckType(PdfFormField.TYPE_CROSS);
field1.setValue("value1");
field1.regenerateField();
PdfFormField field2 = PdfFormField.createRadioButton(pdfDoc, new Rectangle(287, 577, 18, 18), radioGroup, "value2");
field2.setCheckType(PdfFormField.TYPE_CROSS);
field2.regenerateField();
PdfFormField field3 = PdfFormField.createRadioButton(pdfDoc, new Rectangle(314, 578, 18, 18), radioGroup, "value3");
field3.setCheckType(PdfFormField.TYPE_CROSS);
field3.regenerateField();
PdfAcroForm.getAcroForm(pdfDoc, true).addField(radioGroup);
doc.close();
Final solution with iText 7:
public static void main(String[] args) throws Exception {
// RadioButton with cross instead of bullet.
final String filename = "SampleRadioButton.pdf";
final float boxLength = 20;
final float crossWidth = 1;
final String[] languages = { "Dutch", "English", "French" };
try (PdfWriter writer = new PdfWriter(filename); PdfDocument pdfDoc = new PdfDocument(writer); Document doc = new Document(pdfDoc)) {
pdfDoc.addNewPage();
final PdfAcroForm form = PdfAcroForm.getAcroForm(pdfDoc, true);
final PdfButtonFormField radioGroup = PdfFormField.createRadioGroup(pdfDoc, "Language", languages[1]);
int count = 0;
for (final String language : languages) {
count++;
// button
final Rectangle rect = new Rectangle(40, 800 - (count * 30), boxLength, boxLength);
final PdfFormField radioButton = PdfFormField.createRadioButton(pdfDoc, rect, radioGroup, language);
final PdfDictionary radioDict = radioButton.getPdfObject();
final PdfDictionary mk = new PdfDictionary();
mk.put(PdfName.CA, new PdfString("8")); // check=4, circle=1, cross=8, diamond=u, square=n, star=H
radioDict.put(PdfName.MK, mk);
radioButton.setVisibility(PdfFormField.VISIBLE);
editAppearance(pdfDoc, radioButton, language, boxLength, crossWidth);
// text
final Paragraph para = new Paragraph(language).setFontSize(18);
doc.showTextAligned(para, 70, 800 - (count * 30), TextAlignment.LEFT);
}
form.addField(radioGroup);
}
Desktop.getDesktop().open(new File(filename));
}
private static void editAppearance(PdfDocument pdfDoc, PdfFormField radioButton, String value, float length, float crossWidth) {
final PdfStream streamOn = (PdfStream) new PdfStream().makeIndirect(pdfDoc);
final PdfCanvas canvasOn = new PdfCanvas(streamOn, new PdfResources(), pdfDoc);
final Rectangle rect = new Rectangle(0, 0, length, length);
final PdfFormXObject xObjectOn = new PdfFormXObject(rect);
canvasOn.saveState();
canvasOn.setStrokeColor(ColorConstants.BLACK).setLineWidth(crossWidth);
// bottom left to top right
canvasOn.moveTo(0, 0).lineTo(length, length).stroke();
// Top left to bottom right
canvasOn.moveTo(0, length).lineTo(length, 0).stroke();
canvasOn.restoreState();
xObjectOn.getPdfObject().getOutputStream().writeBytes(streamOn.getBytes());
final PdfWidgetAnnotation widget = radioButton.getWidgets().get(0);
widget.setNormalAppearance(new PdfDictionary());
widget.getNormalAppearanceObject().put(new PdfName(value), xObjectOn.getPdfObject());
}
}

RTL not working in pdf generation with itext 5.5 for Arabic text

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;
}

Categories