PDFBox – 刷新来自Java的嵌套PDComboBox

huangapple go评论79阅读模式
英文:

PDFBox - Refreshing nested PDComboBox from Java

问题

我刚开始使用PDFBox,需要一些帮助。

我在互联网上搜索过,但没有找到任何有用的信息,并尝试了很多方法。

我需要从一个PDF文件中解析出数据,然后用Java填充一些字段,并从数据库中导出填充后的文件。我有几个嵌套的组合框,当我在第一个组合框中放入值时,它会显示该值的正确文本,但是当我在嵌套的组合框中放入值时,它显示的是值而不是文本,它没有根据第一个组合框刷新值的列表。

如果您通过PDF编辑器编辑PDF文件,则不会出现此问题。

以下是编辑后的代码:

public ByteArrayOutputStream parseToSmartPdf(final File file, final Map<String, String> pdfContentMap) {
    final ByteArrayOutputStream baos;
    try {
        final InputStream inputStream = new BufferedInputStream(new FileInputStream(file));
        final PDDocument pdfDocument = PDDocument.load(inputStream.readAllBytes());
        inputStream.close();
        final PDAcroForm pdfAcroForm = pdfDocument.getDocumentCatalog().getAcroForm();
        if (Objects.isNull(pdfAcroForm)) {
            throw new FileEmptyException();
        }

        for (final Map.Entry<String, String> entry : new TreeMap<>(pdfContentMap).entrySet()) {
            final String key = entry.getKey();
            final String value = entry.getValue();
            final PDField field = pdfAcroForm.getField(key);
            if ("Tx".equals(field.getFieldType())) {
                field.setValue(value);
            } else if ("Ch".equals(field.getFieldType())) {
                if (field instanceof PDComboBox) {
                    final PDComboBox pdComboBox = (PDComboBox) field;
                    pdComboBox.setValue(value);
                }
            }
        }
        baos = new ByteArrayOutputStream();
        pdfDocument.save(baos);
        pdfDocument.close();
    } catch (final IOException e) {
        throw new FileProcessingException();
    }
    return baos;
}

PDFBox版本:2.0.0(我也尝试过最新版本:2.0.21)

我正在使用以下链接中的PDF文件进行测试。
https://drive.google.com/file/d/1vKslaheP7ADlCca75X1jjd2f8Cca7AzU/view?usp=sharing

存在冲突的字段:

  • When and where -> World region <-> State/area
  • Aircraft information ->
    Manufacturer <-> Model
  • Flight details -> Last departure point ->
    Country <-> ICAO code
  • Flight details -> Planned destination ->
    Country <-> ICAO code

非常感谢您的支持。

英文:

I'm new using PDFBox and need some help.

I have searched on the internet, but I didn't find anything and have tried plenty of things.

I have to parse from a PDF file in order to fill out some fields from Java and export it filled out again, taking data from the database. I have several nested combo boxes and when I put the value in the first one, it shows the correct text for the value, but the problem arrives when I put the value in the nested combo box, it shows the value instead of the text, it doesn't refresh the value's list depend on the first combo box.

This problem doesn't happen if you edit the PDF file from a PDF editor.

public ByteArrayOutputStream parseToSmartPdf(final File file, final Map&lt;String, String&gt; pdfContentMap) {
    final ByteArrayOutputStream baos;
    try {
        final InputStream inputStream = new BufferedInputStream(new FileInputStream(file));
        final PDDocument pdfDocument = PDDocument.load(inputStream.readAllBytes());
        inputStream.close();
        final PDAcroForm pdfAcroForm = pdfDocument.getDocumentCatalog().getAcroForm();
        if (Objects.isNull(pdfAcroForm)) {
            throw new FileEmptyException();
        }

        for (final Map.Entry&lt;String, String&gt; entry : new TreeMap&lt;&gt;(pdfContentMap).entrySet()) {
            final String key = entry.getKey();
            final String value = entry.getValue();
            final PDField field = pdfAcroForm.getField(key);
            if (&quot;Tx&quot;.equals(field.getFieldType())) {
                field.setValue(value);
            } else if (&quot;Ch&quot;.equals(field.getFieldType())) {
                if (field instanceof PDComboBox) {
                    final PDComboBox pdComboBox = (PDComboBox) field;
                    pdComboBox.setValue(value);
                }
            }
        }
        baos = new ByteArrayOutputStream();
        pdfDocument.save(baos);
        pdfDocument.close();
    } catch (final IOException e) {
        throw new FileProcessingException();
    }
    return baos;
}

Edited:

PDFBox version: 2.0.0 (I tried with the latest version too: 2.0.21)

A link to the PDF file that I'm using to test.
https://drive.google.com/file/d/1vKslaheP7ADlCca75X1jjd2f8Cca7AzU/view?usp=sharing

Conflicting fields:

  • When and where -> World region <-> State/area
  • Aircraft information ->
    Manufacturer <-> Model
  • Flight details -> Last departure point ->
    Country <-> ICAO code
  • Flight details -> Planned destination ->
    Country <-> ICAO code

Thanks for the support beforehand.

答案1

得分: 1

感谢 @TilmanHausherr 的支持。

使用 PDFDebugger,您可以看到 PDF 文件针对“父”组合框的每个选项都有一个内部组合框,您可以获取选项值列表以加载“嵌套”组合框。

  1. 使用 PDFDebugger 打开 PDF 文件(您需要下载 PDFBox 应用的 JAR 文件):

    java -jar pdfbox-app-x.x.x.jar PDFDebugger <pdf_file_name>

  2. 激活以下选项以显示 PDF 内容并更轻松地检查它们:「View -> Show Internal Structure」

  3. 在组件树中转到「Root -> AcroForm -> Fields」,您可以看到所有组件及其属性、选项、值等。

知道各自的名称后,您可以使用以下代码加载「嵌套」组合框:

final PDField optionsValuesField = pdComboBox.getAcroForm().getField("optionsValuesFieldName");
final PDComboBox optionsValuesPdComboBox = (PDComboBox) optionsValuesField;

final PDField nestedPdComboBoxField = pdComboBox.getAcroForm().getField("nestedPdComboBoxName");
final PDComboBox nestedPdComboBox = (PDComboBox) nestedPdComboBoxField;

nestedPdComboBox.setOptions(optionsValuesPdComboBox.getOptionsExportValues(), optionsValuesPdComboBox.getOptionsDisplayValues());
英文:

Thanks to @TilmanHausherr for your support.

Using PDFDebugger you can see that PDF files have an internal combo box for each option of the "parent" combo box where you can take option-value list to load the "nested" combo box.

  1. Open the PDF file with PDFDebugger (you need to download the jar of PDFBox app):

    java -jar pdfbox-app-x.x.x.jar PDFDebugger <pdf_file_name>

  2. Activate the following option to show PDF content and check them easier: "View -> Show Internal Structure"

  3. In the components tree go to "Root -> AcroForm -> Fields" where you can see all the components and their attributes, options, values, etc.

When you know the respective names you can load the "nested" combo box with the following code:

final PDField optionsValuesField = pdComboBox.getAcroForm().getField(&quot;optionsValuesFieldName&quot;);
final PDComboBox optionsValuesPdComboBox = (PDComboBox) optionsValuesField;

final PDField nestedPdComboBoxField = pdComboBox.getAcroForm().getField(&quot;nestedPdComboBoxName&quot;);
final PDComboBox nestedPdComboBox = (PDComboBox) nestedPdComboBoxField;

nestedPdComboBox.setOptions(optionsValuesPdComboBox.getOptionsExportValues(), optionsValuesPdComboBox.getOptionsDisplayValues());

huangapple
  • 本文由 发表于 2020年9月24日 21:44:36
  • 转载请务必保留本文链接:https://go.coder-hub.com/64047832.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定