PDFBox and chinese characters

2019-09-06 14:30发布

问题:

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).

Loading of the fonts is done using

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

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

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

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

Thanks for any help

EDITED

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

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 ..

Thanks again

回答1:

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


标签: java pdf pdfbox