说明:poi利用模板导出 excel,关于公式计算的问题,写的有点乱,不过自认为,把me运用excel公式遇到的问题都写的差不多了
- 在导出excel的时候,要想 公式进行自动计算
1.1 首先,进行填写的excel数据列cell 的格式,一定是 数值型的,
不能是 文本格式,如果是 文本格式,不能进行公式计算。
1.11 对于 设置 数值格式,有两种方式:
1.111 第一种方式: 在excel导出 模板里面进行设置,如下,选中特定(一个或者区域)下的单元格,
点击右键,选中【设置单元格格式】,然后,选择【数值】-->在这里,还可以设置小数各位或者整数
1.112 在java代码里,进行设置 导出列的 单元格格式,如下
列子是设置的 数值型的整数(double),
利用公式计算,后面会讲 ,这里就不写了。
/**设置内容为 数值型 文本格式 * @param row 行数 * @param column 每行的第几个单元格 * @param style 每格单元格的样式,如字体,大小,边框... * @param cellValue 给单元格填充的 值 */ private void setCellContext(HSSFRow row, int column, CellStyle style, String cellValue) { HSSFCell cell = row.createCell(column); style.setDataFormat(HSSFDataFormat.getBuiltinFormat("#,#0"));//数据格式只显示整数 // 设置单元格格式 cell.setCellStyle(style); if(cellValue.indexOf("SUM") != -1){ cell.setCellType(CellType.FORMULA);//设置为公式 cell.setCellFormula(cellValue); }else{ // 设置单元格内容为double类型 cell.setCellValue(Double.parseDouble(cellValue)); } }
1.2 excel 利用公式导出
公式分为两种,一种是在 excel 模板里面进行写的公式,一种是java代码拼接的公式
1.21 java代码拼接的公式
1.211 给拼接的公式的单元格设置 单元格格式为【公式】
如 n行的第几列,固定的列,要进行 小计,或者合计类的,写的是 公式,就一定要 设置单元格格式为公式格式,
设置为公式,上面的代码有写 setCellContext()方法
否则,如不设置公式格式,现在java里面写计算sum求和的公式,因前面列都是数值型的,
执行 cell.setCellValue(Double.parseDouble(cellValue)); 这个代码,会报错,
因为你的sum求和公式 是字符型的,且不是存数字的字符型,是带有sum的字符型公式
或者,这时,你会说,那我列输出的时候,直接 给列 设置成【文本】进行输出,就不会报错了,
设置成【文本】代码,如下:
/** * @param row 行数 * @param column 每行的第几列 * @param style 每个单元格的样式,如字体,大小。。 * @param cellValue 填充单元格的值(就是导出的值) */ private void setCell(HSSFRow row, int column, CellStyle style, String cellValue) { HSSFCell cell = row.createCell(column); cell.setCellStyle(style); if (StringUtils.isBlank(cellValue)) cellValue = ""; // 去掉两端空格 cellValue = StringUtils.trim(cellValue); cell.setCellValue(cellValue); }
那么,我会告诉你,这个时候,会出现的问题
设置成 【文本】后,在你导出的excel文件里面,你看到的就直接是公式,而不是利用公式 直接计算出来的值,
这个时候,需要双击这个带有公式的单元格,才会进行计算,既不美观,也不符合需求吧,
所以,要把带有公式的单元格设置成公式
1.212 拼接的公式的单元格设置为【公式】,还会出现一个不太美观的东西,就是,没有值的列,对于行的合计来说,会显示0
如果此时,你sql查询出来时,对于没有的数据,你给设置为0 进行返回list的话,是没有问题的,
因,excel里面没值的单元格都是0进行填充,此时的合计,正好也是0;
像我写的这个,就是sql,只查询出来一个字段,别的字段所在的单元格不进行填充,所显示在excel里面的就是空,
此时的合计,对于没值的列,直接展示的是0,这样就不好了,如下图:
要解决这个问题,在你拼接公式的时候,进行过滤,如果值为0 的时候,就直接展示空的字符串"",如下代码:
/** @param rowIn 行数 * @param col 每个行里面的列,及单元格 * @param contextstyle 每个单元格的样式 * @param rowInit 要进行求和的所有行数 */ private void setCellTotalOfKdxz(HSSFRow rowIn, int col, HSSFCellStyle contextstyle, int rowInit){ setCellContext(rowIn, col+1, contextstyle, "IF(SUM(B5:B"+ rowInit + ")=0,\"\",SUM(B5:B"+ rowInit + "))"); setCellContext(rowIn, col+2, contextstyle, "IF(SUM(C5:C"+ rowInit + ")=0,\"\",SUM(C5:C"+ rowInit + "))"); setCellContext(rowIn, col+3, contextstyle, "IF(SUM(D5:D"+ rowInit + ")=0,\"\",SUM(D5:D"+ rowInit + "))"); setCellContext(rowIn, col+4, contextstyle, "IF(SUM(E5:E"+ rowInit + ")=0,\"\",SUM(E5:E"+ rowInit +"))"); }
番外:::
if判断,直接写在excel模板里面怎么进行写
单元格写的公式如下:
=IF(SUM(E5:E6)=0,"",SUM(E5:E6"))
1.22 excel导出模板里面拼接公式
1.221 先在之前要用到的模板里面,写好公式,如下
导出数据集不是固定的,没有那么多导出行数据的时候,这个公式还在那 进行显示着,如上图,会很不好,
所以,解决方案如下:点击公式--》显示公式 【显示公式】按钮变暗就表示操作成功了,如下:
当java读取此模板时,为了防止获取不到原先写入模板的公式,先获取单元格公式,
如下,读取单元格公式(前提是不是提前写入模板的吗,那在哪列下,你也应该清楚,按照excel写入的公式的列,读取公式)
/** 小计-获取公式 * @param rowIn 行数 * @param i 每行的列,及每行的每个单元格 */ private void total(HSSFRow rowIn, int i){ rowIn.getCell(i).setCellFormula(rowIn.getCell(i).getCellFormula()); //小计-系统审核订单 rowIn.getCell(i+4).setCellFormula(rowIn.getCell(i+4).getCellFormula()); //小计-办理成功 rowIn.getCell(i+8).setCellFormula(rowIn.getCell(i+8).getCellFormula()); //小计-办理失败 rowIn.getCell(i+9).setCellFormula(rowIn.getCell(i+9).getCellFormula()); //合计-各小计之和 }
1.3 当公式都写好后,一定要在代码后 加上这句话,只有加上如下的这句代码,
不论是写人模板的公式,还是java后台拼接的公式,才会执行
sheet.setForceFormulaRecalculation(true); // 执行公式
2. 单元格设置格式
//sheet.getRow(i).getCell(j).setCellType(Cell.CELL_TYPE_NUMERIC); 这个方法不能用,否则有异常,且这个方法已过时
用这个方法来设置格式,如下
cell.setCellType(CellType.FORMULA);//设置为列格式为公式
//cell.setCellType(CellType.BOOLEAN);//设置为列格式为布尔
//cell.setCellType(CellType.NUMERIC);//设置为列格式为数值
cell.setCellFormula(cellValue);
| 常量 | 说明 | 取值 |
| Cell.CELL_TYPE_NUMERIC | 数值 | cell.getNumericCellValue() 或cell.getDateCellValue() |
| Cell.CELL_TYPE_STRING | 字符串 | cell.getStringCellValue() 或cell.toString() |
| Cell.CELL_TYPE_BOOLEAN |
布尔 |
cell.getBooleanCellValue() |
| Cell.CELL_TYPE_FORMULA | 表达式 | cell.getCellFormula() |
| Cell.CELL_TYPE_ERROR | 异常 | cell.getErrorCellValue() |
| Cell.CELL_TYPE_BLANK | 空 |
番外::::
当数据为0时,不进行展示,直接展示空,如何给excel设置??
如下,选中要进行限制的区域或者单元格 --> 右键 --> 设置单元格格式 --> 数字 --> 自定义 --> 填写 [=0]"" ---> 点击确认