2016-11-21 3 views
1

У меня есть бизнес-требование, в котором мне предоставлен документ Excel, который имеет сопоставление xml на месте (в основном используя опцию меню Excel-> Source, а затем выбирая файл xml и отображение элементов XML в ячейки excel). Например: Значение в ячейке A2 отображается в элемент xml «document_title», B2 сопоставляется с «document_number».Чтение Excel, имя элемента XML MAP с использованием Apache POI

Требование состоит в том, чтобы программно прочитать документ Excel и найти список элементов XML и найти отображаемые ячейки и содержимое ячейки. Например: Искать элемент xml «document_title» и найти ячейку, к которой этот элемент сопоставлен (в примере, упомянутом выше, это A2) и прочитать содержимое ячейки.

Я попытался использовать классы OPCP и классы XSSFReader apache POI и попытаться разобрать его с помощью 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, xpath и значение ячейки ячейки, связанной с этими элементами XML.

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(); 

} 

Надеюсь, это кому-то поможет. Не стесняйтесь спрашивать, есть ли какие-либо вопросы.

Спасибо,

Смежные вопросы