Java 隐藏小计时重新排序RowLabel时获取异常-Apache POI

Java 隐藏小计时重新排序RowLabel时获取异常-Apache POI,java,apache-poi,pivot-table,Java,Apache Poi,Pivot Table,根据下面的代码,我不想添加addRowLabel(1),但需要addRowLabel(2)。运行应用程序并打开数据透视表后,会出现异常,但如果添加addRowLabel(1)(当前已注释),则会按预期工作。这是在添加隐藏小计的逻辑后发生的。这是apache POI的预期行为还是可以修复? 请在下面查找代码。 注意:隐藏小计时会出现此问题 package com.test.pivottables; import org.apache.poi.xssf.usermodel.*; impo

根据下面的代码,我不想添加addRowLabel(1),但需要addRowLabel(2)。运行应用程序并打开数据透视表后,会出现异常,但如果添加addRowLabel(1)(当前已注释),则会按预期工作。这是在添加隐藏小计的逻辑后发生的。这是apache POI的预期行为还是可以修复? 请在下面查找代码。 注意:隐藏小计时会出现此问题

  package com.test.pivottables;
  import org.apache.poi.xssf.usermodel.*;
  import org.apache.poi.ss.usermodel.*;
   import org.apache.poi.ss.util.*;
     import org.apache.poi.ss.*;
   import java.io.*;
   import java.util.ArrayList;
  import java.util.HashSet;
   import java.util.Iterator;
 import java.util.List;
 import java.util.Set;
  import org.openxmlformats.schemas.spreadsheetml.x2006.main.*;
 class TestPivotTables {
  public static void main(String[] args) throws IOException{
    Workbook wb = new XSSFWorkbook();
    String[][] data = new String[][]{{"STATUS","PASSED","DATA","VALUE"}, 
  {"BLUE","Y","TTT","20"},
 {"RED","N","UUU","10"},{"BLUE","N","PPP","30"}};

    XSSFSheet sheet = (XSSFSheet) wb.createSheet("data");
    XSSFSheet pivot = (XSSFSheet) wb.createSheet("summary");
    for(String[] dataRow : data){
        XSSFRow row = sheet.createRow(sheet.getPhysicalNumberOfRows());
        for(String dataCell : dataRow){
            XSSFCell cell = 
        row.createCell(row.getPhysicalNumberOfCells());
            cell.setCellValue(dataCell);
        }
    }

    XSSFTable table = sheet.createTable();    
    CTTable cttable = table.getCTTable();
    table.setDisplayName("table");
    cttable.setRef("A1:D4");
    cttable.setId(1);

    CTTableColumns columns = cttable.addNewTableColumns();
    columns.setCount(3);

    int i = 1;
    for (String colName : data[0]){
        CTTableColumn column = columns.addNewTableColumn();
        column.setId(++i);
        column.setName(colName);      
    }

    XSSFPivotTable pivotTable =  pivot.createPivotTable(new 
 AreaReference("A1:D4", SpreadsheetVersion.EXCEL2007),
new CellReference("A4"), sheet);

    pivotTable.addRowLabel(0);
    pivotTable.addRowLabel(2);
    //pivotTable.addRowLabel(1);

    List<Integer> iterList = new ArrayList<Integer>();
    iterList.add(0);
    iterList.add(2);
    //iterList.add(1);
    pivotTable.getCTPivotTableDefinition().setRowHeaderCaption("Colour");
   for (int j=0;j<iterList.size();j++) {
        CTPivotField ctPivotField = 
   pivotTable.getCTPivotTableDefinition().getPivotFields().
  getPivotFieldList().get(iterList.get(j));
        for (i = 0; i < sheet.getLastRowNum()-1; i++) {
            if(ctPivotField.getItems().getItemArray(i)!=null) {
                ctPivotField.getItems().getItemArray(i).unsetT();
                ctPivotField.getItems().getItemArray(i).setX((long)i);
            }
        }
        for (i = sheet.getLastRowNum(); i > sheet.getLastRowNum()-2; i--) 
  {
            if(ctPivotField.getItems().getItemArray(i)!=null) {
                ctPivotField.getItems().removeItem(i);
            }
        }
        ctPivotField.getItems().setCount(2);

        Set<String> collection = new HashSet<String>();
        int ctr = 0;
        Row row = null;
        Cell cell = null;
        boolean isNull = false;
        do{
            try{
                row = sheet.getRow(ctr);
                cell = row.getCell(0);
                collection.add(cell.toString());
                ctr++;
            } catch(Exception e) {
                isNull = true;
            }
        }while(isNull!=true);
        if(collection!=null && collection.size()>0) {
            Iterator value = collection.iterator(); 
            while (value.hasNext()) { 
                pivotTable.getPivotCacheDefinition().
  getCTPivotCacheDefinition().getCacheFields().
  getCacheFieldList().get(j).getSharedItems().addNewS().
  setV(value.next().toString()); 
            } 
        }
        ctPivotField.setAutoShow(false);
        ctPivotField.setDefaultSubtotal(false);
        ctPivotField.setSubtotalTop(false);
        ctPivotField.setSubtotalCaption(null);
        ctPivotField.setCompact(false);
    }
    System.out.println("----end---");
    pivotTable.addColumnLabel(DataConsolidateFunction.COUNT, 3, "test");

    FileOutputStream fileOut = new FileOutputStream("pivotsample1.xlsx");
    wb.write(fileOut);
    wb.close();

}}
package com.test.pivottables;
导入org.apache.poi.xssf.usermodel.*;
导入org.apache.poi.ss.usermodel.*;
导入org.apache.poi.ss.util.*;
导入org.apache.poi.ss.*;
导入java.io.*;
导入java.util.ArrayList;
导入java.util.HashSet;
导入java.util.Iterator;
导入java.util.List;
导入java.util.Set;
导入org.openxmlformats.schemas.spreadsheetml.x2006.main.*;
类TestPivotTables{
公共静态void main(字符串[]args)引发IOException{
工作簿wb=新XSSFWorkbook();
字符串[][]数据=新字符串[][{{{“状态”、“已通过”、“数据”、“值”},
{“蓝色”、“Y”、“TTT”、“20”},
{“红色”、“N”、“UUU”、“10”}、{“蓝色”、“N”、“PPP”、“30”};
XSSFSheet sheet=(XSSFSheet)wb.createSheet(“数据”);
XSSFSheet pivot=(XSSFSheet)wb.createSheet(“摘要”);
for(字符串[]数据行:数据){
XSSFRow row=sheet.createRow(sheet.getPhysicalNumberOfRows());
for(字符串数据单元:dataRow){
XSSFCell单元=
createCell(row.getPhysicalNumberOfCells());
cell.setCellValue(数据单元);
}
}
XSSFTable table=sheet.createTable();
CTTable=table.getCTTable();
table.setDisplayName(“table”);
cttable.setRef(“A1:D4”);
cttable.setId(1);
CTTableColumns=cttable.addNewTableColumns();
列。设置计数(3);
int i=1;
for(字符串colName:data[0]){
CTTableColumn=columns.addNewTableColumn();
column.setId(++i);
column.setName(colName);
}
XSSFPivotTable pivotTable=pivot.createPivotTable(新建)
区域参考(“A1:D4”,电子表格版本.EXCEL2007),
新单元参考(“A4”),第页;
数据透视表.addRowLabel(0);
数据透视表.addRowLabel(2);
//数据透视表.addRowLabel(1);
List iterList=new ArrayList();
iterList.add(0);
增加(2);
//iterList.add(1);
数据透视表.getCTPivotTableDefinition().setRowHeaderCaption(“颜色”);
对于(int j=0;j sheet.getLastRowNum()-2;i--)
{
if(ctPivotField.getItems().getItemArray(i)!=null){
ctPivotField.getItems().removeItem(i);
}
}
ctPivotField.getItems().setCount(2);
Set collection=newhashset();
int ctr=0;
行=空;
Cell=null;
布尔值isNull=false;
做{
试一试{
row=sheet.getRow(ctr);
cell=row.getCell(0);
collection.add(cell.toString());
ctr++;
}捕获(例外e){
isNull=true;
}
}while(isNull!=true);
if(collection!=null&&collection.size()>0){
迭代器值=collection.Iterator();
while(value.hasNext()){
数据透视表。getPivotCacheDefinition()。
getCTPivotCacheDefinition().getCacheFields()。
getCacheFieldList().get(j).getSharedItems().addNewS()。
setV(value.next().toString());
} 
}
ctPivotField.setAutoShow(false);
ctPivotField.setDefaultSubtotal(false);
ctPivotField.setSubtotalTop(假);
ctPivotField.setSubtotalCaption(空);
ctPivotField.setCompact(false);
}
System.out.println(“----结束----”;
数据透视表.addColumnLabel(DataConsolidateFunction.COUNT,3,“测试”);
FileOutputStream fileOut=新的FileOutputStream(“pivotsample1.xlsx”);
wb.写入(文件输出);
wb.close();
}}

问题在于如何构建数据透视表定义和数据透视缓存定义。必须这样做,因为
apachepoi
为每个行标签创建的字段与pivot表数据范围中的行一样多。当对枢轴字段进行特殊设置时,这是错误的。你试着这么做,但你做错了

我不能详细说明你到底哪里出了问题,因为那太费劲了。但需要做的是:

对于行标签中的每列:

  • 确定该列中的唯一标签。这是必要的建设 缓存
然后构建数据透视表和缓存

对于每个唯一的标签:

  • 将数据透视字段项生成为编号项
  • 生成具有此标签的共享元素的缓存定义
然后从透视表定义中删除更多项。但如果应该有小计,则在那里保留一个默认元素。如果不是,那就不是

完整示例:

import org.apache.poi.xssf.usermodel.*;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.*;
import org.apache.poi.ss.*;
import java.io.*;
import java.util.ArrayList;
import java.util.TreeSet;
import java.util.List;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.*;

class TestPivotTables {
 public static void main(String[] args) throws IOException{
  Workbook wb = new XSSFWorkbook();
  String[][] data = new String[][]{
   {"STATUS","PASSED","DATA","VALUE"}, 
   {"BLUE","Y","TTT","20"},
   {"RED","N","UUU","10"},
   {"BLUE","N","PPP","30"}
  };

  XSSFSheet sheet = (XSSFSheet) wb.createSheet("data");
  XSSFSheet pivot = (XSSFSheet) wb.createSheet("summary");
  for(String[] dataRow : data){
   XSSFRow row = sheet.createRow(sheet.getPhysicalNumberOfRows());
   for(String dataCell : dataRow){
    XSSFCell cell = row.createCell(row.getPhysicalNumberOfCells());
    cell.setCellValue(dataCell);
   }
  }

  AreaReference areaReference = new AreaReference("A1:D4", SpreadsheetVersion.EXCEL2007);
  XSSFPivotTable pivotTable = pivot.createPivotTable(areaReference, new CellReference("A4"), sheet);

  pivotTable.getCTPivotTableDefinition().setRowHeaderCaption("Colour");

  List<Integer> iterList = new ArrayList<Integer>();
  iterList.add(0);
  iterList.add(2);
  iterList.add(1);

  for (Integer j : iterList) {

   //create row label - apache poi creates as much fields for each as rows are in the pivot table data range
   pivotTable.addRowLabel(j);

   //determine unique labels in column j
   TreeSet<String> uniqueItems = new java.util.TreeSet<String>();
   for (int r = areaReference.getFirstCell().getRow()+1; r < areaReference.getLastCell().getRow()+1; r++) {
    uniqueItems.add(sheet.getRow(r).getCell(j).getStringCellValue());
   }
   System.out.println(uniqueItems);

   //build pivot table and cache
   CTPivotField ctPivotField = pivotTable.getCTPivotTableDefinition().getPivotFields().getPivotFieldArray(j);
   int i = 0;
   for (String item : uniqueItems) {
    //take the items as numbered items: <item x="0"/><item x="1"/>
    ctPivotField.getItems().getItemArray(i).unsetT();
    ctPivotField.getItems().getItemArray(i).setX((long)i);
    //build a cache definition which has shared elements for those items 
    //<sharedItems><s v="BLUE"/><s v="RED"/></sharedItems>
    pivotTable.getPivotCacheDefinition().getCTPivotCacheDefinition().getCacheFields().getCacheFieldArray(j)
     .getSharedItems().addNewS().setV(item);
    i++;
   }

   ctPivotField.setAutoShow(false);
   ctPivotField.setDefaultSubtotal(false);
   //ctPivotField.setSubtotalTop(false);
   //ctPivotField.setSubtotalCaption(null);
   ctPivotField.setCompact(false);

   //remove further items
   if (ctPivotField.getDefaultSubtotal()) i++; //let one default item be if there shall be subtotals
   for (int k = ctPivotField.getItems().getItemList().size()-1; k >= i; k--) {
    ctPivotField.getItems().removeItem(k);
   }
   ctPivotField.getItems().setCount(i);

  }

  System.out.println("----end---");

  pivotTable.addColumnLabel(DataConsolidateFunction.COUNT, 3, "test");

  FileOutputStream fileOut = new FileOutputStream("pivotsample1.xlsx");
  wb.write(fileOut);
  fileOut.close();
  wb.close();
 }
}
import org.apache.poi.xssf.usermodel.*;
导入org.apache.poi.ss.usermodel.*;
导入org.apache.poi.ss.util.*;
导入org.apache.poi.ss.*;
导入java.io.*;
导入java.util.ArrayList;
导入java.util.TreeSet;
导入java.util.List;
导入org.openxmlformats.schemas.spreadsheetml.x2006.main.*;
类TestPivotTables{
公共静态void main(字符串[]args)引发IOException{
工作簿wb=新XSSFWorkbook();
字符串[][]数据=新字符串[][]{
{“状态”、“已通过”、“数据”、“值”},
{“蓝色”、“Y”、“TTT”、“20”},
{“红色”、“N”、“UUU”、“10”},
{“蓝色”、“N”、“PPP”、“30”}
};
XSSFSheet sheet=(XSSFSheet)wb.createSheet(“数据”);
XSSFSheet pivot=(XSSFSheet)wb.createSheet(“摘要”);
for(字符串[]数据行:数据){
XSSFRow row=sheet.createRow(sheet.getPhysicalNumberOfRows());
for(字符串数据单元:dataRow){
XSSFCell cell=row.createCell(row.getPhysicalNumberOfCells());
cell.setCellValue(数据单元);
}
}
AreaReference AreaReference=新的AreaReference(“A1:D4”,电子表格