2017-08-29 82 views
0

如何使用Apache POI从Excel表中访问数据透视表中的单元格值? 我尝试使用XSSFPivotTable.getPivotTables,但无法访问单元格值。 Book1.xlsx是在工作表Sheet1上有一个数据透视表的Excel工作簿。如何使用Apache POI从Excel表格访问数据透视表中的单元格值?

FileInoutStream input = new FileInputStream(new File(Book1.xlsx)); XSSFWorkbook wb = new XSSFWorkbook(input); XSSFSheet sh = wb.getSheet("Sheet1"); XSSFPivotTable pt = sh.getPivotTables().get(0);

无法访问细胞在未来的这个角透视表。

+2

嗨。 请添加一个MVCE(https://stackoverflow.com/help/mcve),以便我们可以更好地了解您想要做什么以及问题出在哪里。 –

+0

@FabianSchöner新增了MCVE。 –

+0

你有答案吗? – Frank

回答

0

下面是一个自定义的方式来访问数据透视表标题和数据,即时通讯不知道,但我无法找到一种方式来访问通过库的数据,在线搜索我读了一些东西,说它不支持。

让我们来看看我做了什么:

输入文件:在数字

enter image description here

等转换字母列:

 Map<String, Integer> map = new HashMap<String, Integer>() { 
      { 
       int index =1; 
       for (char ch = 'A'; ch <= 'Z'; ++ch) { 
        put(String.valueOf(ch), index); 
        index++; 
       } 
      } 
    }; 

获取表对象

java.util.List<XSSFPivotTable> l = sh.getPivotTables(); 

下面的代码,这将使一招的结果

XML调试视图:

<xml-fragment name="PivotTable7" cacheId="24" applyNumberFormats="0" applyBorderFormats="0" applyFontFormats="0" applyPatternFormats="0" applyAlignmentFormats="0" applyWidthHeightFormats="1" dataCaption="Values" updatedVersion="6" minRefreshableVersion="3" useAutoFormatting="1" itemPrintTitles="1" createdVersion="6" indent="0" outline="1" outlineData="1" multipleFieldFilters="0" xmlns:main="http://schemas.openxmlformats.org/spreadsheetml/2006/main"> 
    <main:location ref="F6:G7" firstHeaderRow="0" firstDataRow="1" firstDataCol="0"/> 
    <main:pivotFields count="2"> 
    <main:pivotField dataField="1" subtotalTop="0" showAll="0"> 
     <main:items count="2"> 
     <main:item x="0"/> 
     <main:item t="default"/> 
     </main:items> 
    </main:pivotField> 
    <main:pivotField dataField="1" subtotalTop="0" showAll="0"/> 
    </main:pivotFields> 
    <main:rowItems count="1"> 
    <main:i/> 
    </main:rowItems> 
    <main:colFields count="1"> 
    <main:field x="-2"/> 
    </main:colFields> 
    <main:colItems count="2"> 
    <main:i> 
     <main:x/> 
    </main:i> 
    <main:i i="1"> 
     <main:x v="1"/> 
    </main:i> 
    </main:colItems> 
    <main:dataFields count="2"> 
    <main:dataField name="A" fld="0" baseField="0" baseItem="1"/> 
    <main:dataField name="B" fld="1" baseField="0" baseItem="1"/> 
    </main:dataFields> 
    <main:pivotTableStyleInfo name="PivotStyleLight16" showRowHeaders="1" showColHeaders="1" showRowStripes="0" showColStripes="0" showLastColumn="1"/> 
    <main:extLst> 
    <main:ext uri="{962EF5D1-5CA2-4c93-8EF4-DBF5C05439D2}" xmlns:x14="http://schemas.microsoft.com/office/spreadsheetml/2009/9/main"> 
     <x14:pivotTableDefinition hideValuesRow="1" xmlns:xm="http://schemas.microsoft.com/office/excel/2006/main"/> 
    </main:ext> 
    <main:ext uri="{747A6164-185A-40DC-8AA5-F01512510D54}" xmlns:xpdl="http://schemas.microsoft.com/office/spreadsheetml/2016/pivotdefaultlayout"> 
     <xpdl:pivotTableDefinition16 SubtotalsOnTopDefault="0"/> 
    </main:ext> 
    </main:extLst> 
</xml-fragment> 

看着REF =“F6:G7”我知道这将使得招范围

String range = l.get(0).getCTPivotTableDefinition().getLocation().getRef(); //F6:G7 rows/cols reference - case of our sheet 

      //determinate range of table 
      int firstcol = map.get(range.substring(0, 1)); 
      int firstrow = Integer.parseInt(range.substring(1, 2)); 
      int lastcol = map.get(range.substring(3, 4)); 
      int lastrow = Integer.parseInt(range.substring(4, 5)); 

的完整代码:

public static void main(String[] args) { 

     //tranform letters in numbers for columns 
     Map<String, Integer> map = new HashMap<String, Integer>() { 
      { 
       int index =1; 
       for (char ch = 'A'; ch <= 'Z'; ++ch) { 
        put(String.valueOf(ch), index); 
        index++; 
       } 
      } 
    }; 
    try { 
     FileInputStream input = new FileInputStream(new File("C:\\Desktop\\ook.xlsx")); 

     XSSFWorkbook wb = new XSSFWorkbook(input); 
     XSSFSheet sh = wb.getSheet("Sheet1"); 

     Iterator<Row> rowIterator = sh.iterator(); 
     ArrayList columndata = new ArrayList<>(); 

     java.util.List<XSSFPivotTable> l = sh.getPivotTables(); 

     String range = l.get(0).getCTPivotTableDefinition().getLocation().getRef(); //F6:G7 rows/cols reference - case of our sheet 

     //determinate range of table 
     int firstcol = map.get(range.substring(0, 1)); 
     int firstrow = Integer.parseInt(range.substring(1, 2)); 
     int lastcol = map.get(range.substring(3, 4)); 
     int lastrow = Integer.parseInt(range.substring(4, 5)); 

while (rowIterator.hasNext()) { 

    Row row = rowIterator.next(); 
    if(checkrightrowcol(row.getRowNum()+1, firstrow, lastrow)){ 
    Iterator<Cell> cellIterator = row.cellIterator(); 
    while (cellIterator.hasNext()) { 
     Cell cell = cellIterator.next(); 

     if(checkrightrowcol(cell.getColumnIndex()+1,firstcol,lastcol)){  

      switch(cell.getCellType()){ 
      case Cell.CELL_TYPE_NUMERIC: // numeric value 
       System.out.println(cell.getNumericCellValue()); 
       break; 
      case Cell.CELL_TYPE_STRING: // String Value 
       System.out.println(cell.getStringCellValue()); 
       break; 

       //..add more 
       } 
      } 
      } 
     } 
    } 

    } catch (IOException e) { 
     e.printStackTrace(); 
    } 
} 

说明的checkrightrowcol

public static boolean checkrightrowcol(int n , int start, int end){ 

     while (start!=end){ 
      if(n == start || n == end) 
       return true; 
      start++; 
     } 
     return false; 
    } 

如果返回true IM表中的数据,主我使用 “+1”,因为行和列的索引从 “0”

结果开始:

enter image description here

+0

我试过上面的代码,但面临一个奇怪的问题。能够得到正确的范围说K6:N21如果枢轴是在Excel中手动创建的,但是如果枢轴是以编程方式创建的,则将范围变为K6:L7。只是为了记录,数据透视表是用程序正确创建的。 –

+0

我看到男人,我不知道,但它可能是图书馆的限制 – Frank

相关问题