PDF-Checkbox - 在没有 JavaScript 的情况下选中一个并取消选中另一个
PDF-Checkbox - check one and uncheck another without JavaScript
在我的项目中,我需要 3 个复选框,它们应该像单选按钮一样工作。但是单选按钮在 Adobe Reader 中有一些缺点。出于这个原因,我必须使用复选框。有一个非常有趣的答案,但我不明白如何使用 iText 完成此操作:
Java iText and custom Radiobutton behaviour
在这种情况下,任何人——尤其是这篇文章的作者 Lonzak——都可以帮助我吗?谢谢和亲切的问候,德克
我认为解决方案是修复您当前的代码。以下示例创建了 3 个单选按钮,并且都包含一个叉号。它基于 itext 5,您可能需要针对 itext 7 对其进行一些调整。
Document document = new Document(PageSize.A4, 50, 50, 50, 50);
PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream("output.pdf"));
document.open();
RadioCheckField bt = new RadioCheckField(writer, new Rectangle(261, 576, 279, 594), "radio", "value1");
bt.setCheckType(RadioCheckField.TYPE_CROSS);
bt.setBackgroundColor(BaseColor.WHITE);
//bt.setBorderStyle(PdfBorderDictionary.STYLE_SOLID);
bt.setBorderColor(BaseColor.BLACK);
bt.setTextColor(BaseColor.BLACK);
bt.setBorderWidth(BaseField.BORDER_WIDTH_THIN);
bt.setChecked(false);
PdfFormField f1 = bt.getRadioField();
bt.setOnValue("value2");
bt.setChecked(true);
bt.setBox(new Rectangle(287, 577, 305, 595));
PdfFormField f2 = bt.getRadioField();
bt.setChecked(false);
PdfFormField top = bt.getRadioGroup(true, false);
bt.setOnValue("value3");
bt.setBox(new Rectangle(314, 578, 332, 596));
PdfFormField f3 = bt.getRadioField();
top.addKid(f1);
top.addKid(f2);
top.addKid(f3);
writer.addAnnotation(top);
document.close();
更新:这是您使用 iText7 的代码,但是似乎有一个 bug,因此单选按钮的检查样式没有改变.也许 itext 的人可以说更多...
PdfDocument pdfDoc = new PdfDocument(new PdfWriter("output7.pdf"));
Document doc = new Document(pdfDoc);
PdfButtonFormField radioGroup = PdfFormField.createRadioGroup(pdfDoc, "ExampleGroup", "");
radioGroup.setPage(1);
pdfDoc.addNewPage();
PdfFormField field1 = PdfFormField.createRadioButton(pdfDoc, new Rectangle(261, 576, 18, 18), radioGroup, "value1");
field1.setCheckType(PdfFormField.TYPE_CROSS);
field1.setValue("value1");
field1.regenerateField();
PdfFormField field2 = PdfFormField.createRadioButton(pdfDoc, new Rectangle(287, 577, 18, 18), radioGroup, "value2");
field2.setCheckType(PdfFormField.TYPE_CROSS);
field2.regenerateField();
PdfFormField field3 = PdfFormField.createRadioButton(pdfDoc, new Rectangle(314, 578, 18, 18), radioGroup, "value3");
field3.setCheckType(PdfFormField.TYPE_CROSS);
field3.regenerateField();
PdfAcroForm.getAcroForm(pdfDoc, true).addField(radioGroup);
doc.close();
iText 7 的最终解决方案:
public static void main(String[] args) throws Exception {
// RadioButton with cross instead of bullet.
final String filename = "SampleRadioButton.pdf";
final float boxLength = 20;
final float crossWidth = 1;
final String[] languages = { "Dutch", "English", "French" };
try (PdfWriter writer = new PdfWriter(filename); PdfDocument pdfDoc = new PdfDocument(writer); Document doc = new Document(pdfDoc)) {
pdfDoc.addNewPage();
final PdfAcroForm form = PdfAcroForm.getAcroForm(pdfDoc, true);
final PdfButtonFormField radioGroup = PdfFormField.createRadioGroup(pdfDoc, "Language", languages[1]);
int count = 0;
for (final String language : languages) {
count++;
// button
final Rectangle rect = new Rectangle(40, 800 - (count * 30), boxLength, boxLength);
final PdfFormField radioButton = PdfFormField.createRadioButton(pdfDoc, rect, radioGroup, language);
final PdfDictionary radioDict = radioButton.getPdfObject();
final PdfDictionary mk = new PdfDictionary();
mk.put(PdfName.CA, new PdfString("8")); // check=4, circle=1, cross=8, diamond=u, square=n, star=H
radioDict.put(PdfName.MK, mk);
radioButton.setVisibility(PdfFormField.VISIBLE);
editAppearance(pdfDoc, radioButton, language, boxLength, crossWidth);
// text
final Paragraph para = new Paragraph(language).setFontSize(18);
doc.showTextAligned(para, 70, 800 - (count * 30), TextAlignment.LEFT);
}
form.addField(radioGroup);
}
Desktop.getDesktop().open(new File(filename));
}
private static void editAppearance(PdfDocument pdfDoc, PdfFormField radioButton, String value, float length, float crossWidth) {
final PdfStream streamOn = (PdfStream) new PdfStream().makeIndirect(pdfDoc);
final PdfCanvas canvasOn = new PdfCanvas(streamOn, new PdfResources(), pdfDoc);
final Rectangle rect = new Rectangle(0, 0, length, length);
final PdfFormXObject xObjectOn = new PdfFormXObject(rect);
canvasOn.saveState();
canvasOn.setStrokeColor(ColorConstants.BLACK).setLineWidth(crossWidth);
// bottom left to top right
canvasOn.moveTo(0, 0).lineTo(length, length).stroke();
// Top left to bottom right
canvasOn.moveTo(0, length).lineTo(length, 0).stroke();
canvasOn.restoreState();
xObjectOn.getPdfObject().getOutputStream().writeBytes(streamOn.getBytes());
final PdfWidgetAnnotation widget = radioButton.getWidgets().get(0);
widget.setNormalAppearance(new PdfDictionary());
widget.getNormalAppearanceObject().put(new PdfName(value), xObjectOn.getPdfObject());
}
}
在我的项目中,我需要 3 个复选框,它们应该像单选按钮一样工作。但是单选按钮在 Adobe Reader 中有一些缺点。出于这个原因,我必须使用复选框。有一个非常有趣的答案,但我不明白如何使用 iText 完成此操作:
Java iText and custom Radiobutton behaviour
在这种情况下,任何人——尤其是这篇文章的作者 Lonzak——都可以帮助我吗?谢谢和亲切的问候,德克
我认为解决方案是修复您当前的代码。以下示例创建了 3 个单选按钮,并且都包含一个叉号。它基于 itext 5,您可能需要针对 itext 7 对其进行一些调整。
Document document = new Document(PageSize.A4, 50, 50, 50, 50);
PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream("output.pdf"));
document.open();
RadioCheckField bt = new RadioCheckField(writer, new Rectangle(261, 576, 279, 594), "radio", "value1");
bt.setCheckType(RadioCheckField.TYPE_CROSS);
bt.setBackgroundColor(BaseColor.WHITE);
//bt.setBorderStyle(PdfBorderDictionary.STYLE_SOLID);
bt.setBorderColor(BaseColor.BLACK);
bt.setTextColor(BaseColor.BLACK);
bt.setBorderWidth(BaseField.BORDER_WIDTH_THIN);
bt.setChecked(false);
PdfFormField f1 = bt.getRadioField();
bt.setOnValue("value2");
bt.setChecked(true);
bt.setBox(new Rectangle(287, 577, 305, 595));
PdfFormField f2 = bt.getRadioField();
bt.setChecked(false);
PdfFormField top = bt.getRadioGroup(true, false);
bt.setOnValue("value3");
bt.setBox(new Rectangle(314, 578, 332, 596));
PdfFormField f3 = bt.getRadioField();
top.addKid(f1);
top.addKid(f2);
top.addKid(f3);
writer.addAnnotation(top);
document.close();
更新:这是您使用 iText7 的代码,但是似乎有一个 bug,因此单选按钮的检查样式没有改变.也许 itext 的人可以说更多...
PdfDocument pdfDoc = new PdfDocument(new PdfWriter("output7.pdf"));
Document doc = new Document(pdfDoc);
PdfButtonFormField radioGroup = PdfFormField.createRadioGroup(pdfDoc, "ExampleGroup", "");
radioGroup.setPage(1);
pdfDoc.addNewPage();
PdfFormField field1 = PdfFormField.createRadioButton(pdfDoc, new Rectangle(261, 576, 18, 18), radioGroup, "value1");
field1.setCheckType(PdfFormField.TYPE_CROSS);
field1.setValue("value1");
field1.regenerateField();
PdfFormField field2 = PdfFormField.createRadioButton(pdfDoc, new Rectangle(287, 577, 18, 18), radioGroup, "value2");
field2.setCheckType(PdfFormField.TYPE_CROSS);
field2.regenerateField();
PdfFormField field3 = PdfFormField.createRadioButton(pdfDoc, new Rectangle(314, 578, 18, 18), radioGroup, "value3");
field3.setCheckType(PdfFormField.TYPE_CROSS);
field3.regenerateField();
PdfAcroForm.getAcroForm(pdfDoc, true).addField(radioGroup);
doc.close();
iText 7 的最终解决方案:
public static void main(String[] args) throws Exception {
// RadioButton with cross instead of bullet.
final String filename = "SampleRadioButton.pdf";
final float boxLength = 20;
final float crossWidth = 1;
final String[] languages = { "Dutch", "English", "French" };
try (PdfWriter writer = new PdfWriter(filename); PdfDocument pdfDoc = new PdfDocument(writer); Document doc = new Document(pdfDoc)) {
pdfDoc.addNewPage();
final PdfAcroForm form = PdfAcroForm.getAcroForm(pdfDoc, true);
final PdfButtonFormField radioGroup = PdfFormField.createRadioGroup(pdfDoc, "Language", languages[1]);
int count = 0;
for (final String language : languages) {
count++;
// button
final Rectangle rect = new Rectangle(40, 800 - (count * 30), boxLength, boxLength);
final PdfFormField radioButton = PdfFormField.createRadioButton(pdfDoc, rect, radioGroup, language);
final PdfDictionary radioDict = radioButton.getPdfObject();
final PdfDictionary mk = new PdfDictionary();
mk.put(PdfName.CA, new PdfString("8")); // check=4, circle=1, cross=8, diamond=u, square=n, star=H
radioDict.put(PdfName.MK, mk);
radioButton.setVisibility(PdfFormField.VISIBLE);
editAppearance(pdfDoc, radioButton, language, boxLength, crossWidth);
// text
final Paragraph para = new Paragraph(language).setFontSize(18);
doc.showTextAligned(para, 70, 800 - (count * 30), TextAlignment.LEFT);
}
form.addField(radioGroup);
}
Desktop.getDesktop().open(new File(filename));
}
private static void editAppearance(PdfDocument pdfDoc, PdfFormField radioButton, String value, float length, float crossWidth) {
final PdfStream streamOn = (PdfStream) new PdfStream().makeIndirect(pdfDoc);
final PdfCanvas canvasOn = new PdfCanvas(streamOn, new PdfResources(), pdfDoc);
final Rectangle rect = new Rectangle(0, 0, length, length);
final PdfFormXObject xObjectOn = new PdfFormXObject(rect);
canvasOn.saveState();
canvasOn.setStrokeColor(ColorConstants.BLACK).setLineWidth(crossWidth);
// bottom left to top right
canvasOn.moveTo(0, 0).lineTo(length, length).stroke();
// Top left to bottom right
canvasOn.moveTo(0, length).lineTo(length, 0).stroke();
canvasOn.restoreState();
xObjectOn.getPdfObject().getOutputStream().writeBytes(streamOn.getBytes());
final PdfWidgetAnnotation widget = radioButton.getWidgets().get(0);
widget.setNormalAppearance(new PdfDictionary());
widget.getNormalAppearanceObject().put(new PdfName(value), xObjectOn.getPdfObject());
}
}