2017-09-05 5 views
0

나는 docx 파일에 반복 테이블에 대한 아파치 poi를 사용하고 있습니다. 모든 잘 작동하지만 텍스트 상자 테이블은, 내 코드 테이블이 표시되지 않는 경우 - 낮은 수준이 *.docx 문서를 구문 분석 코드에 따라 table.size() = 0아파치 poi는 텍스트 상자에서 테이블을 가져옵니다

enter image description here

XWPFDocument doc = new XWPFDocument(new FileInputStream(fileName)); 

    List<XWPFTable> table = doc.getTables(); 

    for (XWPFTable xwpfTable : table) { 
     List<XWPFTableRow> row = xwpfTable.getRows(); 
     for (XWPFTableRow xwpfTableRow : row) { 
      List<XWPFTableCell> cell = xwpfTableRow.getTableCells(); 
      for (XWPFTableCell xwpfTableCell : cell) { 
       if(xwpfTableCell != null){ 
       List<XWPFTable> itable = xwpfTableCell.getTables(); 
        if(itable.size()!=0){ 
         for (XWPFTable xwpfiTable : itable) { 
          List<XWPFTableRow> irow = xwpfiTable.getRows(); 
          for (XWPFTableRow xwpfiTableRow : irow) { 
           List<XWPFTableCell> icell = xwpfiTableRow.getTableCells(); 
           for (XWPFTableCell xwpfiTableCell : icell) { 
            if(xwpfiTableCell!=null){ 
            } 
           } 
          } 
         } 
        } 
       } 
      } 
     } 
    } 
+0

와우. 도대체 누가 워드 프로세서를 그렇게 오용하고 있습니까? 테이블 셀에 포함 된 테이블은 충분히 이상합니다. 그러나 모양에 포함 된 테이블? 필자는'* .docx/word/document.xml'을 매우 특별하게 구문 분석하지 않고이 테이블을 얻을 수 있다고 생각하지 않습니다. –

+0

예,이 경우는 매우 이상하지만이 테이블을 구문 분석해야합니다. docx https://ufile.io/6xmqd – nickolson

+0

을 다운로드 할 수 있습니다. 정확히 필요한 것은 무엇입니까? 테이블 내용 만 읽으시겠습니까? 이것은 비교적 쉽다. 또는 사각형 모양 내에서 테이블을 조작? 이것은 가능하지만 훨씬 더 복잡합니다. –

답변

1

을 문서 본문에 모든 표를 가져 오는 것.

접근법은 org.apache.xmlbeans.XmlCursor를 사용 document.xmlw:tbl의 모든 요소를 ​​검색한다. 찾은 경우 List<CTTbl>에 추가하십시오.

텍스트 상자의 직사각형 모양이 document.xml에서 폴백 (fall-back) 콘텐츠를 제공하기 때문에 mc:Fallback 요소를 건너 뛸 필요가 있습니다. 그렇지 않으면 텍스트 상자 안에 테이블을 두 번 넣을 것입니다.

마침내 우리는 List<CTTbl>을 통해 모든 테이블의 내용을 가져옵니다.

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

import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTBody; 
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTbl; 
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTRow; 
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTc; 
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTP; 
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTR; 
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTText; 

import org.apache.xmlbeans.impl.values.XmlAnyTypeImpl; 
import org.apache.xmlbeans.XmlCursor; 

import javax.xml.namespace.QName; 

import java.util.List; 
import java.util.ArrayList; 

public class WordReadAllTables { 

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

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

    CTBody ctbody = document.getDocument().getBody(); 

    XmlCursor xmlcursor = ctbody.newCursor(); 

    QName qnameTbl = new QName("http://schemas.openxmlformats.org/wordprocessingml/2006/main", "tbl", "w"); 
    QName qnameFallback = new QName("http://schemas.openxmlformats.org/markup-compatibility/2006", "Fallback", "mc"); 

    List<CTTbl> allCTTbls = new ArrayList<CTTbl>(); 

    while (xmlcursor.hasNextToken()) { 
    XmlCursor.TokenType tokentype = xmlcursor.toNextToken(); 
    if (tokentype.isStart()) { 
    if (qnameTbl.equals(xmlcursor.getName())) { 
    if (xmlcursor.getObject() instanceof CTTbl) { 
     allCTTbls.add((CTTbl)xmlcursor.getObject()); 
    } else if (xmlcursor.getObject() instanceof XmlAnyTypeImpl) { 
     allCTTbls.add(CTTbl.Factory.parse(xmlcursor.getObject().toString())); 
    } 
    } else if (qnameFallback.equals(xmlcursor.getName())) { 
    xmlcursor.toEndToken(); 
    } 
    } 
    } 

    for (CTTbl cTTbl : allCTTbls) { 
    StringBuffer tableHTML = new StringBuffer(); 
    tableHTML.append("<table>\n"); 
    for (CTRow cTRow : cTTbl.getTrList()) { 
    tableHTML.append(" <tr>\n"); 
    for (CTTc cTTc : cTRow.getTcList()) { 
    tableHTML.append(" <td>"); 
    for (CTP cTP : cTTc.getPList()) { 
     for (CTR cTR : cTP.getRList()) { 
     for (CTText cTText : cTR.getTList()) { 
     tableHTML.append(cTText.getStringValue()); 
     } 
     } 
    } 
    tableHTML.append("</td>"); 
    } 
    tableHTML.append("\n </tr>\n"); 
    } 
    tableHTML.append("</table>"); 

    System.out.println(tableHTML); 

    } 

    document.close(); 

} 
} 

이 코드는 faq-N10025에 언급 된 스키마 ooxml-schemas-1.3.jar 모두의 전체 항아리를 필요로한다.

+0

감사합니다. Axel, 내 하루는 = =)이 링크는 java.lang.NoClassDefFoundError를 해결하는 데 유용합니다. org/openxmlformats/schemas/wordprocessingml http://poi.apache.org /faq.html#faq-N10025 – nickolson

+0

@nickolson : 안녕하세요. 그리고 모든 스키마'ooxml-schemas-1.3.jar'의 전체 항아리가 필요하다는 힌트를 주셔서 감사합니다. –

+0

위의 코드는 * .docx에서 테이블을 가져 오는 데 항상 적합하며 문서의 "숨겨진"테이블에 의존하지 않는다고 생각합니다. 사실입니까? – nickolson