Apache POI:如何在数据透视表的行标签日期中设置 THIS_YEAR 过滤器
Apache POI: How to set THIS_YEAR filter in row label date of a pivot
我正在尝试使用 apache poi 在 excel 中创建一个枢轴。
我的要求是应用日期过滤器(今年),即在数据透视表的日期行标签中仅显示当前年份日期。
问题: 在生成输出 excel 文件的可重现代码下方,“THIS_YEAR”过滤器应用于日期列,但由于某种原因,它是没有显示任何数据。
下面是生成输出的代码。
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.*;
import java.util.GregorianCalendar;
class CreatePivotTableFilter {
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\/yy"));
Sheet sheet = workbook.createSheet();
String[] headers = new String[]{"Column1", "Column2", "Date", "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(2020, 0, 2), 2d},
new Object[]{"A", "B2", new GregorianCalendar(2020, 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]);
}
}
}
XSSFPivotTable pivotTable = ((XSSFSheet)sheet).createPivotTable(
new AreaReference("A1:D9",
SpreadsheetVersion.EXCEL2007),
new CellReference("F4"));
pivotTable.addRowLabel(0);
pivotTable.addRowLabel(1);
pivotTable.addRowLabel(2);
pivotTable.addColumnLabel(DataConsolidateFunction.SUM, 3);
pivotTable.addColumnLabel(DataConsolidateFunction.AVERAGE, 3);
CTPivotFilters filters = CTPivotFilters.Factory.newInstance();
CTPivotFilter filter = filters.addNewFilter();
filter.setId(0);
filter.setFld(2);
filter.setType(STPivotFilterType.THIS_YEAR);
CTFilterColumn filterColumn = filter.addNewAutoFilter().addNewFilterColumn();
filterColumn.setColId(0);
CTFilters ctFilters = filterColumn.addNewFilters();
ctFilter.addNewFilter().setVal("This Year Filter");
//set filters to pivot table definition
pivotTable.getCTPivotTableDefinition().setFilters(filters);
workbook.write(fileout);
}
}
}
代码生成的输出
预期输出
处理低级别 ooxml-schemas
类 的最佳方法是使用 Excel
的 GUI
创建任何想要的东西,然后解压缩结果 *.xlsx
文件并查看 XML
GUI
创建的内容。
在 xl/pivotTables/pivotTable1.xml
的情况下,我们发现:
...
<filters>
<filter fld="2" type="thisYear" id="0">
<autoFilter>
<filterColumn colId="0">
<dynamicFilter type="thisYear"/>
</filterColumn>
</autoFilter>
</filter>
</filters>
...
所以 filterColumn
不包含 <filters><filter ...>
但包含 dynamicFilter
of type
thisYear
.
因此您的代码必须是:
...
CTPivotFilters filters = CTPivotFilters.Factory.newInstance();
CTPivotFilter filter = filters.addNewFilter();
filter.setId(0);
filter.setFld(2);
filter.setType(STPivotFilterType.THIS_YEAR);
CTFilterColumn filterColumn = filter.addNewAutoFilter().addNewFilterColumn();
filterColumn.setColId(0);
CTDynamicFilter ctDynamicFilter = filterColumn.addNewDynamicFilter();
ctDynamicFilter.setType(STDynamicFilterType.THIS_YEAR);
//set filters to pivot table definition
pivotTable.getCTPivotTableDefinition().setFilters(filters);
...
遗憾的是,ooxml-schemas
public 没有任何 API
文档可用。所以如果我们需要它,我们需要从 maven
下载 ooxml-schemas
源。然后我们可以使用 javadoc
创建一个 API
文档。在那里我们可以找到例如CTFilterColumn
的字段和方法。
我正在尝试使用 apache poi 在 excel 中创建一个枢轴。 我的要求是应用日期过滤器(今年),即在数据透视表的日期行标签中仅显示当前年份日期。
问题: 在生成输出 excel 文件的可重现代码下方,“THIS_YEAR”过滤器应用于日期列,但由于某种原因,它是没有显示任何数据。
下面是生成输出的代码。
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.*;
import java.util.GregorianCalendar;
class CreatePivotTableFilter {
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\/yy"));
Sheet sheet = workbook.createSheet();
String[] headers = new String[]{"Column1", "Column2", "Date", "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(2020, 0, 2), 2d},
new Object[]{"A", "B2", new GregorianCalendar(2020, 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]);
}
}
}
XSSFPivotTable pivotTable = ((XSSFSheet)sheet).createPivotTable(
new AreaReference("A1:D9",
SpreadsheetVersion.EXCEL2007),
new CellReference("F4"));
pivotTable.addRowLabel(0);
pivotTable.addRowLabel(1);
pivotTable.addRowLabel(2);
pivotTable.addColumnLabel(DataConsolidateFunction.SUM, 3);
pivotTable.addColumnLabel(DataConsolidateFunction.AVERAGE, 3);
CTPivotFilters filters = CTPivotFilters.Factory.newInstance();
CTPivotFilter filter = filters.addNewFilter();
filter.setId(0);
filter.setFld(2);
filter.setType(STPivotFilterType.THIS_YEAR);
CTFilterColumn filterColumn = filter.addNewAutoFilter().addNewFilterColumn();
filterColumn.setColId(0);
CTFilters ctFilters = filterColumn.addNewFilters();
ctFilter.addNewFilter().setVal("This Year Filter");
//set filters to pivot table definition
pivotTable.getCTPivotTableDefinition().setFilters(filters);
workbook.write(fileout);
}
}
}
代码生成的输出
预期输出
处理低级别 ooxml-schemas
类 的最佳方法是使用 Excel
的 GUI
创建任何想要的东西,然后解压缩结果 *.xlsx
文件并查看 XML
GUI
创建的内容。
在 xl/pivotTables/pivotTable1.xml
的情况下,我们发现:
...
<filters>
<filter fld="2" type="thisYear" id="0">
<autoFilter>
<filterColumn colId="0">
<dynamicFilter type="thisYear"/>
</filterColumn>
</autoFilter>
</filter>
</filters>
...
所以 filterColumn
不包含 <filters><filter ...>
但包含 dynamicFilter
of type
thisYear
.
因此您的代码必须是:
...
CTPivotFilters filters = CTPivotFilters.Factory.newInstance();
CTPivotFilter filter = filters.addNewFilter();
filter.setId(0);
filter.setFld(2);
filter.setType(STPivotFilterType.THIS_YEAR);
CTFilterColumn filterColumn = filter.addNewAutoFilter().addNewFilterColumn();
filterColumn.setColId(0);
CTDynamicFilter ctDynamicFilter = filterColumn.addNewDynamicFilter();
ctDynamicFilter.setType(STDynamicFilterType.THIS_YEAR);
//set filters to pivot table definition
pivotTable.getCTPivotTableDefinition().setFilters(filters);
...
遗憾的是,ooxml-schemas
public 没有任何 API
文档可用。所以如果我们需要它,我们需要从 maven
下载 ooxml-schemas
源。然后我们可以使用 javadoc
创建一个 API
文档。在那里我们可以找到例如CTFilterColumn
的字段和方法。