有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java使用PDFBOX编写阿拉伯语,字符正确,呈现形式不分隔

我试图使用PDFBox Apache生成一个包含阿拉伯语文本的PDF,但文本是作为分隔字符生成的,因为Apache将给定的阿拉伯语字符串解析为一个通用的“官方”Unicode字符序列,该序列相当于阿拉伯语字符的隔离形式

下面是一个例子:
以PDF格式编写的目标文本“应以PDF格式输出”->;
我在PDF文件中获得的内容->

incorrect text

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

有一种方法似乎很有希望获得每个字符的值“Unicode”,但它会生成通用的“官方Unicode”,这就是我的意思

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

输出是644,但是fee0是预期的输出,因为这个字符在中间,从那时起我应该得到中间的Unicode fee0

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

下面链接中第一个表中最左边的一列表示通用Unicode
Arabic Unicode Tables Wikipedia


共 (2) 个答案

  1. # 1 楼答案

    注意:

    此答案中的示例代码可能已过时,请参考h q's answer了解工作示例代码


    首先,我要感谢Tilman HausherrM.Prokhorov向我展示了使使用PDFBox Apache编写阿拉伯语成为可能的库

    答案将分为两部分:
    1. 下载并安装库
    2. 如何使用图书馆

    下载并安装库

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

    要下载库,请从here转到下载页面
    选择最新版本的ICU4J,如下图所示
    Downloads Page
    你将被转移到另一个页面,你会发现一个框中有所需组件的直接链接。继续下载三个文件,你将在下一张图中找到突出显示的文件

    1. icu4j文件。罐子
    2. icu4j src。罐子
    3. icu4j。罐子

    Files

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

    1. 导航到工具栏并单击“工具”
    2. 选择图书馆
    3. 在左下角,你会发现“新建库”按钮“创建你的库”
    4. 导航到在“库”列表中创建的库
    5. 点击它并添加类似的jar文件夹
    6. 添加icu4j。类路径中的jar
    7. 添加icu4j src。来源不全
    8. 添加icu4j文档。Javadoc中的jar
    9. 从最右边查看打开的项目
    10. 展开要在其中使用库的项目
    11. 右键单击“库”文件夹并选择“添加库”
    12. 最后选择您刚刚创建的库

    现在你已经准备好使用这个库了,只需要像那样导入你想要的东西

    import com.ibm.icu.What_You_Want_To_Import;
    


    如何使用图书馆

    使用ArabicsShaping类并反转字符串,我们可以写出正确的附加阿拉伯语
    下面是代码请注意下面代码中的注释

    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

    我希望我已经检查了所有的事情

    更新:反转后,确保再次反转数字,以获得相同的正确数字
    这里有几个函数可能会有所帮助

    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;
    }
    
  2. # 2 楼答案

    下面是一个有效的代码。下载一个示例字体,例如trado.ttf

    确保pdfbox-appicu4jjar文件在类路径中

    import java.io.File;
    import java.io.IOException;
    
    import com.ibm.icu.text.ArabicShaping;
    import com.ibm.icu.text.ArabicShapingException;
    import com.ibm.icu.text.Bidi;
    
    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("trado.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);
            String s ="جملة بالعربي لتجربة الكلاس اللذي يساعد علي وصل الحروف بشكل صحيح";
            Writer.showText(bidiReorder(s));
            Writer.endText();
            Writer.close();
            doc.save(new File("File_Test.pdf"));
            doc.close();
        }
    
        private static String bidiReorder(String text)
        {
            try {
            Bidi bidi = new Bidi((new ArabicShaping(ArabicShaping.LETTERS_SHAPE)).shape(text), 127);
                bidi.setReorderingMode(0);
                return bidi.writeReordered(2);
            }
            catch (ArabicShapingException ase3) {
            return text;
        }
        }
    
    }