0

我是 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> &lt;/w:t>
      </w:r>
      <w:r>
        <w:rPr>
          <w:noProof/>
          <w:sz w:val="20"/>
          <w:u w:val="single"/>
        </w:rPr>
        <w:t> &lt;/w:t>
      </w:r>
      <w:r>
        <w:rPr>
          <w:noProof/>
          <w:sz w:val="20"/>
          <w:u w:val="single"/>
        </w:rPr>
        <w:t> &lt;/w:t>
      </w:r>
      <w:r>
        <w:rPr>
          <w:noProof/>
          <w:sz w:val="20"/>
          <w:u w:val="single"/>
        </w:rPr>
        <w:t> &lt;/w:t>
      </w:r>
      <w:r>
        <w:rPr>
          <w:noProof/>
          <w:sz w:val="20"/>
          <w:u w:val="single"/>
        </w:rPr>
        <w:t> &lt;/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 获得或创建相同的?

4

1 回答 1

1

只要您知道文档中XML需要的Office Open XML Word内容,您也可以使用apache poi. Apache poi基于ooxml-schemaswhich 是Java从 的XML模式定义创建的类Office Open XMLXML这就是为什么这些模式定义中描述的每个元素都有类的原因。

不幸的是,没有任何关于 ooxml 架构的公开文档可用。因此,我们需要下载ooxml-schemas的源代码,然后javadoc从这些源代码中获取描述类和方法的 API 文档。

然后我们在那里找到org.openxmlformats.schemas.wordprocessingml.x2006.main.*类,这些类是 Office Open XML.

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

Word为了在我们需要Interface CTFldCharInterface STFldCharType和中插入表单域Interface 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();
 }
}
于 2019-08-21T15:19:51.337 回答