最近做的一个ITFIN的项目中,后台需要用POI实现导出功能,导出的数据中有文本格式,也有货币格式,所以为了方便在将来导出的表格中做计算,存放货币的单元格需要设置为数值类型。

  导出的Excel的单元格都是文本格式(单元格左上角有个小三角):

  费了不少功夫,终于把“小三角”去掉了,这里总结并分享一下问题的解决方法。

  通过poi导出excel的过程大致是这样的:

     规定单元格的格式 
        ↓ 
      创建单元格 
        ↓ 
     设置单元格的格式 
        ↓ 
     设置数据的格式 
        ↓ 
    把数据存放到单元格中 
        ↓ 
      通过IO流输出

背景POI导出Excel时设置单元格类型为数值类型


  要想存放数值的单元格以数值类型导出,其中最关键的步骤就是上面加粗的两步,设置单元格的格式和向单元格中存放数据。

  核心代码如下:

    /*** 导出Excel-胡玉洋-2015年11月11日* *@param outPutParam Excel数据实体,包括要导出的excel标头、列标题、数据等* */private void createContentRows(ExcelParam outPutParam) {HSSFWorkbook workbook=new HSSFWorkbook(); //创建一个Excel文件// 遍历集合数据,产生数据行for (int i = 0; i < outPutParam.getContent().size(); i++) {int rowIndex = i + 2;HSSFRow contentRow = sheet.createRow(rowIndex);Map<String, Object> rowDate = outPutParam.getContent().get(i);//遍历列for (int j = 0; j < outPutParam.getTitleList().size(); j++) {       Title headTitle = outPutParam.getTitleList().get(j);//获取第i行第j列列标题String headerName = headTitle.getName();//获取第j列列标识Object data = rowDate.get(headerName);//获取第i行第j列所放数据HSSFCellStyle contextstyle =workbook.createCellStyle();HSSFCell contentCell = contentRow.createCell(j);                Boolean isNum = false;//data是否为数值型Boolean isInteger=false;//data是否为整数Boolean isPercent=false;//data是否为百分数if (data != null || "".equals(data)) {//判断data是否为数值型isNum = data.toString().matches("^(-?\\d+)(\\.\\d+)?$");//判断data是否为整数(小数部分是否为0)isInteger=data.toString().matches("^[-\\+]?[\\d]*$");//判断data是否为百分数(是否包含“%”)isPercent=data.toString().contains("%");}//如果单元格内容是数值类型,涉及到金钱(金额、本、利),则设置cell的类型为数值型,设置data的类型为数值类型if (isNum && !isPercent) {HSSFDataFormat df = workbook.createDataFormat(); // 此处设置数据格式if (isInteger) {contextstyle.setDataFormat(df.getBuiltinFormat("#,#0"));//数据格式只显示整数}else{contextstyle.setDataFormat(df.getBuiltinFormat("#,##0.00"));//保留两位小数点}                   // 设置单元格格式contentCell.setCellStyle(contextstyle);// 设置单元格内容为double类型contentCell.setCellValue(Double.parseDouble(data.toString()));} else {contentCell.setCellStyle(contextstyle);// 设置单元格内容为字符型contentCell.setCellValue(data.toString());}}}}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51

  如上,有两个比较重要的点: 
  1、先用正则表达式判断数据是否为数值型,如果为数值型,则设置单元格格式为整数或者小数; 
  2、然后往单元格中存放数据的时候要设置数据的格式为double类型,如果查看poi的源码HSSFCell.java会发现设置数据的方法如下,所以用setCellValue(double)方法即可。

   

优化


  到了这里,您可能以为万事大吉啊了,其实上面的代码有个陷阱,如果不经过大数据量的测试是发觉不出来的哦~~

  如果数据量大的话,系统可能会报错“The maximum number of cell styles was exceeded. You can define up to 4000 styles in a .xls workbook”,原因是style创建的次数太多了,解决这个问题的方法很简单,在循环体外面创建单元格格式contextstyle(即把它当成一个“全局”变量),不要在循环内部创建。

  正确的代码如下:

    /*** 导出Excel-胡玉洋-2015年11月11日* *@param outPutParam Excel数据实体,包括要导出的excel标头、列标题、数据等* */private void createContentRows(ExcelParam outPutParam) {HSSFWorkbook workbook=new HSSFWorkbook(); //创建一个Excel文件HSSFCellStyle contextstyle =workbook.createCellStyle();// 遍历集合数据,产生数据行for (int i = 0; i < outPutParam.getContent().size(); i++) {int rowIndex = i + 2;HSSFRow contentRow = sheet.createRow(rowIndex);Map<String, Object> rowDate = outPutParam.getContent().get(i);//遍历列for (int j = 0; j < outPutParam.getTitleList().size(); j++) {       Title headTitle = outPutParam.getTitleList().get(j);//获取第i行第j列列标题String headerName = headTitle.getName();//获取第j列列标识Object data = rowDate.get(headerName);//获取第i行第j列所放数据HSSFCell contentCell = contentRow.createCell(j);                Boolean isNum = false;//data是否为数值型Boolean isInteger=false;//data是否为整数Boolean isPercent=false;//data是否为百分数if (data != null || "".equals(data)) {//判断data是否为数值型isNum = data.toString().matches("^(-?\\d+)(\\.\\d+)?$");//判断data是否为整数(小数部分是否为0)isInteger=data.toString().matches("^[-\\+]?[\\d]*$");//判断data是否为百分数(是否包含“%”)isPercent=data.toString().contains("%");}//如果单元格内容是数值类型,涉及到金钱(金额、本、利),则设置cell的类型为数值型,设置data的类型为数值类型if (isNum && !isPercent) {HSSFDataFormat df = workbook.createDataFormat(); // 此处设置数据格式if (isInteger) {contextstyle.setDataFormat(df.getBuiltinFormat("#,#0"));//数据格式只显示整数}else{contextstyle.setDataFormat(df.getBuiltinFormat("#,##0.00"));//保留两位小数点}                   // 设置单元格格式contentCell.setCellStyle(contextstyle);// 设置单元格内容为double类型contentCell.setCellValue(Double.parseDouble(data.toString()));} else {contentCell.setCellStyle(contextstyle);// 设置单元格内容为字符型contentCell.setCellValue(data.toString());}}}}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51

  最后导出的正确格式:

POI导出Excel时 设置单元格类型为 数值类型 或者文本类型相关推荐

  1. POI导出excel并设置单元格样式和单元格内容中文自适应

    本案例生产环境真是案例POI导出: 开发环境:idea+mybaits3+spring4+springmvc4+maven3+mysql5.7 poi依赖: <dependency>< ...

  2. Java POI 导出Excel,设置单元格无法编辑, 开启工作表保护后,依然可以筛选, 冻结行列不移动

    1. 设置单元格无法编辑 // 单元格样式锁定 不可编辑 CellStyle lockStyle = workbook.createCellStyle(); lockStyle.setLocked(t ...

  3. poi导出Excel时设置某个单元格颜色

    需求: 查询数据库表数据然后到另一个表找错误的对应字段(就是找到需要填充的单元格所在行的列),对这个单元格进行设置背景色,然后导出数据. 具体的工具类如下 import cn.afterturn.ea ...

  4. java poi导出excel,合并单元格

    java导出excel一般都是2种情况,一种是依赖一个实体类进行导出,或者把数据查询出来当成一个视图,对视图进行创建实体:另一种方式就是通过数据还要计算,然后一块统计,那么就不是很好处理了,我采用的是 ...

  5. ruoyi导出excel时合并单元格

    ruoyi版本 3.8.2 首先第一步 增加注解 /*** 合并行* 参数1合并第一个参数为合并基准列,其他列用逗号拼接,依据基准列进行当前单元行合并 参数:如1,7, 8*/ public Stri ...

  6. sheetJs+xlsx-style——前端实现导出excel表格——设置单元格背景色,居中,自动换行,宽度,百分数展示等

    之前写过一篇博客,是关于elementUi-table组件+xlsx插件实现导出--sheetJs的,之前实现的功能有: 根据dom获取内容 创建工作簿 调整单元格的宽度 实现百分数的展示 插入到工作 ...

  7. poi 导出Excel 动态 合并单元格

    public String arrearagePeriodExport(ArrearageParam param) {param.setPageNo(1);param.setPageSize(Inte ...

  8. html导出excel合并单元格,JS导出EXCEL,动态设置单元格格式,合并单元格(横向或纵向)等操作...

    参考链接: https://blog.csdn.net/weixin_33724046/article/details/89611397 https://www.cnblogs.com/lvsk/p/ ...

  9. poi导出Excel(分行单元格颜色设置,字体设置,合并单元格,插入图片)

    这是一个日报导出功能的代码;图片是用JfreeChars生成好的,话不多少 看代码 public String excelExport(HttpServletRequest request,HttpS ...

  10. apache POI导出excel文件 及单元格合并 、样式的设置

    客户需要从完单物料信息中到处excel 大概思路: 单击某一按钮,触发请求至后台,创建输出流,导出excel ^_^ 前台代码: (此段代码 注释部分存在一个问题,注释部分的请求无效,后台无法响应前台 ...

最新文章

  1. 《Adobe InDesign CS6中文版经典教程》—第1课1.8节练习
  2. 减少资源消耗方法之一:减少状态图片
  3. 整体C#与Sql培训内容及结构
  4. python之模块calendar(汇集了日历相关的操作)
  5. 认证android retrofit,Retrofit之项目介绍
  6. ReactNative布局样式总结
  7. java word转pdf linux_Linux平台中使用PHP把word转pdf的实现方法
  8. 羡慕,浙江大学的双 11 快递,全部由物流机器人配送
  9. php项目webpack打包,利用node.js对webpack打包
  10. day03【后台】管理员维护
  11. Xcode9使用新体验
  12. mybatis xml中大于、小于、if else的写法
  13. 页面调用微信扫一扫功能
  14. PDF文件有密码怎么解除?
  15. 群晖3617可以有几个网卡_一步到位,购入群晖920+和它的小伙伴们
  16. 初中理化生实验室仪器配置
  17. 【游戏】金融帝国2:金融帝国实验室(Capitalism Lab)3.0.19安装包下载
  18. 汽车电子控制-汽油机电子控制QA(1)
  19. DIY背景美化生成器微信小程序源码
  20. Debezium系列之:sqlserver数据库开启CDC

热门文章

  1. 对称网络的电路分析方法
  2. 如何用ABP框架快速完成项目 - 自动化测试 - 前端angular e2e protractor
  3. 获取UI控件位置信息
  4. 使用管道--过滤器风格设计软件
  5. 英特尔服务器级cpu型号含义,intel服务器cpu命名规则
  6. t’触发器真值表和状态方程_t触发器(d触发器真值表)
  7. 震惊世界的中国秘方————里面的方子都是一个老中医几十年的心血!!!...
  8. 无人车成功挑战上海路况,连续5小时不接管,谷歌自动驾驶之父看了都打Call...
  9. Android-APP内存优化
  10. 通过制作一个登录界面学习matlab app designer的基础使用方法