2013-05-28 121 views
0

我有一个非常简单的问题,让我疯狂。基本上我想通过POI/DOCX4J库,docx段落结构和文档大纲来提取。我使用POI paragraph.getLvl()方法对正常的doc文档执行了相同的任务。有没有办法用docx获得相同的结果?我如何重新构建docx的整个TOC结构? 谢谢。POI docx段大纲解析[已解决]


解决方案:

感谢您的回答。我决定以这样的方式

Map headingMap = new HashMap(); 
    headingMap.put("heading 1", 1); 
    headingMap.put("heading 2", 2); 
    headingMap.put("heading 3", 3); 
    headingMap.put("heading 4", 4); 
    headingMap.put("heading 5", 5); 
    headingMap.put("heading 6", 6); 
    headingMap.put("heading 7", 7); 
    headingMap.put("heading 8", 8); 
    headingMap.put("heading 9", 9); 

    Iterator<XWPFParagraph> iterator = docx.getParagraphsIterator(); 
    Styles styles = getStyle(completePath); 

    while(iterator.hasNext()){ 
     XWPFParagraph p = iterator.next(); 

     if(p != null && p.getStyleID() != null){ 
      for (Style s : styles.getStyle()){ 
       if (p.getStyleID().equals(s.getStyleId()) && headingMap.containsKey(s.getName().getVal())){ 
        StringBuffer text = new StringBuffer(); 
        for(XWPFRun run : p.getRuns()) { 
         text.append(run.toString()); 
        } 
       } 
      } 
     } 
    } 
+1

POI是否支持.docx? – duffymo

+1

是的,POI支持Office Open XML格式(OOXML),因此docx – YoBre

回答

1

大纲级别可以直接在段进行设置,或在样式层次结构,让您真正的挑战是导航样式层次结构得到它。

已大纲级别上直接设置它看起来就像一个段落:

 <w:p> 
      <w:pPr> 
       <w:outlineLvl w:val="2"/> 
      </w:pPr> 

假设款物P,在docx4j,这将是p.getPPr()getOutlineLvl

如果级别定义在一些样式S,例如:

 <w:style w:type="paragraph" w:styleId="Heading2"> 
      <w:name w:val="heading 2"/> 
      <w:basedOn w:val="Normal"/> 
      <w:pPr> 
       <w:outlineLvl w:val="1"/> 
      </w:pPr> 

,你可以使用类似(忽略在看什么风格可能支持算法FMP)得到它:

private int getOutlineLvl(Style s) { 
    // Heading 1 is lvl 0 
    // There are 9 levels, so 9 will be lvl 8 
    // So return 9 for normal text 
    if (s==null 
      || s.getPPr()==null) return 9; 

    OutlineLvl outlineLvl = s.getPPr().getOutlineLvl(); 
    if (outlineLvl==null) return 9; 
    return outlineLvl.getVal().intValue(); 
} 

在这种情况下,该段的PPR将包含类似:

    <w:pStyle w:val="Heading2"/> 

你从那里得到的样式名称,则需要看它的样式部分。看看docx4j源代码,看看如何做到这一点。

你需要知道的另一件事是如何遍历段落。假设你对任何内部表都不感兴趣,你可以在mdp.getContent()中使用for循环,其中mdp是主要的文档部分。有关更多信息,请参见docx4j cheat sheet