Apache POI数据透视表 – 如何在Java中使用“介于”值筛选器

huangapple go评论82阅读模式
英文:

Apache POI Pivot Tables- How to use the "In-Between" Value Filter in Java

问题

以下是您提供的代码的翻译部分:

我正在尝试使用Apache POI设计一个数据透视表我想要做的是最初打印出大于某个数字的总和值以及小于某个数字的总和值然而当我尝试这样做时筛选条件彼此抵消这意味着打印出了不应该出现的总和值例如如果我想要总和在2和5之间总和值为1以及大于5的数字都被打印出来这是解释我的问题的代码

// 代码部分略...

这是运行此代码后生成的数据透视表的示例
[![enter image description here][1]][1]

如果您对如何解决这个问题有任何想法请告诉我

请注意,为了减少冗余和提高可读性,我已经略过了一些重复的代码内容。如有需要,您可以随时提问。

英文:

I am trying to design a pivot table using Apache POI, and what I want to do is to initially print the sum value which is greater than a certain number, as well as less than a certain number. However, when I try and do this, the filters cancel each other out, which means that sum values are printed that should not be there. For example, if I want the sum to be between 2 and 5, the sum value of 1, as well as numbers greater than 5, both get printed out. Here is the code that explains my problem:

package com.tutorialspoint.spring;
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 org.openxmlformats.schemas.spreadsheetml.x2006.main.CTAutoFilter;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCustomFilter;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCustomFilters;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTDataField;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTDataFields;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTFilter;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTFilterColumn;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTFilters;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTPivotField;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.STFilterOperator;
import org.springframework.boot.SpringApplication;

import java.util.GregorianCalendar;
import java.util.HashSet;
import java.util.TreeSet;

public class ExcelAutoPivotPracticeApplication {

 public static void main(String[] args) throws Exception {
	 SpringApplication.run(ExcelAutoPivotPracticeApplication.class, args);

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

   DataFormat format = workbook.createDataFormat();
   CellStyle dateStyle = workbook.createCellStyle();
   dateStyle.setDataFormat(format.getFormat("M\\/d\\/yy"));

   Sheet sheet = workbook.createSheet();

   String[] headers = new String[]{"Column1", "Column2", "Date", "IntVal", "Count"};
   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[]{"A", "B1", new GregorianCalendar(2019, 0, 1),  2d},
    new Object[]{"A", "B2", new GregorianCalendar(2019, 0, 1),  4d},
        new Object[]{"B", "B1", new GregorianCalendar(2019, 0, 2),  1d},
    new Object[]{"B", "B2", new GregorianCalendar(2019, 0, 2),  7d},
    new Object[]{"A", "C1", new GregorianCalendar(2019, 0, 1),  5d},
    new Object[]{"A", "C2", new GregorianCalendar(2019, 0, 1),  5d},
    new Object[]{"B", "C1", new GregorianCalendar(2019, 0, 2), 2d},
    new Object[]{"B", "C2", new GregorianCalendar(2019, 0, 2),  8d}
   };
   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 String) {
      cell.setCellValue((String)rowData[c]);
     } else if (rowData[c] instanceof GregorianCalendar) {
      cell.setCellValue((GregorianCalendar)rowData[c]);
      cell.setCellStyle(dateStyle);
     } else if (rowData[c] instanceof Double) {
      cell.setCellValue((Double)rowData[c]);
     }
     else if (rowData[c] instanceof Integer)
    	 cell.setCellValue((Integer) rowData[c]);
    }
   }
AreaReference a = new AreaReference("A1:D9", SpreadsheetVersion.EXCEL2007);
   XSSFPivotTable pivotTable = ((XSSFSheet)sheet).createPivotTable(
    a, 
    new CellReference("E4"));
   pivotTable.addRowLabel(0);
   pivotTable.addRowLabel(1);
   pivotTable.addColLabel(2);
   pivotTable.addColumnLabel(DataConsolidateFunction.SUM, 3);
    pivotTable.addColumnLabel(DataConsolidateFunction.AVERAGE, 3);
   pivotTable.getCTPivotTableDefinition().setCompact(false);
   pivotTable.getCTPivotTableDefinition().setCompactData(false);
   pivotTable.getCTPivotTableDefinition().setOutline(true);
   pivotTable.getCTPivotTableDefinition().setOutlineData(true);
   for (CTPivotField pf: pivotTable.getCTPivotTableDefinition().getPivotFields().getPivotFieldList())
   {
   	System.out.println("FOO");
	pf.setCompact(false);
  	pf.setOutline(true);
  	pf.setDefaultSubtotal(true);
   }
   org.openxmlformats.schemas.spreadsheetml.x2006.main.CTPivotFilters filters =
    org.openxmlformats.schemas.spreadsheetml.x2006.main.CTPivotFilters.Factory.newInstance();
   org.openxmlformats.schemas.spreadsheetml.x2006.main.CTPivotFilter field = filters.addNewFilter();
   field.setId(0);
   field.setFld(1);
   field.setType(org.openxmlformats.schemas.spreadsheetml.x2006.main.STPivotFilterType.VALUE_BETWEEN);
   field.setIMeasureFld(0);
    CTFilterColumn myCol = field.addNewAutoFilter().addNewFilterColumn();
   CTCustomFilters myFilter2= myCol.addNewCustomFilters();
   CTCustomFilter custFilt = myFilter2.addNewCustomFilter();
   CTCustomFilter custFilt2 = myFilter2.addNewCustomFilter();
   custFilt.setOperator(STFilterOperator.GREATER_THAN_OR_EQUAL);
   custFilt.setVal("2");
   custFilt2.setOperator(STFilterOperator.LESS_THAN_OR_EQUAL);
   custFilt2.setVal("5");
   field.getAutoFilter().setRef("A1");
   field.getAutoFilter().getFilterColumnArray(0).setColId(0);
    pivotTable.getCTPivotTableDefinition().setFilters(filters);
   workbook.write(fileout);
  }
 }
}

This is the pivot table that gets printed as a result of running this code:
Apache POI数据透视表 – 如何在Java中使用“介于”值筛选器

If you have any idea on how to help me with this, please let me know!

答案1

得分: 1

以下是翻译好的内容:

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 org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCustomFilter;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCustomFilters;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTDataField;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTFilter;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTFilterColumn;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.STFilterOperator;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTPivotFilters;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTPivotFilter;

import java.util.GregorianCalendar;

class CreatePivotTableFilter {

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

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

   DataFormat format = workbook.createDataFormat();
   CellStyle dateStyle = workbook.createCellStyle();
   dateStyle.setDataFormat(format.getFormat("M/d/yy"));
   Sheet sheet = workbook.createSheet();
   String[] headers = new String[]{"Column1", "Column2", "Date", "IntVal", "Count"};
   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[]{"A", "B1", new GregorianCalendar(2019, 0, 1),  2d},
    new Object[]{"A", "B2", new GregorianCalendar(2019, 0, 1),  4d},
    new Object[]{"B", "B1", new GregorianCalendar(2019, 0, 2),  1d},
    new Object[]{"B", "B2", new GregorianCalendar(2019, 0, 2),  7d},
    new Object[]{"A", "C1", new GregorianCalendar(2019, 0, 1),  5d},
    new Object[]{"A", "C2", new GregorianCalendar(2019, 0, 1),  5d},
    new Object[]{"B", "C1", new GregorianCalendar(2019, 0, 2),  2d},
    new Object[]{"B", "C2", new GregorianCalendar(2019, 0, 2),  8d}
   };
   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 String) {
      cell.setCellValue((String)rowData[c]);
     } else if (rowData[c] instanceof GregorianCalendar) {
      cell.setCellValue((GregorianCalendar)rowData[c]);
      cell.setCellStyle(dateStyle);
     } else if (rowData[c] instanceof Double) {
      cell.setCellValue((Double)rowData[c]);
     }
     else if (rowData[c] instanceof Integer)
         cell.setCellValue((Integer) rowData[c]);
    }
   }

   XSSFPivotTable pivotTable = ((XSSFSheet)sheet).createPivotTable(
    new AreaReference("A1:D9", 
    SpreadsheetVersion.EXCEL2007), 
    new CellReference("F4"));
   pivotTable.addRowLabel(0);
   pivotTable.addRowLabel(1);
   pivotTable.addColLabel(2);
   pivotTable.addColumnLabel(DataConsolidateFunction.SUM, 3);
   pivotTable.addColumnLabel(DataConsolidateFunction.AVERAGE, 3);

   //create filters
   CTPivotFilters filters = CTPivotFilters.Factory.newInstance();

   //set custom value filter
   int filtersCount = 0; // to count filters
   CTPivotFilter filter = filters.addNewFilter();
   filter.setId(0); // filter needs Id
   filter.setFld(1); // filter on column B level
   filter.setType(org.openxmlformats.schemas.spreadsheetml.x2006.main.STPivotFilterType.VALUE_BETWEEN);
   filter.setIMeasureFld(0); //internal measure field is 0 (first data field) = Sum; 1 would be Average
   CTFilterColumn filterColumn = filter.addNewAutoFilter().addNewFilterColumn();
   filterColumn.setColId(0); // filterColumn need colId
   CTCustomFilters customFilters= filterColumn.addNewCustomFilters();
   customFilters.setAnd(true); // following filters are AND linked
   CTCustomFilter customFilter = customFilters.addNewCustomFilter();
   customFilter.setOperator(STFilterOperator.GREATER_THAN_OR_EQUAL);
   customFilter.setVal("2");
   customFilter = customFilters.addNewCustomFilter();
   customFilter.setOperator(STFilterOperator.LESS_THAN_OR_EQUAL);
   customFilter.setVal("5");

   filtersCount++;
   filters.setCount(filtersCount); // set filters count

   pivotTable.getCTPivotTableDefinition().setFilters(filters);

   workbook.write(fileout);
  }

 }
}

注意:由于我只提供纯文本的翻译,代码格式可能在复制粘贴后出现错乱。确保将代码放入适当的集成开发环境(IDE)中,以确保格式正确。

英文:

Well, how to get what needs to be set for the *.xlsx file? The *.xlsx is simply a ZIP archive. So one can unzip the *.xlsx and have a look what is inside it.

So do what you need using Excel's GUI, save the *.xlsx, then unzip it and have a look at /xl/pivotTables/pivotTable1.xml. There you will find the following filter setting:

&lt;filters count=&quot;1&quot;&gt;
&lt;filter fld=&quot;1&quot; type=&quot;valueBetween&quot; evalOrder=&quot;-1&quot; id=&quot;1&quot; iMeasureFld=&quot;0&quot;&gt;
&lt;autoFilter ref=&quot;A1&quot;&gt;
&lt;filterColumn colId=&quot;0&quot;&gt;
&lt;customFilters and=&quot;1&quot;&gt;
&lt;customFilter operator=&quot;greaterThanOrEqual&quot; val=&quot;2&quot;/&gt;
&lt;customFilter operator=&quot;lessThanOrEqual&quot; val=&quot;5&quot;/&gt;
&lt;/customFilters&gt;
&lt;/filterColumn&gt;
&lt;/autoFilter&gt;
&lt;/filter&gt;
&lt;/filters&gt;

So customFilters needs the setting that the following filters are AND linked. This is what your code does not set yet.

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 org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCustomFilter;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCustomFilters;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTDataField;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTFilter;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTFilterColumn;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.STFilterOperator;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTPivotFilters;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTPivotFilter;
import java.util.GregorianCalendar;
class CreatePivotTableFilter {
public static void main(String[] args) throws Exception {
try (Workbook workbook = new XSSFWorkbook(); 
FileOutputStream fileout = new FileOutputStream(&quot;./MyExcelV2.xlsx&quot;) ) {
DataFormat format = workbook.createDataFormat();
CellStyle dateStyle = workbook.createCellStyle();
dateStyle.setDataFormat(format.getFormat(&quot;M\\/d\\/yy&quot;));
Sheet sheet = workbook.createSheet();
String[] headers = new String[]{&quot;Column1&quot;, &quot;Column2&quot;, &quot;Date&quot;, &quot;IntVal&quot;, &quot;Count&quot;};
Row row = sheet.createRow(0);
Cell cell;
for (int c = 0; c &lt; headers.length; c++) {
cell = row.createCell(c); cell.setCellValue(headers[c]);
}
Object[][] data = new Object[][]{
new Object[]{&quot;A&quot;, &quot;B1&quot;, new GregorianCalendar(2019, 0, 1),  2d},
new Object[]{&quot;A&quot;, &quot;B2&quot;, new GregorianCalendar(2019, 0, 1),  4d},
new Object[]{&quot;B&quot;, &quot;B1&quot;, new GregorianCalendar(2019, 0, 2),  1d},
new Object[]{&quot;B&quot;, &quot;B2&quot;, new GregorianCalendar(2019, 0, 2),  7d},
new Object[]{&quot;A&quot;, &quot;C1&quot;, new GregorianCalendar(2019, 0, 1),  5d},
new Object[]{&quot;A&quot;, &quot;C2&quot;, new GregorianCalendar(2019, 0, 1),  5d},
new Object[]{&quot;B&quot;, &quot;C1&quot;, new GregorianCalendar(2019, 0, 2),  2d},
new Object[]{&quot;B&quot;, &quot;C2&quot;, new GregorianCalendar(2019, 0, 2),  8d}
};
for (int r = 0; r &lt; data.length; r++) {
row = sheet.createRow(r+1);
Object[] rowData = data[r];
for (int c = 0; c &lt; rowData.length; c++) {
cell = row.createCell(c);
if (rowData[c] instanceof String) {
cell.setCellValue((String)rowData[c]);
} else if (rowData[c] instanceof GregorianCalendar) {
cell.setCellValue((GregorianCalendar)rowData[c]);
cell.setCellStyle(dateStyle);
} else if (rowData[c] instanceof Double) {
cell.setCellValue((Double)rowData[c]);
}
else if (rowData[c] instanceof Integer)
cell.setCellValue((Integer) rowData[c]);
}
}
XSSFPivotTable pivotTable = ((XSSFSheet)sheet).createPivotTable(
new AreaReference(&quot;A1:D9&quot;, 
SpreadsheetVersion.EXCEL2007), 
new CellReference(&quot;F4&quot;));
pivotTable.addRowLabel(0);
pivotTable.addRowLabel(1);
pivotTable.addColLabel(2);
pivotTable.addColumnLabel(DataConsolidateFunction.SUM, 3);
pivotTable.addColumnLabel(DataConsolidateFunction.AVERAGE, 3);
//create filters
CTPivotFilters filters = CTPivotFilters.Factory.newInstance();
//set custom value filter
int filtersCount = 0; // to count filters
CTPivotFilter filter = filters.addNewFilter();
filter.setId(0); // filter needs Id
filter.setFld(1); // filter on column B level
filter.setType(org.openxmlformats.schemas.spreadsheetml.x2006.main.STPivotFilterType.VALUE_BETWEEN);
filter.setIMeasureFld(0); //internal measure field is 0 (first data field) = Sum; 1 would be Average
CTFilterColumn filterColumn = filter.addNewAutoFilter().addNewFilterColumn();
filterColumn.setColId(0); // filterColumn need colId
CTCustomFilters customFilters= filterColumn.addNewCustomFilters();
customFilters.setAnd(true); // following filters are AND linked
CTCustomFilter customFilter = customFilters.addNewCustomFilter();
customFilter.setOperator(STFilterOperator.GREATER_THAN_OR_EQUAL);
customFilter.setVal(&quot;2&quot;);
customFilter = customFilters.addNewCustomFilter();
customFilter.setOperator(STFilterOperator.LESS_THAN_OR_EQUAL);
customFilter.setVal(&quot;5&quot;);
filtersCount++;
filters.setCount(filtersCount); // set filters count
pivotTable.getCTPivotTableDefinition().setFilters(filters);
workbook.write(fileout);
}
}
}

huangapple
  • 本文由 发表于 2020年9月16日 21:26:05
  • 转载请务必保留本文链接:https://go.coder-hub.com/63921076.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定