Java 使用PDFBOX编写阿拉伯语字符 更新1
我正在尝试使用pdfbox在pdf文档中写入一些阿拉伯字符。结果我得到了一些奇怪的角色。您可以在下面找到我用于测试的代码片段。请注意,相同的代码用于打印拉丁字符,没有任何问题Java 使用PDFBOX编写阿拉伯语字符 更新1,java,pdfbox,Java,Pdfbox,我正在尝试使用pdfbox在pdf文档中写入一些阿拉伯字符。结果我得到了一些奇怪的角色。您可以在下面找到我用于测试的代码片段。请注意,相同的代码用于打印拉丁字符,没有任何问题 public static void main(String[] args) throws Exception { PDDocument document = new PDDocument(); PDPage page = new PDPage(PDPage.PAGE_SIZE_A4); doc
public static void main(String[] args) throws Exception {
PDDocument document = new PDDocument();
PDPage page = new PDPage(PDPage.PAGE_SIZE_A4);
document.addPage(page);
PDPageContentStream stream = new PDPageContentStream(document, page,true, true);
//Use of a unicode font
PDFont font = PDTrueTypeFont.loadTTF(document,"C:/arialuni.ttf");
font.setFontEncoding(new WinAnsiEncoding());
stream.setFont(font, 12);
stream.beginText();
stream.moveTextPositionByAmount(40, 600);
stream.drawString("سي ججس ححسيب حسججسيبنم حح ");
stream.endText();
stream.close();
document.save("c:\\resultpdf.pdf");
document.close();
}
谢谢你的帮助。我尝试了从微软网站下载的Unicode字体,但仍然有相同的结果
public void drawUnicodeString(String text) throws IOException {
COSString string = new COSString();
for (int i = 0; i < text.length(); i++) {
char c = text.charAt(i);
string.append(c >> 8);
string.append(c & 0xff);
}
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
string.writePDF(buffer);
appendRawCommands(buffer.toByteArray());
appendRawCommands(32);
appendRawCommands(getISOBytes("Tj\n"));
}
public static PDType0Font loadTTF(PDDocument doc, InputStream is)
throws IOException {
/* Load the font which we will convert to Type0 font. */
PDTrueTypeFont pdTtf = PDTrueTypeFont.loadTTF(doc, is);
TrueTypeFont ttf = pdTtf.getTTFFont();
CMAPEncodingEntry unicodeMap = null;
for (CMAPEncodingEntry candidate : ttf.getCMAP().getCmaps()) {
if (candidate.getPlatformId() == CMAPTable.PLATFORM_WINDOWS
&& candidate.getPlatformEncodingId() == CMAPTable.ENCODING_UNICODE) {
unicodeMap = candidate;
break;
}
}
if (unicodeMap == null) {
throw new RuntimeException(
"To use as CIDFont, the TTF must have a Windows platform Unicode encoding");
}
float scaling = 1000f / ttf.getHeader().getUnitsPerEm();
MyPDCIDFontType2Font pdCidFont2 = new MyPDCIDFontType2Font();
pdCidFont2.setBaseFont(pdTtf.getBaseFont());
pdCidFont2.setFontDescriptor((PDFontDescriptorDictionary) pdTtf
.getFontDescriptor());
/* Fixme -- should determine the minimum and maximum charcode in the map */
int[] cid2gid = new int[65536];
List<Float> widths = new ArrayList<Float>();
int[] widthValues = ttf.getHorizontalMetrics().getAdvanceWidth();
for (int i = 0; i < cid2gid.length; i++) {
int glyph = unicodeMap.getGlyphId(i);
cid2gid[i] = glyph;
widths.add((float) i);
widths.add((float) i);
widths.add(widthValues[glyph] * scaling);
}
pdCidFont2.setCidToGid(cid2gid);
pdCidFont2.setWidths(widths);
pdCidFont2.setDefaultWidth(widths.get(0).longValue());
/* Now construct the type0 font that we actually return */
myType0Font pdFont0 = new myType0Font();
pdFont0.setDescendantFont(pdCidFont2);
pdFont0.setDescendantFonts(new COSObject(pdCidFont2.getCOSObject()));
pdFont0.setEncoding(COSName.IDENTITY_H);
pdFont0.setBaseFont(pdTtf.getBaseFont());
// pdfont0.setToUnicode(COSName.IDENTITY_H); XXX how to express identity
// mapping as ToUnicode program? */
return pdFont0;
}
public void destring(字符串文本)引发IOException{
余弦字符串=新余弦();
对于(int i=0;i>8);
追加字符串(c&0xff);
}
ByteArrayOutputStream缓冲区=新建ByteArrayOutputStream();
writePDF(缓冲区);
appendRawCommands(buffer.toByteArray());
附加命令(32);
AppendRaw命令(getISOBytes(“Tj\n”));
}
公共静态PDType0Font loadTTF(PDDocument文档,InputStream为)
抛出IOException{
/*加载我们将转换为Type0字体的字体*/
PDTrueTypeFont pdTtf=PDTrueTypeFont.loadTTF(单据,is);
TrueTypeFont ttf=pdTtf.gettFont();
CMAPEncodingEntry unicodeMap=null;
对于(CMAPEncodingEntry候选:ttf.getCMAP().getCmaps()){
if(candidate.getPlatformId()==CMAPTable.PLATFORM\u窗口
&&candidate.getPlatformEncodingId()=cMatable.ENCODING_UNICODE){
unicodeMap=候选人;
打破
}
}
if(unicodeMap==null){
抛出新的运行时异常(
“要用作CIDFont,TTF必须具有Windows平台Unicode编码”);
}
浮点缩放=1000f/ttf.getHeader().getUnitsPrem();
MyPDCIDFontType2Font pdCidFont2=新的MyPDCIDFontType2Font();
pdcdfont2.setBaseFont(pdTtf.getBaseFont());
pdCidFont2.setFontDescriptor((PDFontDescriptorDictionary)pdTtf
.getFontDescriptor());
/*Fixme——应该确定映射中的最小和最大字符码*/
int[]cid2gid=新int[65536];
列表宽度=新的ArrayList();
int[]widthValues=ttf.getHorizontalMetrics().getAdvanceWidth();
对于(int i=0;i
下面是打印的字符:
我不知道为什么这些字符断开连接我建议您尝试将ICU4J JAR添加到项目中:
可以通过应用和来编写阿拉伯语。(差异文件附在问题说明中)
我希望修补程序将应用于2.0版。我不熟悉PDFBox,但我认为问题在于:
font.setFontEncoding(新的WinAnScienceODing())代码>设置unicode编码而不是ansi编码。尝试使用本文档中的每个编码实现:两个问题。1) PDPageContentStream.drawString()
无法正确处理任何代码点超过255的Unicode字符,请参见欧元符号中出现的奇怪字符;2) (如@Rafael所述)winansienceoding
不包括阿拉伯语字符;但我仍然有相同的结果:PdfDocEncoding PdfDocEncoding=newpdfdocencoding();WinAnsionoding WinAnsionoding=新建WinAnsionoding();PDFDOCENCODE pdfEncode=新的PDFDOCENCODE();StandardEncoding StandardEncoding=新的StandardEncoding();类型1编码t1=新类型1编码(128);WinAnsionODing en=新的WinAnsionODing();在这里的例子中;他们将“byte[]commands=“(x)Tj”.getBytes();”。值“(x)Tj”从何处获得?我将JAR添加到我的项目中,但这并不能解决问题