【问题标题】:Apache POI - is there a way to create a pivot table where the source table is a SXSSFSheet?Apache POI - 有没有办法创建源表是 SXSSFSheet 的数据透视表?
【发布时间】:2018-04-13 22:44:42
【问题描述】:

是这样的: 我必须使用 SXSSFWorkbook(XSSFWorkbook 的流式版本)来创建我的 Excel,因为我必须创建一个包含 700000/800000 行和大约 20 列的工作表。 此表代表我的最终数据透视表的源表。

SXSSFWorkbook workbook();
XSSFSheet pivotSheet = workbook.getXSSFWorkbook().createSheet("Pivot sheet");
AreaReference ar = ....:
CellReference cr = ....;
XSSFPivotTable pivotTable = pivotSheet.createPivotTable(ar, cr); // ERROR!!

问题是,当我尝试在该源上创建此 Pivot 时,XSSFPivotTable.createPivotTable 方法不起作用,尽管 AreaReference 和 CellReference 参数都可以。

如果我使用行数较少的 XSSFWorkbook(不是流式版本),一切正常,但我没有达到我的目标!

谁能给我一个解决方案? 非常感谢!!!!!!

斯特凡诺

【问题讨论】:

  • 我强调我的问题出在我的 Pivot 的 SOURCE 表 SXSSFsheet(流)上

标签: java excel apache-poi pivot


【解决方案1】:

SXSSFWorkbook 可以从XSSFWorkbook 创建。

所以我要做的是创建XSSFWorkbook,其中XSSFSheet 至少包含数据标题,另一个XSSFSheet 用于数据透视表。然后在这个XSSFSheet 上创建XSSFPivotTable,但要使对数据表的引用足够大以供以后的数据使用。

然后我会从这个XSSFWorkbook 创建SXSSFWorkbook,将数据表作为SXSSFSheet,然后将大量数据流式传输到数据表中。

完整示例:

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 org.apache.poi.xssf.streaming.*;

import java.util.Random;
import java.io.FileOutputStream;

class SXSSFPivotTableTest {

 private static void streamCellData(Sheet sheet, int rowsCount) {

  for (int r = 1; r <= rowsCount; r++) {
   Row row = sheet.createRow(r);
   Cell cell = row.createCell(0);
   cell.setCellValue("Name " + ((r-1) % 4 + 1));
   cell = row.createCell(1);
   cell.setCellValue(r * new java.util.Random().nextDouble());
   cell = row.createCell(2);
   cell.setCellValue(r * new java.util.Random().nextDouble());
   cell = row.createCell(3);
   cell.setCellValue("City " + ((r-1) % 3 + 1));  
  }

 }

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

  int rowsCount = 1000000;

  //first create XSSFWorkbook
  XSSFWorkbook wb = new XSSFWorkbook();

  //create XSSFSheet with at least the headings
  XSSFSheet sheet = wb.createSheet("Sheet1");
  Row row = sheet.createRow(0);
  Cell cell = row.createCell(0);
  cell.setCellValue("Name");
  cell = row.createCell(1);
  cell.setCellValue("Value1");
  cell = row.createCell(2);
  cell.setCellValue("Value2");
  cell = row.createCell(3);
  cell.setCellValue("City");

  //create XSSFSheet for pivot table
  XSSFSheet pivotSheet = wb.createSheet("Pivot sheet");

  //create pivot table
  XSSFPivotTable pivotTable = pivotSheet.createPivotTable(
    new AreaReference(new CellReference("Sheet1!A1"), 
                      new CellReference("Sheet1!D" + (rowsCount +1)), //make the reference big enough for later data
                      SpreadsheetVersion.EXCEL2007),
    new CellReference("A5"));
  //Configure the pivot table
  //Use first column as row label
  pivotTable.addRowLabel(0);
  //Sum up the second column
  pivotTable.addColumnLabel(DataConsolidateFunction.SUM, 1);
  //Avarage the third column
  pivotTable.addColumnLabel(DataConsolidateFunction.AVERAGE, 2);
  //Add filter on forth column
  pivotTable.addReportFilter(3);

  //now create SXSSFWorkbook from XSSFWorkbook
  SXSSFWorkbook swb = new SXSSFWorkbook(wb);
  SXSSFSheet ssheet = swb.getSheet("Sheet1");

  //now stream the big amount of data to build the pivot table on into Sheet1
  streamCellData(ssheet, rowsCount);

  swb.write(new FileOutputStream("SXSSFPivotTableTest.xlsx"));
  swb.close();
  swb.dispose();

 }
}

【讨论】:

  • 感谢 Axel,很好的解决方案,也帮助了我!
猜你喜欢
  • 2015-11-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-03
  • 2012-09-12
  • 1970-01-01
相关资源
最近更新 更多