有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

excel Apache POI Pivot表如何在Java中使用“中间”值过滤器

我正在尝试使用ApachePOI设计一个透视表,我想做的是首先打印大于某个数字的和值,以及小于某个数字的和值。然而,当我尝试这样做时,过滤器会相互抵消,这意味着打印的和值不应该存在。例如,如果我希望和在2到5之间,和值1以及大于5的数字都会被打印出来。下面是解释我的问题的代码:

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);
  }
 }
}

这是由于运行以下代码而打印的透视表: enter image description here

如果你对如何帮助我有任何想法,请告诉我


共 (1) 个答案

  1. # 1 楼答案

    那么,如何获得需要为*.xlsx文件设置的内容呢?*.xlsx只是一个ZIP存档。所以你可以把*.xlsx解压,看看里面是什么

    所以,使用ExcelGUI来做你需要做的事情,保存*.xlsx,然后解压并查看/xl/pivotTables/pivotTable1.xml。在这里,您可以找到以下过滤器设置:

    <filters count="1">
     <filter fld="1" type="valueBetween" evalOrder="-1" id="1" iMeasureFld="0">
      <autoFilter ref="A1">
       <filterColumn colId="0">
        <customFilters and="1">
         <customFilter operator="greaterThanOrEqual" val="2"/>
         <customFilter operator="lessThanOrEqual" val="5"/>
        </customFilters>
       </filterColumn>
      </autoFilter>
     </filter>
    </filters>
    

    所以customFilters需要设置以下过滤器是AND链接的。这是您的代码尚未设置的内容

    完整示例:

    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);
      }
    
     }
    }