简体   繁体   English

Apache POI - 有没有办法计算 pivot 表中字符串的出现次数?

[英]Apache POI - Is there a way to count occurrence of a string in a pivot table?

I am using version 4.1.2 of Apache Poi and I have this dataset:我正在使用 Apache Poi 的 4.1.2 版,我有这个数据集:

String[] headers = new String[] { "Company", "Status" };

Object[][] sheetData = {
                {"Company 1", "OK"},
                {"Company 1", "NG"},
                {"Company 2", "NG"},
                {"Company 1", "OK"},
                {"Company 3", "OK"},
                {"Company 1", "NG"},
        };

I'm trying to create a pivot table using Apache POI that groups and counts the occurrence of strings from the 2nd column.我正在尝试使用 Apache POI 创建一个 pivot 表,该 POI 对第二列中字符串的出现进行分组和计数。 I've tried:我试过了:

pivotTable.addRowLabel(0);
pivotTable.addColumnLabel(DataConsolidateFunction.COUNT, 1);

But it somehow still counts the occurrences from the first column.但它仍然以某种方式计算第一列的出现次数。

The pivot table I'm trying to create:我正在尝试创建的 pivot 表:

在此处输入图像描述

and the pivot table that is being generated:以及正在生成的 pivot 表:

在此处输入图像描述

The pivot table you are showing as the one you are trying to create shows the column 1 = B (Status) as a column label using a DataConsolidateFunction as well as column label used for labeling columns. pivot 表显示为您尝试创建的表,将列1 = B (状态)显示为列 label,使用DataConsolidateFunction以及列 ZD304BA20E96D87411588EEABAC850E34 使用列。 So one column has two different properties in the pivot table here.因此,这里的 pivot 表中的一列有两个不同的属性。 That makes it complicated.这使它变得复杂。

The DataConsolidateFunction column label is done already using pivotTable.addColumnLabel(DataConsolidateFunction.COUNT, 1) . DataConsolidateFunction列 label 已经使用pivotTable.addColumnLabel(DataConsolidateFunction.COUNT, 1)完成。 This also sets dataField setting for the column.这也设置了列的dataField设置。

For the column label used for labeling columns apache poi 4.1.2 provides the method XSSFPivotTable.addColLabel .对于用于标记列apache poi 4.1.2的列 label 提供了方法XSSFPivotTable.addColLabel But this method removes the dataField setting.但是此方法删除了dataField设置。 So we need set it new using the low level ooxml-shemas classes.所以我们需要使用低级别ooxml-shemas类来设置它。

And the order of the commands is important here because they effect the same column.命令的顺序在这里很重要,因为它们影响同一列。 First do pivotTable.addColumnLabel and then do pivotTable.addColLabel .首先做pivotTable.addColumnLabel然后做pivotTable.addColLabel Else addColumnLabel will set dataField setting but will remove axis="axisCol" setting from that column.否则addColumnLabel将设置dataField设置,但会从该列中删除axis="axisCol"设置。 But because of the two different properties in the pivot table both settings are needed for that column.但由于 pivot 表中的两个不同属性,该列需要两个设置。

Complete example:完整示例:

import java.io.FileOutputStream;

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

class CreatePivotTable {

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

  String[] headers = new String[] { "Company", "Status" };
  Object[][] sheetData = {
   {"Company 1", "OK"},
   {"Company 1", "NG"},
   {"Company 2", "NG"},
   {"Company 1", "OK"},
   {"Company 3", "OK"},
   {"Company 1", "NG"},
  };

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

   XSSFSheet dataSheet = workbook.createSheet("Data");
   XSSFRow row;
   XSSFCell cell;
   int r = 0;
   row = dataSheet.createRow(r++);
   int c = 0;
   for (String header : headers) {
    cell = row.createCell(c++);
    cell.setCellValue(header);
   }
   for (Object[] dataRow : sheetData) {
    row = dataSheet.createRow(r++);
    c = 0;
    for (Object value : dataRow) {
     cell = row.createCell(c++);
     if (value instanceof String) {
      cell.setCellValue((String)value);
     } //else if...
    }
   } 

   XSSFSheet pivotSheet = workbook.createSheet("Pivot");

   AreaReference areaReference = new AreaReference(
    new CellReference(0, 0),
    new CellReference(sheetData.length, headers.length-1),
    SpreadsheetVersion.EXCEL2007);

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

   pivotTable.addRowLabel(0);
   pivotTable.addColumnLabel(DataConsolidateFunction.COUNT, 1);

   pivotTable.addColLabel(1);
   //Method addColLabel removes the dataField setting. So we need set it new.
   pivotTable.getCTPivotTableDefinition().getPivotFields().getPivotFieldArray(1)
    .setDataField(true);

   workbook.write(fileout);

  }

 }
}

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

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