2016-11-21 140 views
1

我有一個業務需求,其中提供了具有xml映射的excel文檔(基本上使用excel菜單選項Developer-> Source,然後選擇一個xml文件並將XML元素映射到Excel單元格)。例如:單元格A2中的值映射到xml元素「document_title」,B2映射到「document_number」。使用Apache POI讀取Excel,XML MAP元素名稱

要求是以編程方式讀取excel文檔並搜索XML元素列表並查找映射的單元格和單元格的內容。例如:搜索xml元素「document_title」並查找該元素映射到的單元格(在上述示例中,這是A2)並讀取單元格的內容。

我已經嘗試使用OPCP包和Apache POI的XSSFReader類,並嘗試使用DOMParser解析它,但無法實現此目的。

以下是源代碼的修剪版本,有人可以幫助我在正確的方向。

public static void main(String[] args) throws IOException 
{ 
    System.out.println("reading excel"); 

    try { 
     OPCPackage pkg = OPCPackage.open("D:\\test.xlsx"); 
     XSSFReader r = new XSSFReader(pkg); 
     SharedStringsTable sst = r.getSharedStringsTable(); 

     InputStream inp = r.getSheet("rId1"); 

     InputSource inpSource = new InputSource(inp); 

     DOMParser parser = new DOMParser(); 
     parser.parse(inpSource); 

     Document doc = parser.getDocument(); 
     inp.close(); // dont know yet, how to read each element, and hence trying to write this to a file 

     OutputStream writer = new FileOutputStream("D:\\outtrId11.xml"); 
     TransformerFactory transfac = TransformerFactory.newInstance(); 
     Transformer trans = transfac.newTransformer(); 
           trans.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes"); 
     trans.setOutputProperty(OutputKeys.INDENT, "yes"); 
     trans.setOutputProperty(OutputKeys.ENCODING, "UTF-8"); 

     //create string from xml tree 

     StreamResult result = new StreamResult(writer); 
     DOMSource source = new DOMSource(doc); 
     trans.transform(source, result);    

    } catch (InvalidFormatException e1) { 
     // TODO Auto-generated catch block 
     e1.printStackTrace(); 
    } catch (OpenXML4JException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } catch (SAXException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } catch (TransformerConfigurationException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } catch (TransformerException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 

如果有任何疑問/建議,請讓我知道。任何幫助將非常感謝

回答

2

經過一些爬行通過互聯網後,我發現一個例子發佈到解決POI類之一的錯誤。我已經調整了這個例子中的代碼以滿足我的需要,並得到了所需的東西。總之,下面的代碼讀取一個xlsx文件,檢索任何關係(在這種情況下,我感興趣的關係是tableSingleCells,因爲它包含xml映射數據)。代碼然後爲所有映射的XML元素和關聯的單元格引用解析此文檔。

最後,我顯示與這些XML元素關聯的單元格的XML元素,xpath和單元格值。

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

    System.out.println("reading excel"); 

    File file = new File("D:\\test.xlsx"); 
    // load an XLSX file with mapping informations 

    XSSFWorkbook wb; 
    wb = new XSSFWorkbook(file.getAbsolutePath()); 

     for(XSSFSheet sheet : wb) { 

      for(POIXMLDocumentPart doc : sheet.getRelations()) { 

       final PackagePart part = doc.getPackagePart(); 
       assert null!=part; 

       if(part==null) { 
        System.out.println("part of relation is null. Will be ignored!"); 
        continue; 
       } 

       //System.out.println(String.format("contentType [%s]", part.getContentType())); 

       if(part.getContentType().equalsIgnoreCase("application/vnd.openxmlformats-officedocument.spreadsheetml.tableSingleCells+xml")) 
       { 
        System.out.println(String.format("contentType [%s]", part.getContentType())); 

        SingleXmlCellsDocument singleCellsXml = SingleXmlCellsDocument.Factory.parse(part.getInputStream()); 
        CTSingleXmlCells scs = singleCellsXml.getSingleXmlCells(); 

        for(CTSingleXmlCell sc : scs.getSingleXmlCellArray()) { 

         //get R reference 
         final String ref = sc.getR(); 

         //get cell reference 
         final CellReference cellRef = new CellReference(ref); 
         final CTXmlCellPr cellPr = sc.getXmlCellPr(); 

         //get xml element reference 
         final CTXmlPr pr = cellPr.getXmlPr(); 

         //get xpath reference 
         final String xpath = pr.getXpath(); 

         //navigate to the cell by setting row and column 
         final int rowNum = cellRef.getRow(); 
         XSSFRow row = sheet.getRow(rowNum); 

         final int colNum = cellRef.getCol(); 
         XSSFCell cell = row.getCell(colNum); 


         DataFormatter formatter = new DataFormatter(); 

         String cellStrValue=""; 

         cellStrValue=formatter.formatCellValue(cell); 


         //System.out.println(xpathQuery); 
         final String xpathQuery = String.format("[Cell Reference: " + ref + "] [Element Name: "+ cellPr.getUniqueName() + "] [Cell Value: " + cellStrValue + "] [Full xpath: " + xpath + "]"); 
         System.out.println(xpathQuery); 


        } 

       } 

      } 

     } 

     wb.close(); 

} 

希望這可以幫助別人。隨時詢問是否有任何疑問。

謝謝,

相關問題