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

前端 未结 3 747
北恋
北恋 2020-12-04 03:14

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(PdfWrit

相关标签:
3条回答
  • 2020-12-04 03:19

    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.

    0 讨论(0)
  • 2020-12-04 03:31

    //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();
    
    0 讨论(0)
  • 2020-12-04 03:33

    For developers that need an straightforward solution

    I used this trick and output is very clean and nice!

    1. create a PDFPTable with 1 column
    2. 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!!!)
    3. create a PDFPCell and remove its borders using setBorder(Rectangle.NO_BORDER) and add the paragraph to cell
    4. 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;
    }
    
    0 讨论(0)
提交回复
热议问题