Java PDFBox-如果设置为只读,则不显示复选框
我正在使用PDFBox生成PDF,我需要在其中添加一个复选框,该复选框需要预设为选中和只读。但有些人认为它不起作用 请查找以下代码,其中添加了PDF上的复选框:Java PDFBox-如果设置为只读,则不显示复选框,java,pdf,pdfbox,Java,Pdf,Pdfbox,我正在使用PDFBox生成PDF,我需要在其中添加一个复选框,该复选框需要预设为选中和只读。但有些人认为它不起作用 请查找以下代码,其中添加了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 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();
}
}
现在,如果取消对该行的注释:
checkbox.setReadonly(true);
或
复选框将不再显示(或可能存在,但值未选中)。
我正在使用PDFBox 1.8.10
AdobeReader11和Foxit中的行为类似
另外,如果我在Adobe中生成PDF而不将框设置为只读,我会看到复选框显示为值集,但当我使用tab将焦点集中在它上时,它会消失。再次在焦点离开时(我单击复选框以外的其他位置),它再次出现
好像我错过了一件很小的事情,但却找不到。
有什么帮助吗?
提前感谢。您需要使用PDAppearanceCharacteristicsDictionary类给出字段外观。这将解决上述问题 请检查下面的示例代码:
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();
}
}
我没有看到任何复选框,尽管我看到了它应该在哪里。您没有将复选框添加到acroform。可能是你在编辑问题的更大代码时意外删除了这一行吗?Tilman,谢谢你的回复。我已经更新了问题并添加了两行注释“为Tilman的注释添加了这行”。希望我做得对。即使在代码改变之后,我也找不到行为上的任何改变。可悲的是,我仍然有一个问题,那就是我永远看不到它。您可以尝试添加acroFormDict.setBoolean(COSName.getPDFName(“needAppearancess”),true);如果仍然不起作用,请询问用户邮件列表。如果你去那里,发布你的代码,并将结果上传到某个地方(你不能附加它)。我们的acroform专家在那里(但我不会向你保证任何事情)。没问题。谢谢你的反馈。我已经把问题放在邮件列表上了。如果您需要参考我的PDF,请点击“下载ZIP”按钮,解压缩下载的文件,其中将包含生成的PDF文件。很抱歉造成混淆,旧代码的行为“cosDict.setItem(COSName.DA,new costring(/Helv 7 Tf 0 g”);”在注释中,由于此原因,您无法看到复选框。取消行注释后,将显示复选框,但问题将出现,如问题所述-即在焦点或只读设置上,复选框将消失。是否有其他人在思考。。。所有这些代码都是为了一个复选框?!?!这个代码有什么问题吗,请让我知道,以便可以更正!!Nirav-抱歉,不是对代码的批评。。。更多关于pdfbox的评论。感谢您提供的示例-它帮助我解决了我的问题。与PDFBOX-2相比,编码将减少,acroform字段控件将易于从开发人员的角度创建和操作:)
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();
}
}