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

Min*_*ges 4 java pdf pdf-generation pdfbox

我正在尝试使用PDFBox Apache生成包含阿拉伯文本的PDF,但该文本会作为分隔的字符生成,因为Apache将给定的阿拉伯字符串解析为一系列常规的“正式” Unicode字符,等效于隔离的阿拉伯字符形式。

这是一个示例:
要在PDF中写入的目标文本“应该在PDF文件中输出”-> ???? ???????
我在PDF文件中得到的内容->

不正确的文字

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

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

System.out.println( Integer.toHexString( (int)(new String("????").charAt(1))) );  
Run Code Online (Sandbox Code Playgroud)

输出为644,但fee0是预期的输出,因为此字符位于中间,那么我应该得到中间的Unicode fee0

所以我想要的是一种生成正确Unicode而不只是官方的方法

以下链接的第一个表中最左侧的列表示常规Unicode
阿拉伯语Unicode表Wikipedia

Min*_*ges 5

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


该答案将分为两个部分:

  1. 下载并安装库
  2. 如何使用图书馆

下载并安装库

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

要下载库,请从此处转到下载页面。如下图所示,
选择最新版本的ICU4J
下载页面
您将转到另一个页面,您将找到一个包含所需组件直接链接的框。继续并下载三个文件,您将在下一张图片中找到突出显示的内容。

  1. icu4j-docs.jar
  2. icu4j-src.jar
  3. icu4j.jar

档案

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

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

现在您可以使用库了,只需导入所需的内容即可

import com.ibm.icu.What_You_Want_To_Import;
Run Code Online (Sandbox Code Playgroud)


如何使用图书馆

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

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();
    }
}
Run Code Online (Sandbox Code Playgroud)

这是输出

输出量

我希望我已经解决了所有问题。

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

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;
}
Run Code Online (Sandbox Code Playgroud)

  • 对于那些使用 maven 构建的人...... pom.xml 中的部分将是 `&lt;dependency&gt; &lt;groupId&gt;com.ibm.icu&lt;/groupId&gt; &lt;artifactId&gt;icu4j&lt;/artifactId&gt; &lt;version&gt;60.2&lt;/version&gt; &lt;/dependency&gt;`,要查看格式,请参见 http://mvnrepository.com/artifact/com.ibm.icu/icu4j/60.2。 (2认同)

h q*_*h q 5

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

\n

编辑:此后我一直在使用Amiri字体,可以从aliftype/amiriGithub存储库下载该字体。

\n

确保pdfbox-appicu4jjar 文件位于您的类路径中。

\n
import java.io.File;\nimport java.io.IOException;\n\nimport com.ibm.icu.text.ArabicShaping;\nimport com.ibm.icu.text.ArabicShapingException;\nimport com.ibm.icu.text.Bidi;\n\nimport org.apache.pdfbox.pdmodel.PDDocument;\nimport org.apache.pdfbox.pdmodel.PDPage;\nimport org.apache.pdfbox.pdmodel.PDPageContentStream;\nimport org.apache.pdfbox.pdmodel.font.*;\n\npublic class Main {\n    public static void main(String[] args) throws IOException , ArabicShapingException\n    {\n    File f = new File("Amiri-Regular.ttf");\n        PDDocument doc = new PDDocument();\n        PDPage Page = new PDPage();\n        doc.addPage(Page);\n        PDPageContentStream Writer = new PDPageContentStream(doc, Page);\n        Writer.beginText();\n        Writer.setFont(PDType0Font.load(doc, f), 20);\n        Writer.newLineAtOffset(0, 700);\n        String s ="\xd8\xac\xd9\x85\xd9\x84\xd8\xa9 \xd8\xa8\xd8\xa7\xd9\x84\xd8\xb9\xd8\xb1\xd8\xa8\xd9\x8a \xd9\x84\xd8\xaa\xd8\xac\xd8\xb1\xd8\xa8\xd8\xa9 \xd8\xa7\xd9\x84\xd9\x83\xd9\x84\xd8\xa7\xd8\xb3 \xd8\xa7\xd9\x84\xd9\x84\xd8\xb0\xd9\x8a \xd9\x8a\xd8\xb3\xd8\xa7\xd8\xb9\xd8\xaf \xd8\xb9\xd9\x84\xd9\x8a \xd9\x88\xd8\xb5\xd9\x84 \xd8\xa7\xd9\x84\xd8\xad\xd8\xb1\xd9\x88\xd9\x81 \xd8\xa8\xd8\xb4\xd9\x83\xd9\x84 \xd8\xb5\xd8\xad\xd9\x8a\xd8\xad";\n        Writer.showText(bidiReorder(s));\n        Writer.endText();\n        Writer.close();\n        doc.save(new File("File_Test.pdf"));\n        doc.close();\n    }\n\n    private static String bidiReorder(String text)\n    {\n        try {\n        Bidi bidi = new Bidi((new ArabicShaping(ArabicShaping.LETTERS_SHAPE)).shape(text), 127);\n            bidi.setReorderingMode(0);\n            return bidi.writeReordered(2);\n        }\n        catch (ArabicShapingException ase3) {\n        return text;\n    }\n    }\n    \n}\n
Run Code Online (Sandbox Code Playgroud)\n