枢轴中的Apache POI多列标签

时间:2018-07-06 14:16:53

标签: java excel apache-poi pivot-table

我想用apache poi在excel中创建数据透视表。那部分本身工作正常,我得到的桌子就像我想要的那样。现在,我想添加第二个Column Label来进一步细分数据,但是我似乎无法正确添加第二列。

我当前的(有效的)代码只有一栏:

private void createPivotTotalOverview(XSSFSheet sheet) {
    XSSFSheet data = workBook.getSheet("Total Cost Table");

    CellReference c1 = new CellReference(0, 0);
    CellReference c2 = new CellReference(data.getPhysicalNumberOfRows() - 1, data.getRow(0).getLastCellNum() - 1);

    AreaReference ar = new AreaReference(c1, c2);
    CellReference cr = new CellReference(CellAddress.A1.formatAsString());

    XSSFPivotTable pivotTable = sheet.createPivotTable(ar, cr, data);   

    pivotTable.getCTPivotTableDefinition().getPivotFields().getPivotFieldArray(9).setAxis(STAxis.AXIS_COL);
    pivotTable.getCTPivotTableDefinition().getPivotFields().getPivotFieldArray(9).addNewItems();
    pivotTable.getCTPivotTableDefinition().getPivotFields().getPivotFieldArray(9).getItems().addNewItem()
            .setT(STItemType.DEFAULT);

    pivotTable.getCTPivotTableDefinition().addNewColFields().addNewField().setX(9);

    pivotTable.addRowLabel(10);
    pivotTable.addRowLabel(11);
    pivotTable.addRowLabel(2);
    pivotTable.addColumnLabel(DataConsolidateFunction.SUM, 8);
}

我试图添加第二个这样的列:

private void createPivotTotalOverview(XSSFSheet sheet) {
    XSSFSheet data = workBook.getSheet("Total Cost Table");

    CellReference c1 = new CellReference(0, 0);
    CellReference c2 = new CellReference(data.getPhysicalNumberOfRows() - 1, data.getRow(0).getLastCellNum() - 1);

    AreaReference ar = new AreaReference(c1, c2);
    CellReference cr = new CellReference(CellAddress.A1.formatAsString());

    XSSFPivotTable pivotTable = sheet.createPivotTable(ar, cr, data);   

    pivotTable.getCTPivotTableDefinition().getPivotFields().getPivotFieldArray(9).setAxis(STAxis.AXIS_COL);
    pivotTable.getCTPivotTableDefinition().getPivotFields().getPivotFieldArray(9).addNewItems();
    pivotTable.getCTPivotTableDefinition().getPivotFields().getPivotFieldArray(9).getItems().addNewItem()
            .setT(STItemType.DEFAULT);
    pivotTable.getCTPivotTableDefinition().getPivotFields().getPivotFieldArray(12).setAxis(STAxis.AXIS_COL);
    pivotTable.getCTPivotTableDefinition().getPivotFields().getPivotFieldArray(12).addNewItems();
    pivotTable.getCTPivotTableDefinition().getPivotFields().getPivotFieldArray(12).getItems().addNewItem()
            .setT(STItemType.DATA);

    pivotTable.getCTPivotTableDefinition().addNewColFields().addNewField().setX(9);
    pivotTable.getCTPivotTableDefinition().addNewColFields().addNewField().setX(12);
    pivotTable.getCTPivotTableDefinition().getColFields().setCount(2);


    pivotTable.addRowLabel(10);
    pivotTable.addRowLabel(11);
    pivotTable.addRowLabel(2);
    pivotTable.addColumnLabel(DataConsolidateFunction.SUM, 8);
}

但是用第二个代码,当我打开excel时,数据透视表似乎坏了,但是它不再显示该表了。 Excel询问我是否要恢复尽可能多的数据,然后告诉我Removed Part: /xl/pivotTables/pivotTable3.xml part with XML error. (PivotTable view) Load error. Line 2, column 0.

有人可以帮我添加第二列吗?

1 个答案:

答案 0 :(得分:2)

colFields中的xl/pivotTables/pivotTable1.xml元素应该看起来像这样

<colFields count="2">
 <field x="9"/>
 <field x="12"/>
</colFields>

用于多个col字段。但是您的代码添加了两个colFields元素,导致了这一点:

<colFields count="2">
 <field x="9"/>
</colFields>
<colFields>
 <field x="12"/>
</colFields>

这是错误的。

所以不是

---
pivotTable.getCTPivotTableDefinition().addNewColFields().addNewField().setX(9);
pivotTable.getCTPivotTableDefinition().addNewColFields().addNewField().setX(12);
pivotTable.getCTPivotTableDefinition().getColFields().setCount(2);
...

...
pivotTable.getCTPivotTableDefinition().addNewColFields().addNewField().setX(9);
pivotTable.getCTPivotTableDefinition().getColFields().addNewField().setX(12);
pivotTable.getCTPivotTableDefinition().getColFields().setCount(2);
...

并且请不要过度使用Excel的公差。为什么使用.setT(STItemType.DATA)作为第二个col字段的项目类型?为什么不像第一个一样.setT(STItemType.DEFAULT)呢?类型DATA导致Excel 2007崩溃。 Excel 365似乎可以接受这一点。

所以请使用:

pivotTable.getCTPivotTableDefinition().getPivotFields().getPivotFieldArray(12).getItems().addNewItem()
   .setT(STItemType.DEFAULT);

还有顺便说一句:

构造函数AreaReference(CellReference topLeft, CellReference botRight)已过时。改用AreaReference(CellReference topLeft, CellReference botRight, SpreadsheetVersion version)