PDFBox 中奇怪的组合框行为

Strange combobox behavior in PDFBox

我有这段代码可以在 PDF 文件中创建一个组合框。它有两个问题。

  1. 特殊字符(如 ö)在组合框打开时可以正确显示,但在组合框关闭时无法显示。
  2. 当我在 Acrobat 中打开 PDF、更改值并保存 PDF 时,组合框不知何故不见了。当我再次打开 PDF 时,它不再显示了。

我是不是把 PDFBox 搞砸了 类 或者可能是什么问题?

这是打开状态的图片:

这是一个处于关闭状态的:

    public class ComboTest {
        public static void main(String[] args) {

        PDFont font = PDType1Font.HELVETICA;
        Color color = Color.BLACK;
        float fontSize = 12;

        PDDocument document = new PDDocument();
        PDPage page = new PDPage(PDRectangle.A4);

        document.addPage(page);

        PDAcroForm acroForm = new PDAcroForm(document);
        PDComboBox comboBox = new PDComboBox(acroForm);
        comboBox.setPartialName("test");

        String defaultAppearanceString = "/" + font.getName() + " " + fontSize + " Tf "
                + 0 + " " + 0 + " " + 0 + " rg";
        comboBox.setDefaultAppearance(defaultAppearanceString);

        PDAnnotationWidget widget = new PDAnnotationWidget();
        widget.setRectangle(new PDRectangle(200, 200, 100, 20));
        widget.setAnnotationFlags(4);
        widget.setPage(page);
        widget.setParent(comboBox);

        List<String> exportValues = new ArrayList<>();
        List<String> displayValues = new ArrayList<>();

        displayValues.add("öne");
        displayValues.add("two");
        displayValues.add("thrée");

        exportValues.add("1");
        exportValues.add("2");
        exportValues.add("3");


        comboBox.setOptions(exportValues, displayValues);

        List<PDAnnotationWidget> widgets = new ArrayList<>();
        widgets.add(widget);
        try {
            page.getAnnotations().add(widget);
        } catch (IOException e) {
            e.printStackTrace();
        }

        comboBox.setWidgets(widgets);


        try {
            FileOutputStream output = new FileOutputStream("test.pdf");
            document.save(output);
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
    }

在代码末尾添加:

acroForm.getFields().add(comboBox);
document.getDocumentCatalog().setAcroForm(acroForm);

这可以确保您的 acroform 及其字段对于 PDF 是已知的。

关于特殊字符,将Helvetica字体的名称替换为"Helv",这是Adobe的标准名称。

更好、更干净的解决方案:设置默认资源。

PDResources dr = new PDResources();
dr.put(COSName.getPDFName("Helv"), font);
acroForm.setDefaultResources(dr);

您也可以使用 "Helv" 而不是 "Helv",但它必须与您的默认外观字符串相同。

所以现在完整的代码是:

public class ComboTest
{
    public static void main(String[] args)
    {

        PDFont font = PDType1Font.HELVETICA;
        Color color = Color.BLACK;
        float fontSize = 12;

        PDDocument document = new PDDocument();
        PDPage page = new PDPage(PDRectangle.A4);

        document.addPage(page);

        PDAcroForm acroForm = new PDAcroForm(document);
        PDComboBox comboBox = new PDComboBox(acroForm);
        comboBox.setPartialName("test");

        // Helv instead of Helvetica
        String defaultAppearanceString = "/Helv " + fontSize + " Tf "
                + 0 + " " + 0 + " " + 0 + " rg";
        comboBox.setDefaultAppearance(defaultAppearanceString);

        PDAnnotationWidget widget = new PDAnnotationWidget();
        widget.setRectangle(new PDRectangle(200, 200, 100, 20));
        widget.setAnnotationFlags(4);
        widget.setPage(page);
        widget.setParent(comboBox);

        List<String> exportValues = new ArrayList<>();
        List<String> displayValues = new ArrayList<>();

        displayValues.add("öne");
        displayValues.add("two");
        displayValues.add("thrée");

        exportValues.add("1");
        exportValues.add("2");
        exportValues.add("3");

        comboBox.setOptions(exportValues, displayValues);

        List<PDAnnotationWidget> widgets = new ArrayList<>();
        widgets.add(widget);
        try
        {
            page.getAnnotations().add(widget);
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }

        comboBox.setWidgets(widgets);

        // new
        acroForm.getFields().add(comboBox);
        document.getDocumentCatalog().setAcroForm(acroForm);
        PDResources dr = new PDResources();
        dr.put(COSName.getPDFName("Helv"), font);
        acroForm.setDefaultResources(dr);

        try
        {
            FileOutputStream output = new FileOutputStream("test.pdf");
            document.save(output);
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }

    }
}