中易网

poi操作excel表,怎么将单元格的格式设置为

答案:1  悬赏:60  
解决时间 2021-01-14 20:31
poi操作excel表,怎么将单元格的格式设置为
最佳答案
通过poi导出excel的过程大致是这样的:
     规定单元格的格式
        ↓
      创建单元格
        ↓
     设置单元格的格式
        ↓
     设置数据的格式
        ↓
    把数据存放到单元格中
        ↓
      通过IO流输出

背景POI导出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 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());
}
}
}
}123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051

  如上,有两个比较重要的点:
  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(即把它当成一个“全局”变量),不要在循环内部创建。
  正确的代码如下:

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 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());
}
}
}
}123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051
我要举报
如以上问答内容为低俗、色情、不良、暴力、侵权、涉及违法等信息,可以点下面链接进行举报!
大家都在看
充电器什么牌子最好
玄学上定义的一年是从立春开始,到第二年的立
有哪些附有爱情诗意的网名
迷幻真人密室逃脱地址在哪,我要去那里办事
左边一个单人旁右边一个冬是什么字
高技与大专的区别在哪
游戏中收到系统中奖消息
下列说法正确的是(  )A.击打排球时手感
梅港村地址好找么,我有些事要过去
有关葫芦的小说
淮海路地铁几号线
肇庆市宝庆行汽车销售服务有限公司地址在哪,
动物油脂猪油和鸡油用作饲料油价格高吗?
383是什么意思? 哪位朋友说下、 O(∩_∩)O谢
宝宝长到多高可以不使用床护栏了?
推荐资讯
携来百侣曾游里面的“曾”读什么?
呼气与吸气有什么区别
谁知道98/99AC米兰球员的号码?
枫泾古镇汽车站到嘉善的公交车是几路车?
如果女方有地贫,男方无地贫,那么可以怀孕吗
我从楼上倒尿淋到了人,怎么办
电脑无法刷新,刷新时桌面图标一动不动,怎么
手贱在mac pro上装了win10 当初也不知道安装
极速打码6小时能赚50元吗?
读那么多书还是忘了,那读书有什么意义
请问从太原到扬州最快的,最方便的乘车路线是
请教一下关于PID自整定的三个参数的计算方法
手机登qq时,显示手机磁盘不足,清理后重新登
刺客的套装怎么选啊?