简体   繁体   English

Grouping a column with dates and times (by date, month, and year) in an Excel Pivot Table using Java Apache POI

[英]Grouping a column with dates and times (by date, month, and year) in an Excel Pivot Table using Java Apache POI

I'm currently working on a Java application using Java Apache POI to create a Pivot table.我目前正在使用 Java Apache POI 开发 Java 应用程序以创建 Z6B8F027B6BBZ46CFA 表。 I have a column that contain datetime values like this "6/21/2019 15:17:17":我有一列包含日期时间值,例如“6/21/2019 15:17:17”:

+---------------------------------+
| Date                | Values    |
+---------------------|-----------+
| 6/21/2019 15:17:17  | 4.31      |
| 6/21/2019 15:17:42  | 3.00      |
| 6/21/2019 15:17:42  | 1.45      |
| 6/21/2019 16:51:28  | 3.00      |
| 6/24/2019 20:08:33  | 3.00      |
| 6/24/2019 20:08:33  | 4.31      |
| 6/24/2019 20:08:33  | 10.15     |
| 6/25/2019 17:57:05  | 21.55     |
| 6/25/2019 18:12:35  | 4.35      |
+---------------------------------+

and I need to group this column in the Pivot table into days (months, years) like that using Java Apache POI我需要使用Java Apache POI将 Pivot 表中的这一列分组为天(月,年)

+---------------------------------+
| Result         | Sum of Values  |
+----------------|----------------+
| 21-Jun         | 11.46          |
| 24-Jun         | 17.46          |
| 25-Jun         | 25.9           |
+----------------|----------------+
| Grand Total    | 55.12          |
+---------------------------------+

Any ideas on how to do this?关于如何做到这一点的任何想法?

PS a similar question already exists, but remained unanswered PS一个类似的问题已经存在,但仍未得到解答

This is not as simple as you might think.这并不像你想象的那么简单。 The pivot table creation of apache poi is very rudimentary until now. apache poi的pivot表创建到现在还很初级。 This is fine as long only default pivot tables are needed.只要只需要默认的 pivot 表就可以了。 Excel will calculate all necessary while opening the file. Excel将在打开文件时计算所有必要的。 But if the need is customizing the pivot table, then more efford is needed.但如果需要定制 pivot 表,则需要更多的努力。 And apache poi does not provide classes and methods for this directly.apache poi并没有直接为此提供类和方法。 Using the underlaying ooxml-schemas classes is necessary.使用底层的ooxml-schemas类是必要的。

In case of your request, we need set a proper pivot cache since the field group settings are set there.如果您有要求,我们需要设置一个适当的 pivot 缓存,因为在那里设置了字段组设置。 Apache poi only sets a rudimentary pivot cache in hope that Excel will correct this while opening the file. Apache poi只设置了一个基本的 pivot 缓存,希望Excel在打开文件时能纠正这个问题。

But to set aa proper pivot cache we need at first determine unique data in data column which ist used as the row label.但是要设置一个适当的 pivot 缓存,我们首先需要确定数据列中的唯一数据,该数据用作 label 行。 That is because only unique data will be stored in pivot cache.这是因为只有唯一的数据将存储在 pivot 缓存中。

If done that we can build the pivot cache and then set field group settings there.如果完成,我们可以构建 pivot 缓存,然后在那里设置字段组设置。

Complete example:完整示例:

import java.io.FileOutputStream;

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

import java.util.TimeZone;
import java.util.GregorianCalendar;

class CreatePivotTableDateValue {

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

  try (Workbook workbook = new XSSFWorkbook();
       FileOutputStream fileout = new FileOutputStream("Excel.xlsx") ) {

   DataFormat format = workbook.createDataFormat();
   CellStyle dateStyle = workbook.createCellStyle();
   dateStyle.setDataFormat(format.getFormat("M\\/d\\/yyyy hh:mm:ss"));

   Sheet sheet = workbook.createSheet();

   String[] headers = new String[]{"Date", "Value"};
   Row row = sheet.createRow(0);
   Cell cell;
   for (int c = 0; c < headers.length; c++) {
    cell = row.createCell(c); cell.setCellValue(headers[c]);
   }

   Object[][] data = new Object[][]{
    new Object[]{new GregorianCalendar(2019, 5, 21, 15, 17, 17), 4.31},
    new Object[]{new GregorianCalendar(2019, 5, 21, 15, 17, 42), 3.00},
    new Object[]{new GregorianCalendar(2019, 5, 21, 15, 17, 42), 1.45},
    new Object[]{new GregorianCalendar(2019, 5, 21, 16, 51, 28 ), 3.00},
    new Object[]{new GregorianCalendar(2019, 5, 24, 20, 8, 33), 3.00},
    new Object[]{new GregorianCalendar(2019, 5, 24, 20, 8, 33), 4.31},
    new Object[]{new GregorianCalendar(2019, 5, 24, 20, 8, 33), 10.15},
    new Object[]{new GregorianCalendar(2019, 5, 25, 17, 57, 05), 21.55},
    new Object[]{new GregorianCalendar(2019, 5, 25, 18, 12, 35), 4.35 }
   };

   for (int r = 0; r < data.length; r++) {
    row = sheet.createRow(r+1);
    Object[] rowData = data[r];
    for (int c = 0; c < rowData.length; c++) {
     cell = row.createCell(c);
     if (rowData[c] instanceof GregorianCalendar) {
      cell.setCellValue((GregorianCalendar)rowData[c]);
      cell.setCellStyle(dateStyle);
     } else if (rowData[c] instanceof Double) {
      cell.setCellValue((Double)rowData[c]);
     }
    }
   }

   sheet.setColumnWidth(0, 19 * 256);

   // create default pivot table
   AreaReference areaReference = new AreaReference("A1:B10",  SpreadsheetVersion.EXCEL2007);
   XSSFPivotTable pivotTable = ((XSSFSheet)sheet).createPivotTable(areaReference, new CellReference("D4"));
   pivotTable.addRowLabel(0);
   pivotTable.addColumnLabel(DataConsolidateFunction.SUM, 1);

   // here ends direct apache poi support

   // customize pivot table
   // determine unique data in data column 0, the row label
   java.util.TreeSet<GregorianCalendar> uniqueItems = new java.util.TreeSet<GregorianCalendar>();
   for (int r = 0; r < data.length; r++) {
    GregorianCalendar calendar = (GregorianCalendar)data[r][0];
    calendar.setTimeZone(TimeZone.getTimeZone("GMT"));
    uniqueItems.add(calendar);
   }

   // we need min date and max date for grouping
   GregorianCalendar minDate = uniqueItems.first();
   GregorianCalendar maxDate = uniqueItems.last();

   // set proper pivot cache
   pivotTable.getPivotCacheDefinition().getCTPivotCacheDefinition().getCacheFields().getCacheFieldArray(0)
    .getSharedItems().setCount(uniqueItems.size());
   pivotTable.getPivotCacheDefinition().getCTPivotCacheDefinition().getCacheFields().getCacheFieldArray(0)
    .getSharedItems().setMinDate(minDate);
   pivotTable.getPivotCacheDefinition().getCTPivotCacheDefinition().getCacheFields().getCacheFieldArray(0)
    .getSharedItems().setMaxDate(maxDate);
   pivotTable.getPivotCacheDefinition().getCTPivotCacheDefinition().getCacheFields().getCacheFieldArray(0)
    .getSharedItems().setContainsDate(true);
   pivotTable.getPivotCacheDefinition().getCTPivotCacheDefinition().getCacheFields().getCacheFieldArray(0)
    .getSharedItems().setContainsString(false);
   pivotTable.getPivotCacheDefinition().getCTPivotCacheDefinition().getCacheFields().getCacheFieldArray(0)
    .getSharedItems().setContainsNonDate(false);
   pivotTable.getPivotCacheDefinition().getCTPivotCacheDefinition().getCacheFields().getCacheFieldArray(0)
    .getSharedItems().setContainsSemiMixedTypes(false);
   for (GregorianCalendar item : uniqueItems) {
    pivotTable.getPivotCacheDefinition().getCTPivotCacheDefinition().getCacheFields().getCacheFieldArray(0)
     .getSharedItems().addNewD().setV(item);
   }

   // set field group settings
   pivotTable.getPivotCacheDefinition().getCTPivotCacheDefinition().getCacheFields().getCacheFieldArray(0)
    .addNewFieldGroup().setBase(0);
   pivotTable.getPivotCacheDefinition().getCTPivotCacheDefinition().getCacheFields().getCacheFieldArray(0)
    .getFieldGroup().addNewRangePr().setGroupBy(org.openxmlformats.schemas.spreadsheetml.x2006.main.STGroupBy.DAYS);
   pivotTable.getPivotCacheDefinition().getCTPivotCacheDefinition().getCacheFields().getCacheFieldArray(0)
    .getFieldGroup().getRangePr().setStartDate(minDate);
   pivotTable.getPivotCacheDefinition().getCTPivotCacheDefinition().getCacheFields().getCacheFieldArray(0)
    .getFieldGroup().getRangePr().setEndDate(maxDate);

   // at least one grup item in group settings
   pivotTable.getPivotCacheDefinition().getCTPivotCacheDefinition().getCacheFields().getCacheFieldArray(0)
    .getFieldGroup().addNewGroupItems().setCount(1);
   pivotTable.getPivotCacheDefinition().getCTPivotCacheDefinition().getCacheFields().getCacheFieldArray(0)
    .getFieldGroup().getGroupItems().addNewS().setV("0");

   workbook.write(fileout);

  }

 }
}

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

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