I used the code from the answer from this question to create my radiobuttons: How to Create a Radio Button Group with PDFBox 2.0
After I created my PDF and tried to read the (programatically) selected value from it, this code worked fine:
PDDocumentCatalog catalog = doc.getDocumentCatalog();
PDAcroForm form = catalog.getAcroForm();
List<PDField> fields = form.getFields();
for(PDField field: fields) {
Object value = field.getValueAsString();
String name = field.getFullyQualifiedName();
if (field instanceof PDRadioButton) {
// value is correct and field is instance of PDRadioButton works too
}
}
When I open the PDF in Acrobat Reader DC, make changes and save it again the code doesn't work anymore. There is no instance of PDRadioButton anymore and the value is always an empty string.
When I open the PDF in Acrobat Touch it doesn't even display properly.
(When I open the version that was previously edited by Acrobat Reader DC, Acrobat Touch can display it correctly)
Any suggestions what may be wrong with the code?
Here is a minimal example that behaves the same:
package test;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.apache.pdfbox.cos.COSDictionary;
import org.apache.pdfbox.cos.COSName;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.PDPageContentStream;
import org.apache.pdfbox.pdmodel.PDResources;
import org.apache.pdfbox.pdmodel.common.PDRectangle;
import org.apache.pdfbox.pdmodel.font.PDFont;
import org.apache.pdfbox.pdmodel.font.PDType1Font;
import org.apache.pdfbox.pdmodel.graphics.color.PDColor;
import org.apache.pdfbox.pdmodel.graphics.color.PDDeviceRGB;
import org.apache.pdfbox.pdmodel.interactive.annotation.PDAnnotationWidget;
import org.apache.pdfbox.pdmodel.interactive.annotation.PDAppearanceCharacteristicsDictionary;
import org.apache.pdfbox.pdmodel.interactive.form.PDAcroForm;
import org.apache.pdfbox.pdmodel.interactive.form.PDRadioButton;
public class WriterTest {
public static void main(String[] args) {
try {
PDDocument document = new PDDocument();
PDPage page = new PDPage(PDRectangle.A4);
document.addPage(page);
PDAcroForm acroForm = new PDAcroForm(document);
acroForm.setNeedAppearances(true);
acroForm.setXFA(null);
document.getDocumentCatalog().setAcroForm(acroForm);
PDFont font = PDType1Font.HELVETICA;
PDResources res = new PDResources();
COSName fontName = res.add(font);
acroForm.setDefaultResources(res);
acroForm.setDefaultAppearance('/' + fontName.getName() + " 10 Tf 0 g");
PDPageContentStream contents = new PDPageContentStream(document, page);
List<String> options = Arrays.asList("a", "b", "c");
PDRadioButton radioButton = new PDRadioButton(acroForm);
radioButton.setPartialName("RadioButtonParent");
radioButton.setExportValues(options);
radioButton.getCOSObject().setName(COSName.DV, options.get(1));
List<PDAnnotationWidget> widgets = new ArrayList<>();
for (int i = 0; i < options.size(); i++) {
PDRadioButton subRadioButtons = new PDRadioButton(acroForm);
subRadioButtons.setPartialName("RadioButton");
PDAppearanceCharacteristicsDictionary fieldAppearance = new PDAppearanceCharacteristicsDictionary(new COSDictionary());
fieldAppearance.setBorderColour(new PDColor(new float[] { 0, 0, 0 }, PDDeviceRGB.INSTANCE));
PDAnnotationWidget widget = subRadioButtons.getWidgets().get(0);
widget.setRectangle(new PDRectangle(30, 811 - i * (21), 16, 16));
widget.setAppearanceCharacteristics(fieldAppearance);
widgets.add(widget);
page.getAnnotations().add(widget);
contents.beginText();
contents.setFont(font, 10);
contents.newLineAtOffset(56, 811 - i * (21) + 4);
contents.showText(options.get(i));
contents.endText();
}
radioButton.setWidgets(widgets);
acroForm.getFields().add(radioButton);
contents.close();
try (FileOutputStream output = new FileOutputStream("test.pdf")) {
document.save(output);
}
document.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
See Question&Answers more detail:os