当前位置: 首页 > 知识库问答 >
问题:

使用Apache POI处理docx文件中的复选框

苍烨然
2023-03-14

你能帮帮我吗?我需要通过Apache POI在我的MS Word docx模板中填充复选框。Checkboxes已由Developer选项卡->Controls->CheckBox插入,并位于段落->“w:sdt”标记内(而不是段落->run内)。

XML部分:

<w:p w:rsidR="00C81ACC" w:rsidRDefault="00C81ACC" w:rsidP="004658AE">
    <w:pPr>
        <w:spacing w:line="276" w:lineRule="auto"/>
        <w:ind w:left="383" w:hanging="383"/>
        <w:rPr>
            <w:rFonts w:ascii="Arial" w:hAnsi="Arial" w:cs="Arial"/>
            <w:sz w:val="18"/>
            <w:szCs w:val="18"/>
        </w:rPr>
    </w:pPr>
    <w:sdt>
        <w:sdtPr>
            <w:rPr>
                <w:rFonts w:ascii="Arial" w:hAnsi="Arial" w:cs="Arial"/>
                <w:sz w:val="18"/>
                <w:szCs w:val="18"/>
            </w:rPr>
            <w:id w:val="615721754"/>
            <w14:checkbox>
                <w14:checked w14:val="0"/>
                <w14:checkedState w14:val="2612" w14:font="MS Gothic"/>
                <w14:uncheckedState w14:val="2610" w14:font="MS Gothic"/>
            </w14:checkbox>
        </w:sdtPr>
        <w:sdtContent>
            <w:r>
                <w:rPr>
                    <w:rFonts w:ascii="MS Gothic" w:eastAsia="MS Gothic" w:hAnsi="MS Gothic" w:cs="Arial" w:hint="eastAsia"/>
                    <w:sz w:val="18"/>
                    <w:szCs w:val="18"/>
                </w:rPr>
                <w:t>☐</w:t>
            </w:r>
        </w:sdtContent>
    </w:sdt>
    <w:r>
        <w:rPr>
            <w:rFonts w:ascii="Arial" w:hAnsi="Arial" w:cs="Arial"/>
            <w:sz w:val="18"/>
            <w:szCs w:val="18"/>
        </w:rPr>
        <w:t xml:space="preserve"> Pass</w:t>
    </w:r>
</w:p>

共有1个答案

钱锐
2023-03-14

到目前为止,Apache POI还不支持这一点。由于它使用扩展的XML来自W14名称空间,甚至底层的OOXML-Schema类也不支持这一点。这些架构类是从2007年发布的Office Open XMLXML架构生成的。来自W14名称空间的扩展XML较晚,不是Office Open XML的一部分。

因此,如果想要支持它,那么就需要在非常低的XML级别上工作。但是对于像复选框这样简单的东西,这里可以作为一个例子来展示。

下面的代码包含类W14checkbox的工作草稿。这提供了一个静态方法来检查给定的CTSDTrun是否包含W14:CheckBox。如果是这种情况,则可以从该CTSDTrun创建W14CheckBox对象。然后该对象提供getchecksetcheck方法。

请注意,在setchecked中,不仅需要设置布尔值w14:checkbox/w14:check,还需要设置ctsdtcontentrun的相应文本值。这可以是Unicode字符“投票框”(U+2610)表示未选中,也可以是Unicode字符“带选中的投票框”(U+2612)表示选中。

完整示例:

import java.io.*;
import org.apache.poi.xwpf.usermodel.*;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.*;

import org.apache.xmlbeans.*;
import javax.xml.namespace.QName;

public class WordFillCheckBox {

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

  XWPFDocument document = new XWPFDocument(new FileInputStream("source.docx"));

  for (XWPFParagraph paragraph : document.getParagraphs()) { //go through all paragraphs
   for (CTSdtRun sdtRun : paragraph.getCTP().getSdtList()) {
    if (W14Checkbox.isW14Checkbox(sdtRun)) {
     W14Checkbox w14Checkbox = new W14Checkbox(sdtRun);
     System.out.println(w14Checkbox.getChecked());
     if (w14Checkbox.getChecked()) w14Checkbox.setChecked(false); else w14Checkbox.setChecked(true);
     System.out.println(w14Checkbox.getChecked());
    }
   }
  }

  FileOutputStream out = new FileOutputStream("result.docx");
  document.write(out);
  out.close();
  document.close();

 }

 static class W14Checkbox {
  CTSdtRun sdtRun = null;
  CTSdtContentRun sdtContentRun = null;
  XmlObject w14CheckboxChecked = null;

  W14Checkbox(CTSdtRun sdtRun) {
   this.sdtRun = sdtRun;
   this.sdtContentRun = sdtRun.getSdtContent();
   String declareNameSpaces = "declare namespace w14='http://schemas.microsoft.com/office/word/2010/wordml'";
   XmlObject[] selectedObjects = sdtRun.getSdtPr().selectPath(declareNameSpaces + ".//w14:checkbox/w14:checked");
   if (selectedObjects.length > 0) {  
    this.w14CheckboxChecked  = selectedObjects[0];
   }
  }
  CTSdtContentRun getContent() {
   return this.sdtContentRun;
  }
  XmlObject getW14CheckboxChecked() {
   return this.w14CheckboxChecked;
  }
  boolean getChecked() {
   XmlCursor cursor = this.w14CheckboxChecked.newCursor();
   String val = cursor.getAttributeText(new QName("http://schemas.microsoft.com/office/word/2010/wordml", "val", "w14"));
   return "1".equals(val) || "true".equals(val);
  }
  void setChecked(boolean checked) {
   XmlCursor cursor = this.w14CheckboxChecked.newCursor();
   String val = (checked)?"1":"0";
   cursor.setAttributeText(new QName("http://schemas.microsoft.com/office/word/2010/wordml", "val", "w14"), val);
   cursor.dispose();
   CTText t = this.sdtContentRun.getRArray(0).getTArray(0);
   String content = (checked)?"\u2612":"\u2610";
   t.setStringValue(content);
  }

  static boolean isW14Checkbox(CTSdtRun sdtRun) {
   CTSdtPr sdtPr = sdtRun.getSdtPr();
   String declareNameSpaces = "declare namespace w14='http://schemas.microsoft.com/office/word/2010/wordml'";
   XmlObject[] selectedObjects = sdtPr.selectPath(declareNameSpaces + ".//w14:checkbox");
   if (selectedObjects.length > 0) return true;  
   return false;
  }
 }
}

注意:这只是一个工作草案,需要进一步发展,以便生产使用。

 类似资料:
  • 我正在尝试创建一个包含多列的word文档。这样做(而不是使用表)的原因是,数据将跨越多个页面,在添加到新页面之前,我只能用列填充整个页面。 可以用ApachePOI实现吗?谢谢

  • 问题内容: 我一直在使用python实现自定义解析器,并使用该解析数据来格式化要在内部分发的word文档。到目前为止,所有格式都非常简单明了,但是我对如何在单个表格单元格中插入复选框感到非常困惑。 我尝试在python-docx中使用python对象函数(使用等),这会导致MS Word在尝试打开文件时引发以下错误:“文件xxxx无法打开,因为内容有问题详细信息:文件已损坏,无法打开”。 经过一段

  • 我无法使用ApachePOI删除docx文件中的所有注释。有没有其他方法可以使用docx4j api删除注释?

  • 我还尝试了另一种方法:修改原始XML、解压缩docx并操作文件“word/document.XML”。当我压缩回解压缩的文件夹并将其重命名为docx时,MS Word无法打开它。

  • 您好,我正在尝试将一个表从一个docx文件复制到另一个docx文件,但实际情况是,该表的值在新文档中的表下方和表外部被复制(请参见下面的图片) Talbe在新的docx里 正如您所见,表的值被复制到表的外部。我使用的是Libre Office,ApachePOI版本3.17,我的电脑运行的是Ubuntu 16.04 我用来执行复制的代码如下

  • 问题内容: 您认为将docx文档读取为java对象哪个更好?为什么? 换一种说法。哪个库支持大多数单词标签? 问题答案: 披露:我领导docx4j项目 尽管docx4j还可以处理pptx和xlsx,但它主要用于docx操作。举例来说,在撰写本文时,docx4j论坛中有近1000个主题。pptx论坛仅占10%。 无论您想对docx文档做什么,docx4j都应该能够为您提供帮助。通用工作流只有一页概述

  • 我试图用处理docx文件。只是简单地读取然后写入文件(现在)。这是我的简单代码: 问题是输入文件的头文件中有一个小图像。因此,在使用POI处理输入文件并在Microsoft Word中打开输出文件后,我收到损坏的文件错误: 一切工作在OO Writer,但不是在办公室。 问题是:怎么了?apache POI是否不处理头文件中包含图像的文件?你知道解决这个问题的方法吗? 我需要使用,我不考虑其他工具

  • 这是如何使用公共类frome的一个后续步骤。其他处理选项卡中的java文件?;使用来自的Usage类中的示例。java文件-有完整的文档吗?-处理2。x和3。x论坛,我有这个: /tmp/Sketch/Foo.java 这个例子运行得很好,但是如果我取消注释import peasy。组织 行,则编译失败: 当然,我确实在下安装了PeasyCam,如果我导入peasy.*它工作得很好 来自草图。 我