Apache poi 不允许空值创建数据透视表
Apache poi not allowing blank values for pivot creation
我正在尝试使用 apache poi 为正常值创建一个枢轴 table 它工作正常,但如果存在空值或空白值,xlsx 文件将被修复并且枢轴在打开时被删除。
这是我的代码:
static void addRowLabel(XSSFPivotTable pivotTable, XSSFSheet dataSheet, AreaReference areaReference, int column) {
DataFormatter formatter = new DataFormatter(java.util.Locale.US);
//apache poi creates as much fields for each as rows are in the pivot table data range
pivotTable.addRowLabel(column);
java.util.TreeSet<String> uniqueItems = new java.util.TreeSet<String>();
for (int r = areaReference.getFirstCell().getRow()+1; r < areaReference.getLastCell().getRow()+1; r++) {
if (dataSheet.getRow(r).getCell(column) != null && dataSheet.getRow(r).getCell(column).getCellType() != CellType.BLANK) {
uniqueItems.add(formatter.formatCellValue(dataSheet.getRow(r).getCell(column)));
} else {
uniqueItems.add("");
}
}
CTPivotField ctPivotField = pivotTable.getCTPivotTableDefinition().getPivotFields().getPivotFieldArray(column);
int i = 0;
for (String item : uniqueItems) {
//take the items as numbered items
ctPivotField.getItems().getItemArray(i).unsetT();
ctPivotField.getItems().getItemArray(i).setX((long)i);
//build a cache definition which has shared elements for those items
pivotTable.getPivotCacheDefinition().getCTPivotCacheDefinition().getCacheFields().getCacheFieldArray(column).getSharedItems().addNewS().setV(item);
i++;
}
//set pivot field settings
ctPivotField.setOutline(false); // no outline format
ctPivotField.setDefaultSubtotal(false); // no subtotals for this field
if (ctPivotField.getDefaultSubtotal()) i++;
for (int k = ctPivotField.getItems().getItemList().size()-1; k >= i; k--) {
ctPivotField.getItems().removeItem(k);
}
ctPivotField.getItems().setCount(i);
}
该方法用于添加行,下面代码开始执行:
public static void secondway( ) throws IOException {
try (XSSFWorkbook workbook = new XSSFWorkbook(new FileInputStream("/opt/source.xlsx"));
FileOutputStream fileout = new FileOutputStream("/opt/ExcelResult.xlsx") ) {
XSSFSheet dataSheet = workbook.getSheetAt(0);
XSSFSheet pivotSheet = workbook.createSheet("Pivot");
int firstRow = dataSheet.getFirstRowNum();
int lastRow = dataSheet.getLastRowNum();
int firstCol = dataSheet.getRow(0).getFirstCellNum();
int lastCol = dataSheet.getRow(0).getLastCellNum();
CellReference topLeft = new CellReference(firstRow, firstCol);
CellReference botRight = new CellReference(lastRow, lastCol - 1);
AreaReference areaReference = new AreaReference(topLeft,botRight, SpreadsheetVersion.EXCEL2007);
XSSFPivotTable pivotTable = pivotSheet.createPivotTable(areaReference, new CellReference("A1"), dataSheet);
addRowLabel(pivotTable, dataSheet, areaReference, 0);
addRowLabel(pivotTable, dataSheet, areaReference, 2);
pivotTable.addColumnLabel(DataConsolidateFunction.SUM, 1, "test");
workbook.write(fileout);
}
}
我不确定我做错了什么或如何支持空白值。请帮忙。
我正在使用的输入:
打开时显示以下错误并删除了 piivot:
[![在此处输入图片描述][3]][3]
addRowLabel
方法的目的,似乎来自我的回答 java: How to create a pivot with apache poi?,是为了更正 apache poi
,它为每个数据透视字段创建与行一样多的项目在 pivot table 数据范围内。但它应该与数据透视字段数据列中的唯一项一样多。
为了获得每列的唯一项目,使用了 java.util.TreeSet
,因为它不能包含重复的元素。
但是 Excel
pivot table 不区分大小写。因此 11 KD
和 11 kd
是 Excel
枢轴 table 的相同值。这就是为什么在创建 java.util.TreeSet
.
时需要将 String.CASE_INSENSITIVE_ORDER
用作 Comparator
做改变:
...
java.util.TreeSet<String> uniqueItems = new java.util.TreeSet<String>();
...
进入
...
java.util.TreeSet<String> uniqueItems = new java.util.TreeSet<String>(String.CASE_INSENSITIVE_ORDER);
...
它应该可以工作。
我正在尝试使用 apache poi 为正常值创建一个枢轴 table 它工作正常,但如果存在空值或空白值,xlsx 文件将被修复并且枢轴在打开时被删除。
这是我的代码:
static void addRowLabel(XSSFPivotTable pivotTable, XSSFSheet dataSheet, AreaReference areaReference, int column) {
DataFormatter formatter = new DataFormatter(java.util.Locale.US);
//apache poi creates as much fields for each as rows are in the pivot table data range
pivotTable.addRowLabel(column);
java.util.TreeSet<String> uniqueItems = new java.util.TreeSet<String>();
for (int r = areaReference.getFirstCell().getRow()+1; r < areaReference.getLastCell().getRow()+1; r++) {
if (dataSheet.getRow(r).getCell(column) != null && dataSheet.getRow(r).getCell(column).getCellType() != CellType.BLANK) {
uniqueItems.add(formatter.formatCellValue(dataSheet.getRow(r).getCell(column)));
} else {
uniqueItems.add("");
}
}
CTPivotField ctPivotField = pivotTable.getCTPivotTableDefinition().getPivotFields().getPivotFieldArray(column);
int i = 0;
for (String item : uniqueItems) {
//take the items as numbered items
ctPivotField.getItems().getItemArray(i).unsetT();
ctPivotField.getItems().getItemArray(i).setX((long)i);
//build a cache definition which has shared elements for those items
pivotTable.getPivotCacheDefinition().getCTPivotCacheDefinition().getCacheFields().getCacheFieldArray(column).getSharedItems().addNewS().setV(item);
i++;
}
//set pivot field settings
ctPivotField.setOutline(false); // no outline format
ctPivotField.setDefaultSubtotal(false); // no subtotals for this field
if (ctPivotField.getDefaultSubtotal()) i++;
for (int k = ctPivotField.getItems().getItemList().size()-1; k >= i; k--) {
ctPivotField.getItems().removeItem(k);
}
ctPivotField.getItems().setCount(i);
}
该方法用于添加行,下面代码开始执行:
public static void secondway( ) throws IOException {
try (XSSFWorkbook workbook = new XSSFWorkbook(new FileInputStream("/opt/source.xlsx"));
FileOutputStream fileout = new FileOutputStream("/opt/ExcelResult.xlsx") ) {
XSSFSheet dataSheet = workbook.getSheetAt(0);
XSSFSheet pivotSheet = workbook.createSheet("Pivot");
int firstRow = dataSheet.getFirstRowNum();
int lastRow = dataSheet.getLastRowNum();
int firstCol = dataSheet.getRow(0).getFirstCellNum();
int lastCol = dataSheet.getRow(0).getLastCellNum();
CellReference topLeft = new CellReference(firstRow, firstCol);
CellReference botRight = new CellReference(lastRow, lastCol - 1);
AreaReference areaReference = new AreaReference(topLeft,botRight, SpreadsheetVersion.EXCEL2007);
XSSFPivotTable pivotTable = pivotSheet.createPivotTable(areaReference, new CellReference("A1"), dataSheet);
addRowLabel(pivotTable, dataSheet, areaReference, 0);
addRowLabel(pivotTable, dataSheet, areaReference, 2);
pivotTable.addColumnLabel(DataConsolidateFunction.SUM, 1, "test");
workbook.write(fileout);
}
}
我不确定我做错了什么或如何支持空白值。请帮忙。
我正在使用的输入:
打开时显示以下错误并删除了 piivot:
[![在此处输入图片描述][3]][3]
addRowLabel
方法的目的,似乎来自我的回答 java: How to create a pivot with apache poi?,是为了更正 apache poi
,它为每个数据透视字段创建与行一样多的项目在 pivot table 数据范围内。但它应该与数据透视字段数据列中的唯一项一样多。
为了获得每列的唯一项目,使用了 java.util.TreeSet
,因为它不能包含重复的元素。
但是 Excel
pivot table 不区分大小写。因此 11 KD
和 11 kd
是 Excel
枢轴 table 的相同值。这就是为什么在创建 java.util.TreeSet
.
String.CASE_INSENSITIVE_ORDER
用作 Comparator
做改变:
...
java.util.TreeSet<String> uniqueItems = new java.util.TreeSet<String>();
...
进入
...
java.util.TreeSet<String> uniqueItems = new java.util.TreeSet<String>(String.CASE_INSENSITIVE_ORDER);
...
它应该可以工作。