java 用PDFBOX书写阿拉伯文,文字表达形式正确,不分离

xfb7svmp  于 2023-01-24  发布在  Java
关注(0)|答案(2)|浏览(188)

我试图使用PDFBox Apache生成包含阿拉伯语文本的PDF,但文本生成为分隔字符,因为Apache将给定的阿拉伯语字符串解析为一般“官方”Unicode字符序列,相当于阿拉伯语字符的隔离形式。
下面是一个例子:
要写入PDF的目标文本“应该是PDF文件中的预期输出”-〉
我在PDF文件中得到什么-〉

我尝试了一些方法,但没有用这里是其中的一些:
1.将字符串转换为位流并尝试提取正确的值
2.用UTF-8和UTF-16处理字符串字节序列并从中提取值
有一些方法似乎很有希望获得每个字符的值“Unicode”,但它生成一般的“官方Unicode”这就是我的意思

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

输出为644,但fee 0是预期输出,因为此字符位于中间,因此我应获得中间的Unicode fee 0

所以我想要的是一些生成正确Unicode的方法,而不仅仅是官方的方法
以下链接中第一个表的最左列表示通用Unicode
Arabic Unicode Tables Wikipedia

2w2cym1i

2w2cym1i1#

注意事项:

此答案中的示例代码可能已过时,请参阅h q's answer以获取工作示例代码
首先,我要感谢Tilman HausherrM.Prokhorov向我展示了使使用PDFBox Apache编写阿拉伯语成为可能的库。
本答案将分为两部分:
1.下载并安装库
1.如何使用图书馆

下载并安装库

我们将使用ICU库。
ICU代表Unicode的国际组件,它是一组成熟的、广泛使用的C/C和Java库,为软件应用程序提供Unicode和全球化支持。ICU具有广泛的可移植性,在所有平台上以及在C/C和Java软件之间为应用程序提供相同的结果。
要下载库,请转到here的下载页面。
选择最新版本的ICU 4J,如下图所示。

你将被转到另一个页面,你会发现一个框与直接链接所需的组件。继续下载三个文件,你会发现突出显示在下一个图像。

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

以下是有关在Netbeans IDE中创建和添加库的说明
1.导航到工具栏并单击工具
1.选择库
1.在左下角,你会发现新的图书馆按钮创建你的
1.导航到您在库列表中创建的库
1.单击它并添加如下所示的jar文件夹
1.在类路径中添加icu4j.jar
1.在源代码中添加icu4j-src.jar
1.在Javadoc中添加icu4j-docs.jar
1.从最右侧查看打开的项目
1.展开要在其中使用库的项目
1.右键单击libraries文件夹并选择“添加库
1.最后选择您刚刚创建的库。
现在你已经准备好使用这个库了,只需要像这样导入你想要的东西

import com.ibm.icu.What_You_Want_To_Import;

如何使用库

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

以下是输出

我希望我已经把一切都说清楚了。

更新:颠倒后,确保再次颠倒数字,以获得相同的正确数字

这里有几个函数可以提供帮助

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

6pp0gazn2#

下面是一段代码。下载一个示例字体,例如trado.ttf
确保pdfbox-appicu4j jar文件位于类路径中。

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

}

相关问题