如何在 docx 文档中创建复选框和输入文本字段?

How to create checkbox and input text fields in docx document?

我是 apache poi 的新手,谁能帮我在 docx 文档中创建复选框和可填写字段(纯文本、富文本)?我看到了 docx 的 xml 表示,我认为那是元素描述复选框

<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>

并且 xml 元素描述了输入文本:

<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>

但是如何从 apache poi 获取或创建它?

据您所知 Office Open XML Word 文档中需要的 XML,您也可以使用 apache poi 创建它。 Apache poi 基于 ooxml-schemas Java 类 从 Office Open XMLXML 模式定义创建。这就是为什么这些架构定义中描述的每个 XML 元素都有 类。

遗憾的是,没有任何关于 ooxml 模式的文档 public 可用。因此,我们需要下载 ooxml-schemas 的源代码,然后从这些源代码中执行 javadoc 以获得描述 类 和方法的 API 文档。

然后我们找到 org.openxmlformats.schemas.wordprocessingml.x2006.main.* 类,它们是 Office Open XML.

的文字处理部分的 类

注意 ooxml-schemas 版本 1.4apache poi 4.0.0 或更新版本一起使用。对于旧版本 ooxml-schemas,需要版本 1.3

为了在 Word 中插入表单字段,我们需要 Interface CTFldCharInterface STFldCharTypeInterface CTString

示例代码:

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();
 }
}