我有一个数据透视表,其中包含列标签"总销售额"和"个人销售"。我想在数据透视表中添加一个新列来计算销售百分比(个人销售额/总销售额* 100)。我在将此新计算列添加到数据透视表时遇到问题。
我认为我的问题在于以下代码行。
ctCacheField.setFormula("'Individual Sales'/'Total Sales' * 100") in
addFormulaToCache method.
注意:上述行中的单个销售额和总销售额是我在数据透视表中的列名。
这是我的完整代码。当我运行此代码时,它会生成Excel。但是当我打开Excel时,我收到错误,我没有看到数据透视表。
AreaReference a=new AreaReference("Data!A1:C6");
/* Define the starting Cell Reference for the Pivot Table */
CellReference b=new CellReference("A1");
/* Create the Pivot Table */
XSSFPivotTable pivotTable = sheet1.createPivotTable(a,b);
pivotTable.addRowLabel(0);
// 1. Add Formula to cache
addFormulaToCache(pivotTable);
// 2. Add PivotField for Formula column
addPivotFieldForNewColumn(pivotTable);
// 3. Add all column labels before our function..
pivotTable.addColumnLabel(DataConsolidateFunction.COUNT, 2, "Total Sales");
pivotTable.addColumnLabel(DataConsolidateFunction.SUM, 1, "Individual Sales");
addFormulaColumn(pivotTable);
/* Write output to file */
FileOutputStream output_file = new FileOutputStream(new File("C:\\POI_XLS_Pivot_Example.xlsx")); //create XLSX file
new_workbook.write(output_file);//write excel document to output stream
output_file.close(); //close the file
}
private static void addFormulaToCache(XSSFPivotTable pivotTable) {
CTCacheFields ctCacheFields = pivotTable.getPivotCacheDefinition().getCTPivotCacheDefinition().getCacheFields();
CTCacheField ctCacheField = ctCacheFields.addNewCacheField();
ctCacheField.setName("Field1"); // Any field name
**ctCacheField.setFormula("'Individual Sales'/'Total Sales' * 100");** //This is where the problem could be
ctCacheField.setDatabaseField(false);
ctCacheField.setNumFmtId(0);
ctCacheFields.setCount(ctCacheFields.sizeOfCacheFieldArray()); //!!! update count of fields directly
}
private static void addPivotFieldForNewColumn(XSSFPivotTable pivotTable) {
CTPivotField pivotField = pivotTable.getCTPivotTableDefinition().getPivotFields().addNewPivotField();
pivotField.setDataField(true);
pivotField.setDragToCol(false);
pivotField.setDragToPage(false);
pivotField.setDragToRow(false);
pivotField.setShowAll(false);
pivotField.setDefaultSubtotal(false);
}
private static void addFormulaColumn(XSSFPivotTable pivotTable) {
CTDataFields dataFields;
if(pivotTable.getCTPivotTableDefinition().getDataFields() != null) {
dataFields = pivotTable.getCTPivotTableDefinition().getDataFields();
} else {
// can be null if we have not added any column labels yet
dataFields = pivotTable.getCTPivotTableDefinition().addNewDataFields();
}
CTDataField dataField = dataFields.addNewDataField();
dataField.setName("%age Group Difference");
// set index of cached field with formula - it is the last one!!!
dataField.setFld(pivotTable.getPivotCacheDefinition().getCTPivotCacheDefinition().getCacheFields().getCount()-1);
dataField.setBaseItem(0);
dataField.setBaseField(0);
}
答案 0 :(得分:0)
此问题是另一个问题的后续问题:XSSF (POI) - Adding “formula” column to pivot table
您问题的缺失部分是“个人销售”和“总销售额”是数据透视表中的虚拟列名。假设您的来源是:
Fruit | Price
Apple | 1.5
Orange | 1
获得Price * 2的公式自然会是“'Price'* 2”,无论数据透视表中的名称如何。如果您真的希望参考虚构的名称,您的公式会变得更加复杂。对于单元格A1中的数据透视表,对“个人销售”的引用将为:
GETPIVOTDATA("Individual Sales",$A$1,<Filter Name>,<Filter Value>)
但这违背了数据透视表的目的。 作为一个额外的注释,如果你愿意,所有三个valerii ryzhuk的答案都可以放在一个单一的功能中。除了解释答案外,它们不需要拆分。