PDFBox-如果设置为只读则不显示复选框 [英] PDFBox - checkbox is not displayed if set readonly

查看:203
本文介绍了PDFBox-如果设置为只读则不显示复选框的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用PDFBox生成PDF,我需要在其中添加一个复选框,该复选框需要预先设置为选中和只读.但是有些方法是行不通的.

I am generating PDF using PDFBox, where I need to add a checkbox, which needs to be preset to checked and readonly. But some how it does not work.

请找到以下代码,该代码在PDF上添加了该复选框:

Please find below code, which adds the checkbox on PDF:

import java.io.File;
import java.io.IOException;
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.form.PDAcroForm;
import org.apache.pdfbox.pdmodel.interactive.form.PDCheckbox;
import org.apache.pdfbox.pdmodel.interactive.form.PDField;

public class MyTest {
    public static void main(String arg[])  throws IOException, COSVisitorException
    {
        PDDocument document = new PDDocument();
        PDPage page = new PDPage(PDPage.PAGE_SIZE_LETTER);
        document.addPage(page);

        COSDictionary acroFormDict = new COSDictionary();
        acroFormDict.setItem(COSName.getPDFName("Fields"), new COSArray()); // Added this line for Tilman's comment
        PDAcroForm acroForm = new PDAcroForm(document, acroFormDict);
        document.getDocumentCatalog().setAcroForm(acroForm);


        float x = 10f;
        float y = page.getMediaBox().getHeight();  
        float yOffset = 15f;
        float yCurrent = y - yOffset;  

        COSDictionary cosDict = new COSDictionary();
        COSArray rect = new COSArray();
        rect.add(new COSFloat(x));
        rect.add(new COSFloat(yCurrent));
        rect.add(new COSFloat(x+20));
        rect.add(new COSFloat(yCurrent-20));

        cosDict.setItem(COSName.RECT, rect);
        cosDict.setItem(COSName.FT, COSName.getPDFName("Btn")); // Field Type
        cosDict.setItem(COSName.TYPE, COSName.ANNOT);
        cosDict.setItem(COSName.SUBTYPE, COSName.getPDFName("Widget"));
        cosDict.setItem(COSName.T, new COSString("testChk"));
        cosDict.setItem(COSName.DA, new COSString("/Helv 7 Tf 0 g"));

        PDCheckbox checkbox = new PDCheckbox(acroForm, cosDict);
//      checkbox.setReadonly(true);
//      checkbox.setFieldFlags(PDField.FLAG_READ_ONLY);
        checkbox.setValue("Yes");
//      checkbox.check();
        page.getAnnotations().add(checkbox.getWidget());                          
        acroForm.getFields().add(checkbox); // Added this line for Tilman's comment

        yCurrent = yCurrent - 20 - yOffset;

        File file = new File("C:\\pdf\\CheckBox\\CheckBoxSample1.pdf");
        System.out.println("Sample file saved at : " + file.getAbsolutePath());
        document.save(file);
        document.close();
    }

}

现在,如果您取消注释该行:

Now if you uncomment the line:

checkbox.setReadonly(true);

checkbox.setFieldFlags(PDField.FLAG_READ_ONLY);

该复选框将不再显示(或可能在此处,但未选中该值). 我正在使用PDFBox 1.8.10

The checkbox will no more displayed (or may be there but value is unchecked). I am using PDFBox 1.8.10

Adob​​e Reader 11和Foxit中的行为类似.

Behavior is similar in Adobe Reader 11 and Foxit.

如果我在生成PDF时未将框设置为只读,则在Adobe中,我会看到显示的复选框具有设置的值,但是当我使用Tab键将其聚焦时,它就会消失.然后再次聚焦(我单击复选框以外的其他地方),它再次出现.

Also if I generate the PDF without setting the box readonly, in Adobe, I see the checkbox displayed with value set, but when I bring focus on it using tab, it gets disappear. And again on focus out (I click somewhere else other than checkbox), it appears again.

似乎我错过了一件很小的事情,但找不到. 有什么帮助吗? 预先感谢.

It seems like I am missing a very small thing, but could not find out. Any help? Thanks in advance.

推荐答案

您需要使用PDAppearanceCharacteristicsDictionary类提供字段外观.这样可以解决上述问题.

You need to give field appearance using PDAppearanceCharacteristicsDictionary class. That will fix above issue.

请检查下面的示例代码:

Please check sample code below:

import java.io.File;
import java.io.IOException;

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.graphics.color.PDGamma;
import org.apache.pdfbox.pdmodel.interactive.annotation.PDAppearanceCharacteristicsDictionary;
import org.apache.pdfbox.pdmodel.interactive.form.PDAcroForm;
import org.apache.pdfbox.pdmodel.interactive.form.PDCheckbox;

public class MyCheckBox {
    public static void main(String arg[])  throws IOException, COSVisitorException
    {
        PDDocument document = new PDDocument();
        PDPage page = new PDPage(PDPage.PAGE_SIZE_LETTER);
        document.addPage(page);

        PDFont font = PDType1Font.HELVETICA;
        PDResources res = new PDResources();
        String fontName = res.addFont(font);
        String da = "/" + fontName + " 10 Tf 0 0.4 0 rg";


        COSDictionary acroFormDict = new COSDictionary(); 
        acroFormDict.setBoolean(COSName.getPDFName("NeedAppearances"), true);
        acroFormDict.setItem(COSName.FIELDS, new COSArray());
        acroFormDict.setItem(COSName.DA, new COSString(da));

        PDAcroForm acroForm =  new PDAcroForm(document, acroFormDict);
        acroForm.setDefaultResources(res);
        document.getDocumentCatalog().setAcroForm(acroForm);


        float x = 10f;
        float y = page.getMediaBox().getHeight();  
        float yOffset = 15f;
        float yCurrent = y - yOffset;  

        PDGamma colourBlack = new PDGamma();
        PDAppearanceCharacteristicsDictionary fieldAppearance = 
                new PDAppearanceCharacteristicsDictionary(new COSDictionary());
        fieldAppearance.setBorderColour(colourBlack);
        COSArray arr = new COSArray();
        arr.add(new COSFloat(227/255f));
        arr.add(new COSFloat(239/255f));
        arr.add(new COSFloat(1f));
        fieldAppearance.setBackground(new PDGamma(arr));

        COSDictionary cosDict = new COSDictionary();
        COSArray rect = new COSArray();
        rect.add(new COSFloat(x));
        rect.add(new COSFloat(yCurrent));
        rect.add(new COSFloat(x+20));
        rect.add(new COSFloat(yCurrent-20));

        cosDict.setItem(COSName.RECT, rect);
        cosDict.setItem(COSName.FT, COSName.getPDFName("Btn")); // Field Type
        cosDict.setItem(COSName.TYPE, COSName.ANNOT);
        cosDict.setItem(COSName.SUBTYPE, COSName.getPDFName("Widget"));
        cosDict.setItem(COSName.TU, new COSString("Test Checkbox with PDFBox"));
        cosDict.setItem(COSName.T, new COSString("testChk"));
        cosDict.setItem(COSName.DA, new COSString("/F0 10 Tf 0 0.4 0 rg"));
//        cosDict.setInt(COSName.FF, 49152);        //Radio Button Symbol
        cosDict.setInt(COSName.F, 4);
//        cosDict.setInt(COSName.FF, 16384);

        PDCheckbox checkbox = new PDCheckbox(acroForm, cosDict);
        checkbox.setFieldFlags(PDCheckbox.FLAG_READ_ONLY);
        checkbox.setValue("Yes");
//        checkbox.setValue("Off");

        checkbox.getWidget().setAppearanceCharacteristics(fieldAppearance);

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

        yCurrent = yCurrent - 20 - yOffset;

        File file = new File("C:\\pdf\\CheckBoxSample.pdf");
        System.out.println("Sample file saved at : " + file.getAbsolutePath());
        document.save(file);
        document.close();
    }

}

这篇关于PDFBox-如果设置为只读则不显示复选框的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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