如何通过Apache POI在Word文档中添加复选框?问题与解法
I'm working on generating Word documents using Apache POI, and I've been stuck trying to add checkboxes to the document. When I run this line of code:
run3.getCTR().getFldCharArray(0).addNewFfData().addNewCheckBox();
I hit this exception:
Exception in thread "main" java.lang.IndexOutOfBoundsException at org.openxmlformats.schemas.wordprocessingml.x2006.main.impl.CTRImpl.getFldCharArray(Unknown Source) at createSoluminaForm.main(createSoluminaForm.java:45)
Was wondering if any fellow devs have successfully implemented this feature and could share how?
After some trial and error, I got it working by properly setting up the field structure that Apache POI expects for form elements. Here's the helper method I created that handles both checkboxes and text input fields:
static void insertFormField(XWPFParagraph paragraph, String type, CTOnOff onOff) { XWPFRun run = paragraph.createRun(); run.getCTR().addNewFldChar().setFldCharType(STFldCharType.BEGIN); if ("FORMTEXT".equals(type)) { run.getCTR().getFldCharArray(0).addNewFfData().addNewTextInput(); } else if ("FORMCHECKBOX".equals(type)) { CTFFCheckBox checkbox = run.getCTR().getFldCharArray(0).addNewFfData().addNewCheckBox(); checkbox.setChecked(onOff); } run = paragraph.createRun(); run.getCTR().addNewInstrText().setStringValue(type); if ("FORMTEXT".equals(type)) { run = paragraph.createRun(); run.getCTR().addNewFldChar().setFldCharType(STFldCharType.SEPARATE); for (int i = 0; i < 5; i++) { run = paragraph.createRun(); //run.setText(" "); // Unicode Character 'EN SPACE' (U+2002) run.setText(" "); } } run = paragraph.createRun(); run.getCTR().addNewFldChar().setFldCharType(STFldCharType.END); }
How to use it:
// Create a checked checkbox CTOnOff checkedState = CTOnOff.Factory.newInstance(); checkedState.setVal(STOnOff.ON); // Create an unchecked checkbox CTOnOff uncheckedState = CTOnOff.Factory.newInstance(); uncheckedState.setVal(STOnOff.OFF); // Insert the checkbox into your target paragraph insertFormField(parag2, "FORMCHECKBOX", checkedState); // insertFormField(parag2, "FORMCHECKBOX", uncheckedState); // For unchecked
The problem with my original code was that I was trying to access the field array before actually adding a field character to the run. By first adding the BEGIN field character, getFldCharArray(0) has a valid entry to work with, which fixes the IndexOutOfBoundsException.
内容的提问来源于stack exchange,提问作者demir5334

