简体   繁体   English

java:如何使用 apache poi 创建一个枢轴?

[英]java: How to create a pivot with apache poi?

I'm trying to create an Excel Pivot with apache poi, but I dont really understand how to create the format that I want.我正在尝试使用 apache poi 创建 Excel Pivot,但我真的不明白如何创建我想要的格式。 I use this code to create, but I get empty values:我使用此代码创建,但我得到空值:

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

My data looks like this:我的数据如下所示:

在此处输入图片说明

and I want it to look like this:我希望它看起来像这样:

在此处输入图片说明

How do I achieve that?我如何做到这一点?

Apache poi has only rudimentary support for creating pivot tables. Apache poi对创建数据透视表只有基本的支持。 It only creates default pivot tables but is not able creating special settings without falling back to the underlying ooxml-schemas classes.它只创建默认数据透视表,但不能在不回退到底层ooxml-schemas类的情况下创建特殊设置。

For your data source the following code creates what apache poi supports by default:对于您的数据源,以下代码创建了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);

  }

 }
}

This creates a pivot table in outline format, which is the default.这将创建一个大纲格式的数据透视表,这是默认设置。

If you wants creating a pivot table which is not in outline format and is not showing subtotals for each field, we need using the underlying ooxml-schemas classes.如果您想创建一个不是大纲格式的数据透视表并且不显示每个字段的小计,我们需要使用底层ooxml-schemas类。 We need creating the correct pivot table field items.我们需要创建正确的数据透视表字段项。 And we need to build a cache definition which has shared elements for those items.我们需要构建一个缓存定义,其中包含这些项目的共享元素。 See also Apache POI XSSFPivotTable setDefaultSubtotal .另请参阅Apache POI XSSFPivotTable setDefaultSubtotal

The following code should create the pivot table you wants from your data source:以下代码应从数据源创建您想要的数据透视表:

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

  }

 }
}

This code is tested using current apache poi 4.1.2 and needs the full jar of all of the schemas ooxml-schemas-1.4.jar (lower versions for older releases) as mentioned in apache poi FAQ-N10025 .此代码使用当前的apache poi 4.1.2进行测试,并且需要apache poi FAQ-N10025 中提到的所有模式ooxml-schemas-1.4.jar的完整 jar(旧版本的较低版本)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM