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 KD11 kdExcel 枢轴 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);
...

它应该可以工作。