首页 文章

用PDFBOX写阿拉伯语并使用正确的字符表示形式而不分开

提问于
浏览
4

我正在尝试使用PDFBox Apache生成包含阿拉伯语文本的PDF,但文本生成为单独的字符,因为Apache将给定的阿拉伯字符串解析为一系列通用的“官方”Unicode字符,这些字符相当于孤立形式的阿拉伯字符 .

这是一个例子:
目标文本以PDF格式写入"Should be expected output in PDF File" - >جملةبالعربي
我在PDF文件中得到了什么 - >

incorrect text

我尝试了一些方法,但这里有一些没用:
1.将字符串转换为比特流并尝试提取正确的值
2.使用UTF-8 && UTF-16处理String一个字节序列并从中提取值

有一些方法看起来非常有希望得到每个字符的值“Unicode”但是它产生一般的“官方Unicode”这就是我的意思

System.out.println( Integer.toHexString( (int)(new String("كلمة").charAt(1))) );

output is 644 but fee0 was the expected output because this character is in middle from then I should get the middle Unicode fee0

所以我想要的是一些生成正确Unicode的方法,而不仅仅是官方的Unicode

以下链接中第一个表中的“Left”列表示常规Unicode
Arabic Unicode Tables Wikipedia

1 回答

  • 4

    首先,我将感谢Tilman和M.Prokhorov向我展示了使用PDFBox Apache编写阿拉伯语的库 .


    本答复将分为两个部分:

    • 下载库并进行安装

    • 如何使用库


    下载库并进行安装

    我们将使用ICU Library .
    ICU代表Unicode的国际组件,它是一组成熟的,广泛使用的C / C和Java库,为软件应用程序提供Unicode和全球化支持 . ICU具有广泛的可移植性,可在所有平台以及C / C和Java软件之间为应用程序提供相同的结果 .

    要下载库,请转到here的下载页面 .
    选择 ICU4J 的最新版本,如下图所示 .

    Downloads Page

    您将被转移到另一个页面,您将找到一个包含所需组件的直接链接的框 . 请继续下载三个文件,您将在下一个图像中找到突出显示的文件 .

    • icu4j-docs.jar

    • icu4j-src.jar

    • icu4j.jar

    Files

    有关在 Netbeans IDE 中创建和添加库的以下说明

    • 导航到工具栏和单击工具

    • 选择图书馆

    • 在左下方,您将找到新的库按钮创建您的

    • 导航到您在库列表中创建的库

    • 单击它并添加这样的jar文件夹

    • 在类路径中添加icu4j.jar

    • 在Sources中添加icu4j-src.jar

    • 在Javadoc中添加icu4j-docs.jar

    • 从右侧查看已打开的项目

    • 展开要在其中使用库的项目

    • 右键单击libraries文件夹,然后选择添加库

    • 最后选择刚刚创建的库 .

    现在您已准备好使用该库,只需导入您想要的内容

    import com.ibm.icu.What_You_Want_To_Import;
    

    如何使用库

    使用ArabicShaping Class并反转String我们可以写一个正确的附加阿拉伯语 LINE
    这是代码 Notice the comments in the following code

    import com.ibm.icu.text.ArabicShaping;
    import com.ibm.icu.text.ArabicShapingException;
    import java.io.File;
    import java.io.IOException;
    import org.apache.pdfbox.pdmodel.PDDocument;
    import org.apache.pdfbox.pdmodel.PDPage;
    import org.apache.pdfbox.pdmodel.PDPageContentStream;
    import org.apache.pdfbox.pdmodel.font.*;
    
    public class Main {
        public static void main(String[] args) throws IOException , ArabicShapingException
    {
            File f = new File("Arabic Font File of format.ttf");
            PDDocument doc = new PDDocument();
            PDPage Page = new PDPage();
            doc.addPage(Page);
            PDPageContentStream Writer = new PDPageContentStream(doc, Page);
            Writer.beginText();
            Writer.setFont(PDType0Font.load(doc, f), 20);
            Writer.newLineAtOffset(0, 700);
            //The Trick in the next Line of Code But Here is some few Notes first  
            //We have to reverse the string because PDFBox is Writting from the left but Arabic is RTL Language  
            //The output will be perfect except every line will be justified to the left "It's not hard to resolve this"
            // So we have to write arabic string to pdf line by line..It will be like this
            String s ="جملة بالعربي لتجربة الكلاس اللذي يساعد علي وصل الحروف بشكل صحيح";
            Writer.showText(new StringBuilder(new ArabicShaping(reverseNumbersInString(ArabicShaping.LETTERS_SHAPE).shape(s))).reverse().toString());
            // Note the previous line of code throws ArabicShapingExcpetion 
            Writer.endText();
            Writer.close();
            doc.save(new File("File_Test.pdf"));
            doc.close();
        }
    }
    

    这是输出

    Output

    我希望我已经完成了所有事情 .

    Update :反转后请确保再次反转数字以获得相同的正确数字
    这里有几个可以提供帮助的功能

    public static boolean isInt(String Input)
    {
        try{Integer.parseInt(Input);return true;}
        catch(NumberFormatException e){return false;}
    }
    public static String reverseNumbersInString(String Input)
    {
        char[] Separated = Input.toCharArray();int i = 0;
        String Result = "",Hold = "";
        for(;i<Separated.length;i++ )
        {
            if(isInt(Separated[i]+"") == true)
            {
                while(i < Separated.length && (isInt(Separated[i]+"") == true ||  Separated[i] == '.' ||  Separated[i] == '-'))
                {
                    Hold += Separated[i];
                    i++;
                }
                Result+=reverse(Hold);
                Hold="";
            }
            else{Result+=Separated[i];}
        }
        return Result;
    }
    

相关问题