PdfBox编码符号货币欧元
我用Apache PDFBox库创build了一个PDF文档。 我的问题是在页面上绘制string时编码欧元货币符号,因为基本字体Helvetica不提供此字符。 如何将输出“þÿ¬”转换为符号“€”?
不幸的是,PDFBox的string编码还不完美(版本1.8.x)。 不幸的是,它在编码普通PDF对象中的string时使用相同的例程,就像在内容stream中编码string时那样,这是根本错误的。 因此,而不是使用PDPageContentStream.drawString
(它使用错误的编码),你必须自己翻译成正确的编码。
例如,而不是使用
contentStream.beginText(); contentStream.setTextMatrix(100, 0, 0, 100, 50, 100); contentStream.setFont(PDType1Font.HELVETICA, 2); contentStream.drawString("€"); contentStream.endText(); contentStream.close();
这导致了
你可以用一些像
contentStream.beginText(); contentStream.setTextMatrix(100, 0, 0, 100, 50, 100); contentStream.setFont(PDType1Font.HELVETICA, 8); byte[] commands = "(x) Tj ".getBytes(); commands[1] = (byte) 128; contentStream.appendRawCommands(commands); contentStream.endText(); contentStream.close();
导致
如果您想知道如何使用128作为€的字节代码,请查看PDF规范ISO 32000-1 ,附录D.2, 拉丁字符集和编码 ,其中指示八进制值200(十进制128) €在WinAnsiEncoding符号。
PS :另一种方法同时也是由其他答案提出的,在欧元符号的情况下,
contentStream.beginText(); contentStream.setTextMatrix(100, 0, 0, 100, 50, 100); contentStream.setFont(PDType1Font.HELVETICA, 8); contentStream.drawString(String.valueOf(Character.toChars(EncodingManager.INSTANCE.getEncoding(COSName.WIN_ANSI_ENCODING).getCode("Euro")))); contentStream.endText(); contentStream.close();
这确实也画了'€'符号。 但是,即使这种方法看起来比较干净 (它不使用byte
数组,也不会手动构build实际的PDF数据stream操作),但它本身就是很脏的 :
要使用一个破坏的方法,它实际上是以正确的方式打破了它的string参数,以抵消该方法中的错误。
因此,如果PDFBox的人们决定修复破碎的PDFBox方法,这个看似干净的解决方法代码将会开始失败,因为它会提供固定方法破坏的input数据。
无可否认,我怀疑他们会修复2.0.0之前的这个bug(在2.0.0的固定方法有一个不同的名字),但一个永远不知道…
这对我工作:
char symbol = '€'; Encoding e = EncodingManager.INSTANCE.getEncoding(COSName.WIN_ANSI_ENCODING); String toPDF = String.valueOf(Character.toChars(e.getCode(e.getNameFromCharacter(symbol))));`
创造了许多的解决scheme:
String text = "Lorem ipsum dolor sit amet, consectetur adipisici € 1.234,56 " + "elit, sed eiusmod tempor incidunt ut labore et dolore magna aliqua."; contentStream.beginText(); contentStream.setFont(font, 12); contentStream.moveTextPositionByAmount(10, 500); char[] tc = text.toCharArray(); StringBuilder te = new StringBuilder(); Encoding e = EncodingManager.INSTANCE.getEncoding(COSName.WIN_ANSI_ENCODING); for (int i = 0; i < tc.length; i++) { Character c = tc[i]; int code = 0; if(Character.isWhitespace(c)){ code = e.getCode("space"); }else{ code = e.getCode(e.getNameFromCharacter(c)); } te.appendCodePoint(code); } contentStream.drawString( te.toString() ); contentStream.endText(); contentStream.close();
对于字符空间是未知的代码,因为名称“spacehackarabic”没有描述到WinAnsiEncoding,我不知道为什么返回这个名字。 无论如何,我已经validation了字符空间,但是也可以将这个名称映射到等效的代码空间:
e.addCharacterEncoding( 040, "spacehackarabic" );
谢谢…
也许是为时已晚,但我使用它:
String toPDF = String.valueOf(Character.toChars(e.getCode("Euro")));
确保你把大写“E”,如果你做“欧元”抛出一个错误。 请看看这个链接,帮助我很多http://partners.adobe.com/public/developer/en/opentype/glyphlist.txt