如何覆盖 PrimeFaces p:dataExporter 错误地将数字导出为 Excel 中的文本?

How to override PrimeFaces p:dataExporter wrongly exporting numbers as text in Excel?

PrimeFace p:dataExporter tag exports numeric data as text by default, which results in a cell with a green triangle in the upper left corner. This can be seen in the PrimeFaces showcase example 也一样,如果您单击 Excel 汽车下的出口 table。

如何覆盖此默认值以确保我的数字列不会导出为文本?我尝试使用 postProcessor 属性指向我的方法,该方法使用 POI API 为所有数据单元格设置 Excel 格式,但没有生效(没有改变任何东西):

public void formatExcel(Object doc) {
    HSSFWorkbook book = (HSSFWorkbook)doc;
    HSSFSheet sheet = book.getSheetAt(0); 

    HSSFRow header = sheet.getRow(0);
    int colCount = header.getPhysicalNumberOfCells();
    int rowCount = sheet.getPhysicalNumberOfRows();

    HSSFCellStyle numStyle = book.createCellStyle();
    numStyle.setDataFormat((short)1);

    for(int rowInd = 1; rowInd < rowCount; rowInd++) {
        HSSFRow row = sheet.getRow(rowInd);
        for(int cellInd = 1; cellInd < colCount; cellInd++) {
            HSSFCell cell = row.getCell(cellInd);
            String val = cell.getStringCellValue();

            cell.setCellStyle(numStyle);

        }
    }
}

我也试过了

cell.setCellType(HSSFCell.CELL_TYPE_NUMERIC);

但这给了我

java.lang.IllegalStateException: Cannot get a numeric value from a text cell

这意味着所有数据都被不加区别地导出为文本,之后您甚至无法更改它。

在您的后处理器中,您没有将单元格的值设置为整数。您设置类型,但不设置值。设置类型是不够的。您必须将值转换为数字并重新设置

这就是最终对我有用的东西。它远非优雅但有效:

HSSFCellStyle intStyle = book.createCellStyle();
intStyle.setDataFormat((short)1);

HSSFCellStyle decStyle = book.createCellStyle();
decStyle.setDataFormat((short)2);

HSSFCellStyle dollarStyle = book.createCellStyle();
dollarStyle.setDataFormat((short)5);


for(int rowInd = 1; rowInd < rowCount; rowInd++) {
    HSSFRow row = sheet.getRow(rowInd);
    for(int cellInd = 1; cellInd < colCount; cellInd++) {
        HSSFCell cell = row.getCell(cellInd);

        //This is sortof a hack to counter PF exporting all data as text
        //We capture the existing value as string, convert to int, 
        //then format the cell to be numeric and reset the value to be int
        String strVal = cell.getStringCellValue();

        //this has to be done to temporarily blank out the cell value
        //because setting the type to numeric directly will cause 
        //an IllegalStateException because POI stupidly thinks
        //the cell is text because it was exported as such by PF...
        cell.setCellType(HSSFCell.CELL_TYPE_BLANK);
        cell.setCellType(HSSFCell.CELL_TYPE_NUMERIC);

        strVal = strVal.replace(",", StringUtils.EMPTY);

        if(strVal.indexOf('.') == -1) {
            //integer
            //numStyle.setDataFormat((short)1);
            int intVal = Integer.valueOf(strVal);

            cell.setCellStyle(intStyle);
            cell.setCellValue(intVal);
        } else {
            //double
            if(strVal.startsWith("$")) {
                strVal = strVal.replace("$", StringUtils.EMPTY);
                //numStyle.setDataFormat((short)5);
                cell.setCellStyle(dollarStyle);
            } else {
                //numStyle.setDataFormat((short)2);
                cell.setCellStyle(decStyle);
            }

            double dblVal = Double.valueOf(strVal);
            cell.setCellValue(dblVal);
        }
    }
}