1

I'm a new in apache poi could anyone help me with creating checkboxes and fillable fields(plain text, rich text) in docx document? I saw xml representation of docx and I think that is element describe checkbox

<w:fldChar w:fldCharType="begin">
          <w:ffData>
            <w:name w:val="Check59"/>
            <w:enabled/>
            <w:calcOnExit w:val="0"/>
            <w:checkBox>
              <w:sizeAuto/>
              <w:default w:val="0"/>
            </w:checkBox>
          </w:ffData>
        </w:fldChar>
      </w:r>
      <w:bookmarkStart w:id="6" w:name="Check59"/>
      <w:r>
        <w:rPr>
          <w:sz w:val="20"/>
        </w:rPr>
        <w:instrText xml:space="preserve">FORMCHECKBOX</w:instrText>
      </w:r>
      <w:r>
        <w:rPr>
          <w:sz w:val="20"/>
        </w:rPr>
      </w:r>
      <w:r>
        <w:rPr>
          <w:sz w:val="20"/>
        </w:rPr>
        <w:fldChar w:fldCharType="end"/>
      </w:r>

and that xml elements describe input text:

<w:r>
        <w:rPr>
          <w:sz w:val="20"/>
          <w:u w:val="single"/>
        </w:rPr>
        <w:fldChar w:fldCharType="begin">
          <w:ffData>
            <w:name w:val="Text1"/>
            <w:enabled/>
            <w:calcOnExit w:val="0"/>
            <w:textInput/>
          </w:ffData>
        </w:fldChar>
      </w:r>
      <w:r>
        <w:rPr>
          <w:sz w:val="20"/>
          <w:u w:val="single"/>
        </w:rPr>
        <w:instrText xml:space="preserve">FORMTEXT</w:instrText>
      </w:r>
      <w:r>
        <w:rPr>
          <w:sz w:val="20"/>
          <w:u w:val="single"/>
        </w:rPr>
      </w:r>
      <w:r>
        <w:rPr>
          <w:sz w:val="20"/>
          <w:u w:val="single"/>
        </w:rPr>
        <w:fldChar w:fldCharType="separate"/>
      </w:r>
      <w:r>
        <w:rPr>
          <w:noProof/>
          <w:sz w:val="20"/>
          <w:u w:val="single"/>
        </w:rPr>
        <w:t> </w:t>
      </w:r>
      <w:r>
        <w:rPr>
          <w:noProof/>
          <w:sz w:val="20"/>
          <w:u w:val="single"/>
        </w:rPr>
        <w:t> </w:t>
      </w:r>
      <w:r>
        <w:rPr>
          <w:noProof/>
          <w:sz w:val="20"/>
          <w:u w:val="single"/>
        </w:rPr>
        <w:t> </w:t>
      </w:r>
      <w:r>
        <w:rPr>
          <w:noProof/>
          <w:sz w:val="20"/>
          <w:u w:val="single"/>
        </w:rPr>
        <w:t> </w:t>
      </w:r>
      <w:r>
        <w:rPr>
          <w:noProof/>
          <w:sz w:val="20"/>
          <w:u w:val="single"/>
        </w:rPr>
        <w:t> </w:t>
      </w:r>
      <w:r>
        <w:rPr>
          <w:sz w:val="20"/>
          <w:u w:val="single"/>
        </w:rPr>
        <w:fldChar w:fldCharType="end"/>
      </w:r>
      <w:r>
        <w:rPr>
          <w:sz w:val="20"/>
          <w:u w:val="single"/>
        </w:rPr>
        <w:tab/>
      </w:r>
      <w:r>
        <w:rPr>
          <w:sz w:val="20"/>
        </w:rPr>
        <w:t xml:space="preserve">,“Seller” whether one or more, and</w:t>
      </w:r>
    </w:p>

but how that is get from apache poi or create the same?

John
  • 1,375
  • 4
  • 17
  • 40

1 Answers1

2

As far as you know the XML needed in the Office Open XML Word document, you also can creating it using apache poi. Apache poi bases on the ooxml-schemas which are Java classes created from the XML schema definitions of Office Open XML. That's why there are classes for each of the XML elements described in those schema definitions.

Unfortunately there is not any documentation about the ooxml schemas public available. So we need downloading the sources of ooxml-schemas and then doing javadoc form those to get a API documentation which describes the classes and methods.

There we then find org.openxmlformats.schemas.wordprocessingml.x2006.main.* classes which are the classes for word processing part of Office Open XML.

Note ooxml-schemas version 1.4 is for usage together with apache poi 4.0.0 or newer. For older versions ooxml-schemas version 1.3 is needed.

For inserting form fields in Word we need Interface CTFldChar, Interface STFldCharType and Interface CTString.

Example code:

import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
import org.apache.poi.xwpf.usermodel.XWPFRun;

import org.openxmlformats.schemas.wordprocessingml.x2006.main.*;

import java.io.File;
import java.io.FileOutputStream;

/*
needs the full ooxml-schemas-1.4.jar as mentioned in https://poi.apache.org/faq.html#faq-N10025
*/

public class WordInsertFormFields {

 static void insertFormField(XWPFParagraph paragraph, String type, CTString[] options) {
  XWPFRun run = paragraph.createRun();
  run.getCTR().addNewFldChar().setFldCharType(STFldCharType.BEGIN);
  if ("FORMTEXT".equals(type)) {
   run.getCTR().getFldCharArray(0).addNewFfData().addNewTextInput();
  } else if ("FORMDROPDOWN".equals(type)) {
   run.getCTR().getFldCharArray(0).addNewFfData().addNewDdList().setListEntryArray(options);
  } else if ("FORMCHECKBOX".equals(type)) {
   run.getCTR().getFldCharArray(0).addNewFfData().addNewCheckBox();
  }
  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("\u2002");
   }
  }
  run = paragraph.createRun();
  run.getCTR().addNewFldChar().setFldCharType(STFldCharType.END);
 }

 public static void main(String[] args) throws Exception {

  XWPFDocument document = new XWPFDocument();

  XWPFParagraph paragraph = document.createParagraph();
  XWPFRun run = paragraph.createRun();
  run.setText("Input Name: ");
  insertFormField(paragraph, "FORMTEXT", null);

  paragraph = document.createParagraph();
  run = paragraph.createRun();
  run.setText("Choose gender: ");
  CTString male = CTString.Factory.newInstance(); male.setVal("male");
  CTString female = CTString.Factory.newInstance(); female.setVal("female");
  insertFormField(paragraph, "FORMDROPDOWN", new CTString[]{male, female});

  paragraph = document.createParagraph();
  run = paragraph.createRun();
  run.setText("Will you answer mails?: ");
  insertFormField(paragraph, "FORMCHECKBOX", null);

  document.enforceFillingFormsProtection();

  FileOutputStream out = new FileOutputStream(new File("WordInsertFormFields.docx"));
  document.write(out);
  out.close();
 }
}
Axel Richter
  • 56,077
  • 6
  • 60
  • 87
  • How can I set the checkbox as **checked** programmatically with apache poi? – demir5334 Jun 25 '20 at 08:50
  • 1
    @demir5334: When? Directly while creating? Then: `CTFFCheckBox checkbox = run.getCTR().getFldCharArray(0).addNewFfData().addNewCheckBox(); CTOnOff onOff = CTOnOff.Factory.newInstance(); onOff.setVal(STOnOff.ON); checkbox.setChecked(onOff);` – Axel Richter Jun 25 '20 at 09:21
  • Yes, that's what I want. Thanks. – demir5334 Jun 25 '20 at 09:48