为了账号安全,请及时绑定邮箱和手机立即绑定

我在通过 Apache POI 添加计算字段时遇到问题

我在通过 Apache POI 添加计算字段时遇到问题

梦里花落0921 2023-10-13 09:44:48
我正在尝试通过 Apache POI 添加计算字段,当只有一个非计算字段而其余其他字段是计算字段时,我遇到问题 我在打开 excel 工作表时遇到错误,如下所示错误图像但是,当有多个非计算字段时,Excel 工作表不会抛出任何错误,并且计算字段显示正常。添加一个或多个列标签时没有错误。有人可以帮我解决这个问题吗?实际产量预期输出只有一个非计算列和一个计算列,如下所示。预期产出
查看完整描述

1 回答

?
UYOU

TA贡献1878条经验 获得超4个赞

数据透视表定义中有一个元素,如果有多个数据字段作为列字段,colFields则至少需要一个元素。field但apache poi如果仅设置一个列标签,则不会添加该字段,因为如果仅存在一个列字段,则不需要该字段。


但由于您低级别添加了一个数据字段作为列字段,因此它缺少该 colFields字段。这就是为什么在打开文件时出错的原因Excel。


如果设置了多个列标签,则apache poi添加该colFields字段。这就是它起作用的原因。


因此,在低级别创建数据字段后,将以下内容添加到您的代码中:


...

   // 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);

   }

...

这将添加一个新colFields元素(如果尚不存在)。它会field在那里添加该元素(如果尚未存在)。


再次完整的例子:


import java.io.FileOutputStream;


import org.apache.poi.ss.SpreadsheetVersion;

import org.apache.poi.ss.usermodel.*;

import org.apache.poi.ss.util.*;

import org.apache.poi.xssf.usermodel.*;

import org.openxmlformats.schemas.spreadsheetml.x2006.main.*;


class CreatePivotTableCalculatedFields {


 public static void main(String[] args) throws Exception {

  createPivotTable();

 }


 private static void createPivotTable() throws Exception {

  try (XSSFWorkbook wb = new XSSFWorkbook(); 

       FileOutputStream fileOut = new FileOutputStream("Output.xlsx")) {


   XSSFSheet dataSheet = wb.createSheet("1econtent");

   XSSFSheet pivotSheet = wb.createSheet("1e");


   setCellData(dataSheet, wb);


   AreaReference source = new AreaReference("A1:F5", SpreadsheetVersion.EXCEL2007);

   CellReference position = new CellReference(0,0);


   XSSFPivotTable pivotTable = pivotSheet.createPivotTable(source, position,wb.getSheet("1econtent"));

   pivotTable.addRowLabel(2);

   pivotTable.addRowLabel(0);


   pivotTable.addColumnLabel(DataConsolidateFunction.SUM, 3);


   pivotSheet.setDisplayGridlines(false);


   wb.setSelectedTab(1);

   wb.setActiveSheet(1);


   // customize pivot table

   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);


   // 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);

   }


   wb.write(fileOut);

  }

 }


 public static void setCellData(XSSFSheet sheet, XSSFWorkbook wb){

  Object[][] data = new Object[][] {

   new Object[] {"Names", "Age", "Dept", "Salary", "Actuals", "Estimates"},

   new Object[] {"Adam", 22d, "Sales", 10d, 12d, 60d},

   new Object[] {"Bran", 24d, "Finance", 20d, 24d, 60d},

   new Object[] {"Jane", 23d, "IT", 30d, 30d, 60d},

   new Object[] {"Dave", 30d, "Sales", 50d, 6d, 60d}

  };


  XSSFRow row;

  XSSFCell cell;

  for (int r = 0; r < data.length; r++) {

   row = sheet.createRow(r);

   for (int c = 0 ; c < data[r].length; c++) {

    cell = row.createCell(c);

    if (data[r][c] instanceof String) {

     cell.setCellValue((String)data[r][c]);

    } else if (data[r][c] instanceof Double) {

     cell.setCellValue((Double)data[r][c]);

    }

   }

  }

 } 

}



查看完整回答
反对 回复 2023-10-13
  • 1 回答
  • 0 关注
  • 95 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信