PdfBox编码符号货币欧元

时间:2014-03-07 20:46:01

标签: java pdfbox

我使用Apache PDFBox库创建了一个PDF文档。我的问题是在页面上绘制字符串时编码欧元货币符号,因为基本字体Helvetica不提供此字符。如何将输出“þÿ¬”转换为符号“€”?。

4 个答案:

答案 0 :(得分:10)

不幸的是,PDFBox的字符串编码远非完美(版本1.8.x)。不幸的是,它在编码通用PDF对象中的字符串时使用相同的例程,就像在内容流中编码字符串时一样,这是根本错误的。因此,您不必使用PDPageContentStream.drawString(使用错误的编码),而是必须自己转换为正确的编码。

E.g。而不是使用

    contentStream.beginText();
    contentStream.setTextMatrix(100, 0, 0, 100, 50, 100);
    contentStream.setFont(PDType1Font.HELVETICA, 2);
    contentStream.drawString("€");
    contentStream.endText();
    contentStream.close();

导致

€ wrong encoding

你可以使用像

这样的东西
    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();

导致

€ correct encoding

如果您想知道如何使用128作为€的字节代码,请查看PDF规范ISO 32000-1,附件D.2,拉丁字符集和编码表示WinAnsiEncoding中€符号的八进制值200(十进制128)。


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数组,它也不会手动构建实际的PDF流操作),它的是脏的自己的方式:

要使用破坏的方法,它实际上以正确的方式打破其字符串参数以抵消方法中的错误。

因此,如果PDFBox人员决定修复损坏的PDFBox方法,这里看似干净的解决方法代码将开始失败,因为它会提供固定方法损坏的输入数据。

不可否认,我怀疑他们会在2.0.0之前修复这个错误(并且在2.0.0中固定方法有不同的名称),但是人们永远不会知道......

答案 1 :(得分:1)

这对我有用:

char symbol = '€';

Encoding e = EncodingManager.INSTANCE.getEncoding(COSName.WIN_ANSI_ENCODING);

String toPDF = String.valueOf(Character.toChars(e.getCode(e.getNameFromCharacter(symbol))));`

答案 2 :(得分:0)

创建了众多解决方案:

        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();

对于角色空间,它的未知代码因为名称&#34; spacehackarabic&#34;没有描述成WinAnsiEncoding,我不知道为什么要返回这个名字。无论如何,我有验证字符空格,但它也可能将此名称映射到等效的代码空间:

e.addCharacterEncoding( 040, "spacehackarabic" );

...谢谢

答案 3 :(得分:0)

也许为时已晚,但我是这样做的:

fetch_response

确保将大写“E”,如果你执行“euro”会抛出错误。请看一下这个链接,它对我有很大的帮助http://partners.adobe.com/public/developer/en/opentype/glyphlist.txt