PDFBox和汉字 [英] PDFBox and chinese characters

查看:732
本文介绍了PDFBox和汉字的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用pdfbox 1.8,并且试图用汉字填写pdf表单,但我得到的只是奇怪的字符.我得到了一个ttc文件(uming.ttc),并使用字体伪造导出了ttf文件(现在我正尝试仅使用一种导出字体).

I am using pdfbox 1.8 and I am trying to fill a pdf form with chinese character but all I got is strange characters. I got a ttc file (uming.ttc) and using font forge I exported ttf file (right now I am tryng to use only one of the exported fonts).

使用以下字体加载字体

    InputStream is = ..
    PDTrueTypeFont font = PDTrueTypeFont.loadTTF(doc, is);

我正在使用以下代码编写pdf字段(我在stackoverflow中找到了pdf字段,但目前找不到)

and I am writing the pdf field using the following code (that I found here in stackoverflow but currently I can't found it)

    protected void setPDFFieldAndFont(String fieldName, String keyFontName, Object... values) {
    try {
        PDField pdField = pdfForm.getField(fieldName);
        if (pdField == null) {
            return;
        }
        // append fields to create a new textfield
        Filler filler = new Filler();
        filler.append(values);
        String textFieldString = filler.toString();
        String fontName = key2FontName.get(keyFontName);
        COSDictionary dict = pdField.getDictionary();
        COSString defaultAppearance = (COSString) dict
                .getDictionaryObject(COSName.DA);
        if (defaultAppearance != null)
        {
            dict.setString(COSName.DA, "/" + fontName + " 11 Tf");
        }
        if (pdField instanceof PDTextbox)
        {
            PDTextbox textbox = new PDTextbox(pdfForm, dict);
            //PDTextbox textbox = (PDTextbox) pdField;
            textbox.setValue(textFieldString);

        }
    } catch (IOException e) {
        throw new IllegalStateException("Invalid field name: " + fieldName, e);
    }
}

我已经阅读到pdfbox2.0支持unicode,我需要使用这个新版本吗?

I have read that pdfbox2.0 supports unicode do I need to use this new version ?

使用font-forge我已经看到我的ttf字体已编码ISO-10646-1.

Using font-forge I have seen that my ttf font has encoding ISO-10646-1.

感谢您的帮助

已编辑

按照Tilman Hausherr的要求,我尝试了EmbeddedFonts.java,它可以正常工作,但是我以另一种方式填写了表格.我创建了一个主要样本:

As asked by Tilman Hausherr I tried EmbeddedFonts.java and it works fine but I am filling the form in a different way. I created a main sample:

public static void main(String[] args)  throws IOException {

    String pdfform = "D:\\form.pdf";

    PDDocument doc = PDDocument.load(new File(pdfform));
    PDType0Font font = PDType0Font.load(doc, new File("D:\\fonts\\UMingCN.ttf"));
    PDAcroForm acroForm = doc.getDocumentCatalog().getAcroForm();

    PDResources res = acroForm.getDefaultResources();
    if (res == null){
        res = new PDResources();
    }
    COSName fontName = res.add(font);
    acroForm.setDefaultResources(res);



    PDField pdField = acroForm.getField("personalInformation_fullName");
    if (pdField == null) {
        return;
    }
    COSDictionary dict = pdField.getCOSObject();
    COSString defaultAppearance = (COSString) dict.getDictionaryObject(COSName.DA);
    if (defaultAppearance != null)
    {
        dict.setString(COSName.DA, "/" + fontName.getName() + " 11 Tf");
    }
    if (pdField instanceof PDTextField)
    {
        PDTextField textbox = new PDTextField(acroForm);
        textbox.getCOSObject().addAll(dict);

        textbox.setValue("保保保");
    }

    doc.save("example2.pdf");
    doc.close();
}

,但不填充任何内容.在调试中,代码转到textbox.setValue,但是保存的pdfform没有在pdf中设置的值. 可能我缺少一些东西..

but it does not fill anything. In debug the code goes to textbox.setValue but the pdfform saved does not have the value set in the pdf. Probably I am missing something ..

再次感谢

推荐答案

我通过将文本转换为图像来解决了PdfBox和中文(日语,韩语以及任何其他字体)的问题

I solved the issues with PdfBox and chinese (japanese, korean, and any other font) by turning text into image, like this

void writeLine(String text, int x, int y, int width, int height,
           Font font, Color color, PDPageContentStream contentStream, PDDocument document) throws IOException {

    try (
        ByteArrayOutputStream baos = new ByteArrayOutputStream()
    ) {
        int scale = 2;
        BufferedImage img = new BufferedImage(width * scale, height * scale, BufferedImage.TYPE_INT_ARGB);
        Graphics2D g2d = img.createGraphics();
        g2d.setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION, RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY);
        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
        g2d.setRenderingHint(RenderingHints.KEY_COLOR_RENDERING, RenderingHints.VALUE_COLOR_RENDER_QUALITY);
        g2d.setRenderingHint(RenderingHints.KEY_DITHERING, RenderingHints.VALUE_DITHER_ENABLE);
        g2d.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON);
        g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
        g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_SPEED);
        g2d.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE);
        g2d.setFont(font);
        g2d.setColor(color);
        g2d.scale(scale,scale);
        g2d.drawString(text, 0, g2d.getFontMetrics().getAscent());
        g2d.dispose();

        ImageIO.write(img, "png", baos);
        baos.flush();
        baos.close();

        contentStream.drawImage(PDImageXObject.createFromByteArray(
            document,baos.toByteArray(), ""), x, y, width, height);
    }
}

这篇关于PDFBox和汉字的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆