java:如何使用ApachePOI创建pivot?

java:如何使用ApachePOI创建pivot?,java,excel,apache-poi,pivot-table,Java,Excel,Apache Poi,Pivot Table,我试图用ApachePOI创建一个Excel Pivot,但我真的不知道如何创建我想要的格式。我使用此代码创建,但得到空值: XSSFPivotTable pivotTable = sheet.createPivotTable(aref, pos); pivotTable.addColumnLabel(DataConsolidateFunction.SUM, 2, colNames[2]); pivotTable.addColumnLabel(DataConsolidateFunction.SU

我试图用ApachePOI创建一个Excel Pivot,但我真的不知道如何创建我想要的格式。我使用此代码创建,但得到空值:

XSSFPivotTable pivotTable = sheet.createPivotTable(aref, pos);
pivotTable.addColumnLabel(DataConsolidateFunction.SUM, 2, colNames[2]);
pivotTable.addColumnLabel(DataConsolidateFunction.SUM, 3, colNames[3]);
pivotTable.addColumnLabel(DataConsolidateFunction.SUM, 0, colNames[0]);
pivotTable.addColumnLabel(DataConsolidateFunction.SUM, 1, colNames[1]);
我的数据如下所示:

我希望它看起来像这样:


我如何做到这一点

ApachePOI对创建透视表只有基本的支持。它只创建默认的透视表,但不能创建特殊设置而不返回到底层的
ooxml模式

对于您的数据源,以下代码创建默认情况下apache poi支持的内容:

import java.io.FileOutputStream;
import java.io.FileInputStream;

import org.apache.poi.ss.SpreadsheetVersion;
import org.apache.poi.ss.util.AreaReference;
import org.apache.poi.ss.util.CellReference;
import org.apache.poi.xssf.usermodel.*;

class CreatePivotTableDefault {

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

  try (XSSFWorkbook workbook = new XSSFWorkbook(new FileInputStream("ExcelSource.xlsx")); 
       FileOutputStream fileout = new FileOutputStream("ExcelResult.xlsx") ) {

   XSSFSheet dataSheet = workbook.getSheetAt(0);
   XSSFSheet pivotSheet = workbook.createSheet("Pivot");

   AreaReference areaReference = new AreaReference("A1:D5", SpreadsheetVersion.EXCEL2007);

   XSSFPivotTable pivotTable = pivotSheet.createPivotTable(areaReference, new CellReference("A1"), dataSheet);

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

   workbook.write(fileout);

  }

 }
}
这将以默认的大纲格式创建透视表

如果您想要创建一个不是大纲格式的透视表,并且不显示每个字段的小计,那么我们需要使用底层的
ooxml模式
类。我们需要创建正确的透视表字段项。我们需要构建一个缓存定义,其中包含这些项的共享元素。另见

以下代码应该从数据源创建所需的透视表:

import java.io.FileOutputStream;
import java.io.FileInputStream;

import org.apache.poi.ss.SpreadsheetVersion;
import org.apache.poi.ss.util.AreaReference;
import org.apache.poi.ss.util.CellReference;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTPivotField;
import org.apache.poi.ss.usermodel.DataFormatter;
import org.apache.poi.xssf.usermodel.*;

class CreatePivotTable {

 static void addRowLabel(XSSFPivotTable pivotTable, XSSFSheet dataSheet, AreaReference areaReference, int column) { 

  DataFormatter formatter = new DataFormatter(java.util.Locale.US);
  //create row label - apache poi creates as much fields for each as rows are in the pivot table data range
  pivotTable.addRowLabel(column);

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

  //build pivot table and cache
  CTPivotField ctPivotField = pivotTable.getCTPivotTableDefinition().getPivotFields().getPivotFieldArray(column);
  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 
   pivotTable.getPivotCacheDefinition().getCTPivotCacheDefinition().getCacheFields().getCacheFieldArray(column)
    .getSharedItems().addNewS().setV(item);
   i++;
  }

  //set pivot field settings
  ctPivotField.setOutline(false); // no outline format
  ctPivotField.setDefaultSubtotal(false); // no subtotals for this field

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

 }

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

  try (XSSFWorkbook workbook = new XSSFWorkbook(new FileInputStream("ExcelSource.xlsx")); 
       FileOutputStream fileout = new FileOutputStream("ExcelResult.xlsx") ) {

   XSSFSheet dataSheet = workbook.getSheetAt(0);
   XSSFSheet pivotSheet = workbook.createSheet("Pivot");

   AreaReference areaReference = new AreaReference("A1:D5", SpreadsheetVersion.EXCEL2007);

   XSSFPivotTable pivotTable = pivotSheet.createPivotTable(areaReference, new CellReference("A1"), dataSheet);

   addRowLabel(pivotTable, dataSheet, areaReference, 2);
   addRowLabel(pivotTable, dataSheet, areaReference, 3);
   addRowLabel(pivotTable, dataSheet, areaReference, 0);
   addRowLabel(pivotTable, dataSheet, areaReference, 1);

   workbook.write(fileout);

  }

 }
}
import java.io.FileOutputStream;
导入java.io.FileInputStream;
导入org.apache.poi.ss.SpreadsheetVersion;
导入org.apache.poi.ss.util.AreaReference;
导入org.apache.poi.ss.util.CellReference;
导入org.openxmlformats.schemas.spreadsheetml.x2006.main.CTPivotField;
导入org.apache.poi.ss.usermodel.DataFormatter;
导入org.apache.poi.xssf.usermodel.*;
类创建数据透视表{
静态void addRowLabel(XSSF数据透视表、XSSFSheet数据表、AreaReference AreaReference、int列){
DataFormatter formatter=新的DataFormatter(java.util.Locale.US);
//创建行标签-ApachePOI为每个行创建的字段数与透视表数据范围中的行数相同
数据透视表.addRowLabel(列);
//确定列中的唯一标签
java.util.TreeSet uniqueItems=new java.util.TreeSet();
对于(int r=areaReference.getFirstCell().getRow()+1;r=i;k--){
ctPivotField.getItems().removeItem(k);
}
ctPivotField.getItems().setCount(i);
}
公共静态void main(字符串[]args)引发异常{
试试(XSSFWorkbook工作簿=新XSSFWorkbook(新文件输入流(“ExcelSource.xlsx”));
FileOutputStream fileout=新的FileOutputStream(“ExcelResult.xlsx”)){
XSSFSheet数据表=工作簿.getSheetAt(0);
XSSFSheet pivotSheet=workbook.createSheet(“Pivot”);
AreaReference AreaReference=新的AreaReference(“A1:D5”,电子表格版本.EXCEL2007);
XSSFPivotTable pivotTable=pivotSheet.createPivotTable(区域引用,新单元格引用(“A1”),数据表);
addRowLabel(数据透视表、数据表、区域参考,2);
addRowLabel(数据透视表、数据表、区域参考,3);
addRowLabel(数据透视表、数据表、区域参考、0);
addRowLabel(数据透视表、数据表、区域参考,1);
工作簿。写入(归档);
}
}
}

此代码使用当前的ApachePOI4.1.2进行测试,需要所有模式的完整jar,如中所述

哇,谢谢,我甚至没有考虑过这种方法。我遇到了以下异常,我不知道如何修复:线程“main”java.lang.NoSuchMethodError中的异常:“org.apache.xmlbeans.XmlObject org.openxmlformats.schemas.spreadsheetml.x2006.main.impl.CTWorksheetImpl.generatedSetterHelperImpl(org.apache.xmlbeans.XmlObject,javax.xml.namespace.QName,int,short)@regis_studios:此代码使用当前的
apache poi 4.1.2
进行测试,需要所有模式的完整jar
ooxml-schemas-1.4.jar
(较低版本适用于较旧版本)如中所述。您使用的是什么
apache-poi
版本?请确保
ooxml模式
jar以及
poi-ooxml模式jar
适合您的
apache-poi
版本。我丢失了poi-ooxml模式jar。现在它可以工作了!