具有水平列{Apache}的Apache POI数据透视表

时间:2018-04-23 11:54:42

标签: java excel apache-poi

我喜欢这样的excel数据 enter image description here 当我想用下面的代码生成数据透视表时

XSSFSheet pivot = wb.createSheet("pivot");
AreaReference areaReference = new AreaReference("A2:D" + i, SpreadsheetVersion.EXCEL2007);
CellReference cellReference = new CellReference("A1");

XSSFPivotTable pivotTable = pivot.createPivotTable(areaReference, cellReference, sheet);

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

pivotTable.addColumnLabel(DataConsolidateFunction.SUM, 3);

我得到了下一个结果 enter image description here 但是想要这样的东西 enter image description here

我做错了什么?

2 个答案:

答案 0 :(得分:1)

因为它的名称告诉addRowLabel添加了一个行标签。但您希望C表的列data(2)成为列标签。最高apache poi版本3.17,实现此目的的唯一方法是使用底层的低级对象。但这需要有关数据透视表内部的知识。

调查内部的最佳方法是使用*.xlsx的GUI创建一个包含数据透视表的Excel文件。此*.xlsx文件只是ZIP存档。所以我们可以解压缩它并进行研究。在那里,我们会找到XML中工作表的/xl/worksheets个文件,/xl/pivotTables中的数据透视表定义以及/xl/pivotCache中的数据透视表缓存。根据这个XML,我们可以使用包org.openxmlformats.schemas.spreadsheetml.x2006.main.*的低级对象进行编程。

示例:

enter image description here

代码:

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

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

class PivotTableCreating {

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

  XSSFWorkbook wb = (XSSFWorkbook)WorkbookFactory.create(new FileInputStream("PivotExample.xlsx"));

  XSSFSheet pivotSheet = wb.createSheet("pivot");

  XSSFSheet dataSheet = wb.getSheet("data");
  int lastRowNum = dataSheet.getLastRowNum();

  XSSFPivotTable pivotTable = pivotSheet.createPivotTable(
   new AreaReference(new CellReference("data!A1"), new CellReference("data!D" + (lastRowNum+1)), 
   SpreadsheetVersion.EXCEL2007),
   new CellReference("A5"));

  pivotTable.addRowLabel(1);

  pivotTable.addRowLabel(2); //column C as a row label = RowField and AXIS_ROW

  //do changing column C as a col label
  pivotTable.getCTPivotTableDefinition().getPivotFields().getPivotFieldArray(2)
   .setAxis(org.openxmlformats.schemas.spreadsheetml.x2006.main.STAxis.AXIS_COL); //AXIS_COL

  //remove column C from RowFields
  pivotTable.getCTPivotTableDefinition().getRowFields().removeField(1); 
  pivotTable.getCTPivotTableDefinition().getRowFields().setCount(1);

  //create ColFields for column C
  pivotTable.getCTPivotTableDefinition().addNewColFields().addNewField().setX(2); 
  pivotTable.getCTPivotTableDefinition().getColFields().setCount(1);

  pivotTable.addColumnLabel(DataConsolidateFunction.SUM, 3);

  wb.write(new FileOutputStream("PivotExampleNew.xlsx"));
  wb.close();

 }
}

结果:

enter image description here

API - XSSFPivotTable所示,还有进一步的发展(addColLabel)。但是目前(2018年5月)最新的稳定版本apache poi版本3.17没有提供此功能。

答案 1 :(得分:0)

尝试在日期列上执行以下代码:

targets

function(target)替换为您需要的号码(我假设为pivotTable.getCTPivotTableDefinition().getPivotFields().getPivotFieldArray(5).setAxis(STAxis.AXIS_COL) pivotTable.getCTPivotTableDefinition().getPivotFields().getPivotFieldArray(5).addNewItems(); pivotTable.getCTPivotTableDefinition().getPivotFields().getPivotFieldArray(5).getItems().addNewItem() .setT(STItemType.DEFAULT); )。此代码转动列的轴