使用 itext 在 pdf 中书写阿拉伯语
Writing Arabic in pdf using itext
我正在使用 itext 库生成 PDF 文件。
我想写阿拉伯语单词。
当我运行以下代码时,单词字符被反向显示。
使用代码:
PdfContentByte cb = docWriter.getDirectContent();
BaseFont bfBold = BaseFont.createFont("assets/arial.ttf", BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
createHeadings(cb, document.leftMargin(), 70, "السعر الاجمالي: " + tprice + " L.E.");
。
.
.
private void createHeadings(PdfContentByte cb, float x, float y, String text){
cb.beginText();
cb.setFontAndSize(bfBold, 10);
cb.setTextMatrix(x,y);
cb.showText(text.trim());
cb.endText();
}
这张图片描述了上面代码的输出:
http://i.stack.imgur.com/OLoLo.jpg
请查看 Ligatures2 示例。
你是不是忘记了这句话:
cb.setRunDirection(PdfWriter.RUN_DIRECTION_RTL);
当您希望 iText 从右向左书写文本并在必要时创建连字时,setRunDirection()
方法是必需的。此方法也存在于表的上下文中,在这种情况下,您将其应用于 PdfPCell
对象而不是 ColumnText
对象。
另外,我不明白你为什么要用这个String
:"السعر الاجمالي: "
。请改用 Unicode 表示法(例如 "\u0644\u0648\u0631\u0627\u0646\u0633 \u0627\u0644\u0639\u0631\u0628"
之类的东西),因为像您这样使用 String
会在编码和连字方面造成各种混淆。一些编辑器不会使用正确的编码(将您的文本更改为乱码);一些编辑器会制作连字(这不是 iText 所期望的)。
例如,在你的情况下,我不懂阿拉伯语,所以我不知道它是 "\u0627\u0644\u0633\u0639\u0631 \u0627\u0644\u0627\u062c\u0645\u0627\u0644\u064a"
还是 "\u064a\u0644\u0627\u0645\u062c\u0627\u0644\u0627 \u0631\u0639\u0633\u0644\u0627"
因为我不知道我是否必须开始读取值为 \u0627
的字形或值为 \u064a
的字形。在任何情况下:iText 期望 String
中的第一个 "character" 是人类首先阅读的内容。
请看一下ArabicExample例子:
第一行不正确,因为使用 document.add()
时不支持 RTL 和阿拉伯连字。第二行是正确的(据我所知:我看不懂阿拉伯语)因为我使用了 ColumnText
.
这是我使用的代码:
public static final String FONT = "resources/fonts/NotoNaskhArabic-Regular.ttf";
public static final String ARABIC = "\u0627\u0644\u0633\u0639\u0631 \u0627\u0644\u0627\u062c\u0645\u0627\u0644\u064a";
public void createPdf(String dest) throws IOException, DocumentException {
Document document = new Document();
PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(dest));
document.open();
Font f = FontFactory.getFont(FONT, BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
Phrase p = new Phrase("This is incorrect: ");
p.add(new Chunk(ARABIC, f));
p.add(new Chunk(": 50.00 USD"));
document.add(p);
p = new Phrase("This is correct: ");
p.add(new Chunk(ARABIC, f));
p.add(new Phrase(": 50.00"));
ColumnText canvas = new ColumnText(writer.getDirectContent());
canvas.setSimpleColumn(36, 750, 559, 780);
canvas.setRunDirection(PdfWriter.RUN_DIRECTION_LTR);
canvas.addElement(p);
canvas.go();
document.close();
}
我使用了 Phrase
,但是当使用 Paragraph
(Paragraph
扩展 Phrase
)时,您可以期待相同的结果。如果这不能回答您的问题,请澄清。考虑到 Whosebug 上的大多数人不懂阿拉伯语,所以当你提问和说 "it doesn't work" 时,你必须非常明确。因为我们不懂阿拉伯语,所以我们不知道它应该如何工作。
我正在使用 itext 库生成 PDF 文件。 我想写阿拉伯语单词。 当我运行以下代码时,单词字符被反向显示。
使用代码:
PdfContentByte cb = docWriter.getDirectContent();
BaseFont bfBold = BaseFont.createFont("assets/arial.ttf", BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
createHeadings(cb, document.leftMargin(), 70, "السعر الاجمالي: " + tprice + " L.E.");
。 . .
private void createHeadings(PdfContentByte cb, float x, float y, String text){
cb.beginText();
cb.setFontAndSize(bfBold, 10);
cb.setTextMatrix(x,y);
cb.showText(text.trim());
cb.endText();
}
这张图片描述了上面代码的输出: http://i.stack.imgur.com/OLoLo.jpg
请查看 Ligatures2 示例。
你是不是忘记了这句话:
cb.setRunDirection(PdfWriter.RUN_DIRECTION_RTL);
当您希望 iText 从右向左书写文本并在必要时创建连字时,setRunDirection()
方法是必需的。此方法也存在于表的上下文中,在这种情况下,您将其应用于 PdfPCell
对象而不是 ColumnText
对象。
另外,我不明白你为什么要用这个String
:"السعر الاجمالي: "
。请改用 Unicode 表示法(例如 "\u0644\u0648\u0631\u0627\u0646\u0633 \u0627\u0644\u0639\u0631\u0628"
之类的东西),因为像您这样使用 String
会在编码和连字方面造成各种混淆。一些编辑器不会使用正确的编码(将您的文本更改为乱码);一些编辑器会制作连字(这不是 iText 所期望的)。
例如,在你的情况下,我不懂阿拉伯语,所以我不知道它是 "\u0627\u0644\u0633\u0639\u0631 \u0627\u0644\u0627\u062c\u0645\u0627\u0644\u064a"
还是 "\u064a\u0644\u0627\u0645\u062c\u0627\u0644\u0627 \u0631\u0639\u0633\u0644\u0627"
因为我不知道我是否必须开始读取值为 \u0627
的字形或值为 \u064a
的字形。在任何情况下:iText 期望 String
中的第一个 "character" 是人类首先阅读的内容。
请看一下ArabicExample例子:
第一行不正确,因为使用 document.add()
时不支持 RTL 和阿拉伯连字。第二行是正确的(据我所知:我看不懂阿拉伯语)因为我使用了 ColumnText
.
这是我使用的代码:
public static final String FONT = "resources/fonts/NotoNaskhArabic-Regular.ttf";
public static final String ARABIC = "\u0627\u0644\u0633\u0639\u0631 \u0627\u0644\u0627\u062c\u0645\u0627\u0644\u064a";
public void createPdf(String dest) throws IOException, DocumentException {
Document document = new Document();
PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(dest));
document.open();
Font f = FontFactory.getFont(FONT, BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
Phrase p = new Phrase("This is incorrect: ");
p.add(new Chunk(ARABIC, f));
p.add(new Chunk(": 50.00 USD"));
document.add(p);
p = new Phrase("This is correct: ");
p.add(new Chunk(ARABIC, f));
p.add(new Phrase(": 50.00"));
ColumnText canvas = new ColumnText(writer.getDirectContent());
canvas.setSimpleColumn(36, 750, 559, 780);
canvas.setRunDirection(PdfWriter.RUN_DIRECTION_LTR);
canvas.addElement(p);
canvas.go();
document.close();
}
我使用了 Phrase
,但是当使用 Paragraph
(Paragraph
扩展 Phrase
)时,您可以期待相同的结果。如果这不能回答您的问题,请澄清。考虑到 Whosebug 上的大多数人不懂阿拉伯语,所以当你提问和说 "it doesn't work" 时,你必须非常明确。因为我们不懂阿拉伯语,所以我们不知道它应该如何工作。