2016-11-21 75 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(); 

} 

希望这可以帮助别人。随时询问是否有任何疑问。

谢谢,

相关问题