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

时间:2015-03-17 21:31:37

标签: excel jsf primefaces apache-poi

默认情况下,PrimeFace p:dataExporter标记会将数字数据导出为文本,从而导致左上角出现绿色三角形的单元格。如果单击cars表下的Excel导出,也可以在PrimeFaces showcase example中看到。

如何覆盖此默认值以确保我的数字列不会导出为文本?我尝试使用指向我的方法的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

这意味着所有数据都不加区分地导出为文本,然后您甚至无法在之后进行更改。

2 个答案:

答案 0 :(得分:4)

这最终为我工作。它远非优雅,但它有效:

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

答案 1 :(得分:3)

在postProcessor中,您无法将单元格的值设置为整数。您可以设置类型,但不能设置值。设置类型是不够的。您必须将值转换为数字并重新设置