当前位置: 首页 > 面试题库 >

在使用PDFBOX生成的PDF中,“保存的文本字段”值无法正确显示

葛修永
2023-03-14
问题内容
import java.io.IOException;

import javax.swing.text.BadLocationException;

import org.apache.pdfbox.cos.COSArray;
import org.apache.pdfbox.cos.COSDictionary;
import org.apache.pdfbox.cos.COSFloat;
import org.apache.pdfbox.cos.COSName;
import org.apache.pdfbox.cos.COSString;
import org.apache.pdfbox.exceptions.COSVisitorException;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.interactive.action.PDAnnotationAdditionalActions;
import org.apache.pdfbox.pdmodel.interactive.action.type.PDActionJavaScript;
import org.apache.pdfbox.pdmodel.interactive.form.PDAcroForm;
import org.apache.pdfbox.pdmodel.interactive.form.PDTextbox;
import org.junit.Test;

public class TestPDTextbox {
    @Test
    public void Sample1 () throws IOException, COSVisitorException, BadLocationException {


        PDDocument doc = new PDDocument();
        PDPage page = new PDPage();
        doc.addPage(page);

        COSDictionary acroFormDict = new COSDictionary(); 
//        acroFormDict.setBoolean(COSName.getPDFName("NeedAppearances"), true);
        acroFormDict.setItem(COSName.getPDFName("Fields"), new COSArray());

        PDAcroForm acroForm = new PDAcroForm(doc, acroFormDict);
        doc.getDocumentCatalog().setAcroForm(acroForm);

        COSDictionary cosDict1 = new COSDictionary();
        COSArray rect1 = new COSArray();
        rect1.add(new COSFloat(100));
        rect1.add(new COSFloat(700));
        rect1.add(new COSFloat(200));
        rect1.add(new COSFloat(750));

        cosDict1.setItem(COSName.RECT, rect1);
        cosDict1.setItem(COSName.FT, COSName.getPDFName("Tx")); // Field Type
        cosDict1.setItem(COSName.TYPE, COSName.ANNOT);
        cosDict1.setItem(COSName.SUBTYPE, COSName.getPDFName("Widget"));
        cosDict1.setItem(COSName.T, new COSString("tx1"));
        cosDict1.setItem(COSName.DA, new COSString("/Helv 7 Tf 0 g"));
        cosDict1.setItem(COSName.V, new COSString("Test Value1"));

        PDTextbox textbox = new PDTextbox(doc.getDocumentCatalog().getAcroForm(), cosDict1);

//      textbox.setValue("Test Value");

        page.getAnnotations().add(textbox.getWidget());
        acroForm.getFields().add(textbox);

         doc.save("C:\\PDF\\SampleTextbox.pdf");
         doc.close();
    }
}

问题1, 我创建了一个文本字段,如上面的代码所示,并尝试使用textbox.setValue(“ Test
Value”);设置值。方法,但显示如下错误:

java.io.IOException: Error: Don't know how to calculate the position for non-simple fonts
    at org.apache.pdfbox.pdmodel.interactive.form.PDAppearance.getTextPosition(PDAppearance.java:1037)
    at org.apache.pdfbox.pdmodel.interactive.form.PDAppearance.insertGeneratedAppearance(PDAppearance.java:558)
    at org.apache.pdfbox.pdmodel.interactive.form.PDAppearance.setAppearanceValue(PDAppearance.java:338)
    at org.apache.pdfbox.pdmodel.interactive.form.PDVariableText.setValue(PDVariableText.java:131)
    at sample.pdfbox.example.TestPDTextbox.Sample1(TestPDTextbox.java:54)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

第2期

为了解决问题#1,如果我使用cosDictionary属性(即cosDict1.setItem(COSName.V,new COSString(“ Test
Value1”)))设置textBox的值;

然后在Adobe Reader中,无法正确填充textBox的值。我必须单击文本框,然后才显示值,一旦我从字段中移出,值将再次变得不可见。

问题#3

为了解决问题2,我需要将needAppearances标志设置为true,如下所示,然后在PDF中正确显示该字段值之后。但是在采用此html" target="_blank">解决方案之后,一旦用户更改字段值,我将无法提取/解析P​​DF字段,而我们再次解析此PDF。

注意:- 这个问题存在于Adobe Reader中,在这里打开PDF时它也会发出一些信息,例如 将表单字段固定起来
。并且一旦我保存PDF并尝试解析acroform字段,就会发现所有字段都被重置或为null。不能提取任何字段名称或字段值。

因此,使用acroFormDict.setBoolean(COSName.getPDFName(“ NeedAppearances”),true);
代码中的代码似乎有风险,并且会在PDF解析中产生其他问题,因此无法使用。

COSDictionary acroFormDict = new COSDictionary(); 
        acroFormDict.setBoolean(COSName.getPDFName("NeedAppearances"), true);
        acroFormDict.setItem(COSName.getPDFName("Fields"), new COSArray());

        PDAcroForm acroForm = new PDAcroForm(doc, acroFormDict);
        doc.getDocumentCatalog().setAcroForm(acroForm);

我认为,我需要为文本字段设置PDAppearanceDictionary,但是我不知道这样做以及我是否需要为每个字段或在acroform级别进行设置。

请帮助我解决该问题。我正在使用PDFBOX版本1.8.10。


问题答案:

在上述问题中,我通过将页面资源添加到acroform中来修复了Issue#1,并为文本使用了正确的Default
Appearance字符串。现在,我不再需要将needsAppearance标志设置为true。

        PDFont font = PDType1Font.HELVETICA;
        PDResources res = new PDResources();
        String fontName = res.addFont(font);
        String defaultAppearance = "/"+fontName+" 7 Tf 0 g";

        COSDictionary acroFormDict = new COSDictionary(); 
        acroFormDict.setBoolean(COSName.getPDFName("NeedAppearances"), false);
        acroFormDict.setItem(COSName.getPDFName("Fields"), new COSArray());
        acroFormDict.setItem(COSName.DA, new COSString(defaultAppearance));

        PDAcroForm acroForm = new PDAcroForm(doc, acroFormDict);
        acroForm.setDefaultResources(res);

检查以下完整的更正代码:

import java.io.IOException;

import javax.swing.text.BadLocationException;

import org.apache.pdfbox.cos.COSArray;
import org.apache.pdfbox.cos.COSDictionary;
import org.apache.pdfbox.cos.COSFloat;
import org.apache.pdfbox.cos.COSName;
import org.apache.pdfbox.cos.COSString;
import org.apache.pdfbox.exceptions.COSVisitorException;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.PDResources;
import org.apache.pdfbox.pdmodel.font.PDFont;
import org.apache.pdfbox.pdmodel.font.PDType1Font;
import org.apache.pdfbox.pdmodel.interactive.form.PDAcroForm;
import org.apache.pdfbox.pdmodel.interactive.form.PDTextbox;
import org.junit.Test;

public class TestPDTextbox {
    @Test
    public void Sample1 () throws IOException, COSVisitorException, BadLocationException {


        PDDocument doc = new PDDocument();
        PDPage page = new PDPage();
        doc.addPage(page);

        PDFont font = PDType1Font.HELVETICA;
        PDResources res = new PDResources();
        String fontName = res.addFont(font);
        String defaultAppearance = "/"+fontName+" 7 Tf 0 g";

        COSDictionary acroFormDict = new COSDictionary(); 
        acroFormDict.setBoolean(COSName.getPDFName("NeedAppearances"), false);
        acroFormDict.setItem(COSName.getPDFName("Fields"), new COSArray());
        acroFormDict.setItem(COSName.DA, new COSString(defaultAppearance));

        PDAcroForm acroForm = new PDAcroForm(doc, acroFormDict);
        acroForm.setDefaultResources(res);

        doc.getDocumentCatalog().setAcroForm(acroForm);

        COSDictionary cosDict1 = new COSDictionary();
        COSArray rect1 = new COSArray();
        rect1.add(new COSFloat(100));
        rect1.add(new COSFloat(700));
        rect1.add(new COSFloat(200));
        rect1.add(new COSFloat(750));

        cosDict1.setItem(COSName.RECT, rect1);
        cosDict1.setItem(COSName.FT, COSName.getPDFName("Tx")); // Field Type
        cosDict1.setItem(COSName.TYPE, COSName.ANNOT);
        cosDict1.setItem(COSName.SUBTYPE, COSName.getPDFName("Widget"));
        cosDict1.setItem(COSName.T, new COSString("tx1"));
        cosDict1.setItem(COSName.DA, new COSString(defaultAppearance));
//        cosDict1.setItem(COSName.V, new COSString("Test Value1"));

        PDTextbox textbox = new PDTextbox(doc.getDocumentCatalog().getAcroForm(), cosDict1);

      textbox.setValue("Test Value");

        page.getAnnotations().add(textbox.getWidget());
        acroForm.getFields().add(textbox);

         doc.save("C:\\PDF\\SampleTextbox.pdf");
         doc.close();
    }
}


 类似资料:
  • 问题1我创建了一个文本字段,如上面的代码所示,并尝试使用TextBox.setValue(“测试值”)设置值;方法,但它给出的错误如下所示: 问题3 为了解决问题#2,我需要将NeedExceptions标志设置为true,如下所示,然后在PDF中正确显示该字段值。但是在这个解决方案之后,一旦用户改变了字段值,我们再次解析这个PDF字段,我就无法提取/解析PDF字段。 注意:-这个问题存在于Ado

  • 目前我们正在使用Aspose。NET库生成excel并导出为PDF。pdf由多种语言组成,如英语、汉语和泰米尔语。对于英语和汉语来说,这很好,但对于泰米尔语来说,它有拼写问题。 例如, "போல்" 的第一个和第二个字母将翻转。 我们尝试了“Latha”字体和“Arial Unicode MS”字体,文本显示,但字母翻转。我们也尝试过“InaiMathi”字体,但文本没有显示出来。 我也尝试使用不

  • 我试图通过“保存数据”按钮从文本字段中获取数据,然后在单击“显示数据”按钮时在文本小部件中显示该数据。我正在使用SharedPreferences依赖项。我已经完成了代码,但有一个问题,每当我单击“Show data”按钮时,它只显示来自第二个文本字段的数据,如下所示:LastName null 结果应该是:FirstName LastName 这是保存数据 这是演出数据

  • 我有一个由LiberOffice Draw 4.1.0.4创建的PDF表格。 表单包含文本字段、复选框和单选按钮 在我为字段设置值并使用PDFBox(2.0.21)展平表单后,无法显示字段值 我认为这可能是该字段注释的外观问题,但我不知道如何使其正确 测试PDF

  • 我正在使用"pdfbox-app-2.0.0-RC2.jar" 我创建了一个类,它缩小了pdf内容,并在指定的坐标处创建了带有此内容的新pdf。 我的问题是,如果一个pdf文件被修改并添加了新内容,那么缩小后的文件中就会缺少这些内容。 以下是我的方法:

  • 生成PDF框 正如您所看到的,左侧的签名面板是无效的,但左侧的签名字段是存在的并且可以工作。 我用PDFTRON生成相同的PDF。这就是结果: 生成的PDF Tron 在这种情况下,左侧的签名面板正确显示签名字段的存在。 我想获得这第二个案例(正确),但我不明白为什么PDF框可以这样做。 多谢