apache poi 获取相对于其他 table 或段落的段落

apache poi get paragraph relative to other table or paragraph

我正在使用 Apache poi 处理一个 ms word 文档,其中包含任意数量的 table 散布在整个文档中,没有标准化的结构。

w:p
w:p
w:p
w:p
w:p
w:p
w:p
w:p <--- this specific paragraph contains some useful information
w:p
w:p
w:tbl <--- this is the table I'm going to work with
w:p
w:p
w:p
w:p
w:p
w:p
w:tbl
w:p

必须使用位于 table 的 dom 位置上方的段落中的某些信息来补充任意 table 中包含的信息。

我想要运行类似

的东西
for each table in the document
    check above paragraphs until a condition is met
    use that paragraph to do something

到目前为止,dom 节点位置之间的唯一关系是通过类似 org.w3c.dom.Node node = table.getCTTbl().getDomNode(); 的东西可以达到的,在这种情况下,获得像 [=14 这样的双射对象链是相对困难的=]

这个问题似乎太简单了,因为它没有一些我不知道的现有功能。 有什么想法吗?

如果您有一个包含在 Word 文档中的 table 列表,并且需要获取每个 table 上方的段落,则可以执行以下操作:

  • 获取table所在的正文。
  • 获取该文本正文的正文元素。
  • 确定正文元素列表中 table 的索引。
  • 从该索引开始向后遍历正文元素并获得 段落,直到找到有趣的段落或另一个 table 或在开头结束。

代码:

import java.io.FileInputStream;
import org.apache.poi.xwpf.usermodel.*;

import java.util.List;

public class WordReadTablesAndParagraphsAbove {
    
 static void getParagraphsAbove(XWPFTable table) {
  List<IBodyElement> bodyElements = table.getBody().getBodyElements();
  int indexInBodyElementList = bodyElements.indexOf(table); // get index of that table in body elements
  for (int i = indexInBodyElementList -1; i >=0; i--) { // loop backwards through body elements
   IBodyElement bodyElement = bodyElements.get(i);
   if (bodyElement instanceof XWPFParagraph) { // we have a XWPFParagraph
    XWPFParagraph paragraph = (XWPFParagraph)bodyElement;
    // is this the interesting paragraph?
    System.out.println(paragraph + ":" + paragraph.getText());
   } else if (bodyElement instanceof XWPFTable) { // we have another table
    break;
   }
  }
 }

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

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

  for (XWPFTable table : document.getTables()) {
   System.out.println(table);
   getParagraphsAbove(table);
  }
  
  document.close();
 }
}

但整件事闻起来像 XY problem. Why not traversing all body elements in document top down using XWPFDocument.getBodyElements?在那里寻找有趣的段落。然后 table 将是正文元素列表中的下一个 table。