[英]I am facing an issue while adding calculated field through Apache POI
I am trying to add calculated field through Apache POI and I am facing issue when there is only one non-calculated field and rest others are calculated fields I am getting an error while opening excel sheet as below我正在尝试通过 Apache POI 添加计算字段,当只有一个未计算字段并且 rest 其他人是计算字段时我遇到问题我在下面打开 ZBF57C906FA7D2BB66D07372E4158 表时遇到错误
But when there are more than one non-calculated fields excel sheet doesn't throw any error and calculated field displayed fine.但是当有多个非计算字段时 excel 表不会抛出任何错误并且计算字段显示正常。
Here is my code:这是我的代码:
public static void main(String[] args) throws FileNotFoundException, IOException, InvalidFormatException {
createPivotTable();
}
private static void createPivotTable() throws IOException, FileNotFoundException {
try (XSSFWorkbook wb = new XSSFWorkbook()) {
XSSFSheet sheet = wb.createSheet("1econtent");
XSSFSheet sheet1 = wb.createSheet("1e");
sheet1.setDisplayGridlines(false);
setCellData(sheet,wb);
AreaReference source = new AreaReference("A1:F5", SpreadsheetVersion.EXCEL2007);
CellReference position = new CellReference(0,0);
XSSFPivotTable pivotTable = sheet1.createPivotTable(source, position,wb.getSheet("1econtent"));
pivotTable.addRowLabel(2);
pivotTable.addRowLabel(0);
pivotTable.addColumnLabel(DataConsolidateFunction.SUM, 3);
CTCacheFields ctCacheFields = pivotTable.getPivotCacheDefinition().getCTPivotCacheDefinition().getCacheFields();
CTCacheField ctCacheField = ctCacheFields.addNewCacheField();
ctCacheField.setName("Field");
ctCacheField.setFormula("'Actuals' / 'Estimates'");
ctCacheField.setDatabaseField(false);
ctCacheFields.setCount(ctCacheFields.sizeOfCacheFieldArray());
CTPivotField pivotField = pivotTable.getCTPivotTableDefinition().getPivotFields().addNewPivotField();
pivotField.setDataField(true);
pivotField.setDragToCol(false);
pivotField.setDragToPage(false);
pivotField.setDragToRow(false);
pivotField.setShowAll(false);
pivotField.setDefaultSubtotal(false);
CTDataFields dataFields;
if(pivotTable.getCTPivotTableDefinition().getDataFields() != null) {
dataFields = pivotTable.getCTPivotTableDefinition().getDataFields();
} else {
dataFields = pivotTable.getCTPivotTableDefinition().addNewDataFields();
}
CTDataField dataField = dataFields.addNewDataField();
dataField.setName("Calculated Field");
dataField.setFld(pivotTable.getPivotCacheDefinition().getCTPivotCacheDefinition().getCacheFields().getCount()-1);
dataField.setBaseItem(0);
dataField.setBaseField(0);
DataFormat dataformat = pivotTable.getParentSheet().getWorkbook().createDataFormat();
short numFmtId = dataformat.getFormat("0.0%");
dataField.setNumFmtId(numFmtId);
try (FileOutputStream fileOut = new FileOutputStream("Output.xlsx")) {
wb.write(fileOut);
}
}
}
public static void setCellData(XSSFSheet sheet,XSSFWorkbook wb){
Row row1 = sheet.createRow(0);
// Create a cell and put a value in it.
Cell cell11 = row1.createCell(0);
cell11.setCellValue("Names");
Cell cell12 = row1.createCell(1);
cell12.setCellValue("Age");
Cell cell13 = row1.createCell(2);
cell13.setCellValue("Dept");
Cell cell14 = row1.createCell(3);
cell14.setCellValue("Salary");
Cell cell15 = row1.createCell(4);
cell15.setCellValue("Actuals");
Cell cell16 = row1.createCell(5);
cell16.setCellValue("Estimates");
Row row2 = sheet.createRow(1);
Cell cell21 = row2.createCell(0);
cell21.setCellValue("Adam");
Cell cell22 = row2.createCell(1);
cell22.setCellValue(22);
Cell cell23 = row2.createCell(2);
cell23.setCellValue("Sales");
Cell cell24 = row2.createCell(3);
cell24.setCellValue(10);
Cell cell25 = row2.createCell(4);
cell25.setCellValue(12);
Cell cell26 = row2.createCell(5);
cell26.setCellValue(60);
Row row3 = sheet.createRow(2);
Cell cell31 = row3.createCell(0);
cell31.setCellValue("Bran");
Cell cell32 = row3.createCell(1);
cell32.setCellValue(24);
Cell cell33 = row3.createCell(2);
cell33.setCellValue("Finance");
Cell cell34 = row3.createCell(3);
cell34.setCellValue(20);
Cell cell35 = row3.createCell(4);
cell35.setCellValue(24);
Cell cell36 = row3.createCell(5);
cell36.setCellValue(60);
Row row4 = sheet.createRow(3);
Cell cell41 = row4.createCell(0);
cell41.setCellValue("Jane");
Cell cell42 = row4.createCell(1);
cell42.setCellValue(23);
Cell cell43 = row4.createCell(2);
cell43.setCellValue("IT");
Cell cell44 = row4.createCell(3);
cell44.setCellValue(30);
Cell cell45 = row4.createCell(4);
cell45.setCellValue(30);
Cell cell46 = row4.createCell(5);
cell46.setCellValue(60);
Row row5 = sheet.createRow(4);
Cell cell211 = row5.createCell(0);
cell211.setCellValue("Dave");
Cell cell221 = row5.createCell(1);
cell221.setCellValue(30);
Cell cell231 = row5.createCell(2);
cell231.setCellValue("Sales");
Cell cell241 = row5.createCell(3);
cell241.setCellValue(50);
Cell cell251 = row5.createCell(4);
cell251.setCellValue(6);
Cell cell261 = row5.createCell(5);
cell261.setCellValue(60);
}
There is no error when I add one or more column labels.添加一个或多个列标签时没有错误。 Could someone please help me with this.
有人可以帮我解决这个问题。
Expected output is only one non-calculated column and a calculated column as below.预期的 output 只有一个非计算列和一个计算列,如下所示。
There is an element colFields
in pivot table definition which needs at least one field
if there are multiple data fields as column fields. pivot表定义中有一个元素
colFields
,如果有多个数据字段作为列字段,则至少需要一个field
。 But apache poi
does not add that field if only one column label is set because it is not needed if only one column field is present.但是,如果仅设置一列 label,则
apache poi
不会添加该字段,因为如果仅存在一列字段则不需要它。
But since you low level adds a data field as column field it then lacks that colFields
field.但是由于您在低级别添加了一个数据字段作为列字段,因此它缺少该
colFields
字段。 That's why the error while opening the file in Excel
.这就是在
Excel
打开文件时出错的原因。
If multiple column labels are set then apache poi
adds that colFields
field.如果设置了多个列标签,则
apache poi
添加该colFields
字段。 That's why it works then.这就是为什么它起作用的原因。
So add following to your code after your low level creating the data field:因此,在创建数据字段的低级别之后,将以下内容添加到您的代码中:
...
// at least one field in colFields is needed if there are multiple data fields
CTColFields colFields;
if(pivotTable.getCTPivotTableDefinition().getColFields() != null) {
colFields = pivotTable.getCTPivotTableDefinition().getColFields();
} else {
colFields = pivotTable.getCTPivotTableDefinition().addNewColFields();
}
CTField field;
if (colFields.getFieldList().size() == 0) {
field = colFields.addNewField();
field.setX(-2);
}
...
This adds a new colFields
element if not already present.如果尚不存在,这将添加一个新的
colFields
元素。 And it adds that field
element there, if not already present.如果该字段元素尚不存在,它会在那里添加该
field
元素。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.