最近,公司运营平台需要上传Excel文件并进行解析导入数据库,在开发完成后出现了一个始料不及的生产bug,下面是具体原因:
1.在用POI解析Excel时,默认如果Excel单元格中没有数据,且单元格Style没有边框,那它就是个null,所以只判断了单元格是不是为null
从而导致如果Excel单元格style如果有边框,且单元格内容为null或空字符,会正常的去解析。具体问题原因我在下面代码段里加上了注释,有.xlsx和.xls两段代码,具体内容大同小异

解决方案:我找了一下API 发现XSSFRow里面可以get到当前单元格的style,那就肯定有对style进行操作的的方法,
XSSFCellStyle cellStyle = xssfRow.getCell(0).getCellStyle();//使用XSSFCellStyle获取到当前行当前单元格的样式

然后对style进行一下操作
cellStyle.setBorderTop(BorderStyle.NONE);//将上方单元格边框样式去除
cellStyle.setBorderBottom(BorderStyle.NONE);//将下方单元格边框样式去除
cellStyle.setBorderLeft(BorderStyle.NONE);//将左方单元格边框样式去除
cellStyle.setBorderRight(BorderStyle.NONE);//将右方单元格边框样式去除
这样也就解决了边框的问题
以防万一,我也进行了一些if判断

有人说,你这样有些多余,直接判断下面装载参数的map是不是为空不久行了。每个人解决方法的思路不同,很正常,遇到这个问题总想研究一下。
我也只是遇到问题而想办法解决一下问题,也是一种提升,代码是我临时写的一个小demo,有些地方比较乱,勿喷。

代码段:

 public static List<Map<String,Object>> readXls(InputStream is) throws IOException{
HSSFWorkbook hssfWorkbook = new HSSFWorkbook(is);
List<Map<String,Object>> readMap = new ArrayList<>();
// Read the Sheet
for (int numSheet = 0; numSheet < hssfWorkbook.getNumberOfSheets(); numSheet++) {
HSSFSheet hssfSheet = hssfWorkbook.getSheetAt(numSheet);
if (hssfSheet == null) {
continue;
}
// Read the Row
for (int rowNum = 1; rowNum <= hssfSheet.getLastRowNum(); rowNum++) {
HashMap paramMap = new HashMap();
HSSFRow xssfRow = hssfSheet.getRow(rowNum);
if (xssfRow != null) {
if(null!=xssfRow.getCell(0) && xssfRow.getCell(0).getStringCellValue().length()>0 && xssfRow.getCell(0).getStringCellValue().trim().length()>0){
logger.info("============value1==========={}",xssfRow.getCell(0));
HSSFCellStyle cellStyle = xssfRow.getCell(0).getCellStyle();//使用XSSFCellStyle获取到当前行当前单元格的样式
cellStyle.setBorderTop(BorderStyle.NONE);//将上方单元格边框样式去除
cellStyle.setBorderBottom(BorderStyle.NONE);//将下方单元格边框样式去除
cellStyle.setBorderLeft(BorderStyle.NONE);//将左方单元格边框样式去除
cellStyle.setBorderRight(BorderStyle.NONE);//将右方单元格边框样式去除
paramMap.put("value1", getValue(xssfRow.getCell(0)).trim());
}
if(null!=xssfRow.getCell(1) && xssfRow.getCell(1).getStringCellValue().length()>0 && xssfRow.getCell(1).getStringCellValue().trim().length()>0) {
logger.info("============value2==========={}",xssfRow.getCell(1));
HSSFCellStyle cellStyle = xssfRow.getCell(1).getCellStyle();//使用XSSFCellStyle获取到当前行当前单元格的样式
cellStyle.setBorderTop(BorderStyle.NONE);//将上方单元格边框样式去除
cellStyle.setBorderBottom(BorderStyle.NONE);//将下方单元格边框样式去除
cellStyle.setBorderLeft(BorderStyle.NONE);//将左方单元格边框样式去除
cellStyle.setBorderRight(BorderStyle.NONE);//将右方单元格边框样式去除
paramMap.put("value2", getValue(xssfRow.getCell(1)).trim());
}
if(null!=xssfRow.getCell(2) && xssfRow.getCell(2).getStringCellValue().length()>0 && xssfRow.getCell(2).getStringCellValue().trim().length()>0) {
logger.info("============value3==========={}",xssfRow.getCell(2));
HSSFCellStyle cellStyle = xssfRow.getCell(2).getCellStyle();//使用XSSFCellStyle获取到当前行当前单元格的样式
cellStyle.setBorderTop(BorderStyle.NONE);//将上方单元格边框样式去除
cellStyle.setBorderBottom(BorderStyle.NONE);//将下方单元格边框样式去除
cellStyle.setBorderLeft(BorderStyle.NONE);//将左方单元格边框样式去除
cellStyle.setBorderRight(BorderStyle.NONE);//将右方单元格边框样式去除
paramMap.put("value3", getValue(xssfRow.getCell(2)).trim()); }
if(null!=xssfRow.getCell(3) && xssfRow.getCell(3).getStringCellValue().length()>0 && xssfRow.getCell(3).getStringCellValue().trim().length()>0) {
logger.info("============value4==========={}",xssfRow.getCell(3));
HSSFCellStyle cellStyle = xssfRow.getCell(3).getCellStyle();//使用XSSFCellStyle获取到当前行当前单元格的样式
cellStyle.setBorderTop(BorderStyle.NONE);//将上方单元格边框样式去除
cellStyle.setBorderBottom(BorderStyle.NONE);//将下方单元格边框样式去除
cellStyle.setBorderLeft(BorderStyle.NONE);//将左方单元格边框样式去除
cellStyle.setBorderRight(BorderStyle.NONE);//将右方单元格边框样式去除
paramMap.put("value4", getValue(xssfRow.getCell(3)).trim());
}
logger.info("paramMap======{}",paramMap);
if(!paramMap.isEmpty()){
readMap.add(paramMap);
}
}
}
}
if (hssfWorkbook != null) {
hssfWorkbook.close();
}
return readMap;
}
 public static List<Map<String,Object>> readXlsx(InputStream is) throws IOException {
XSSFWorkbook xssfWorkbook = new XSSFWorkbook(is);
ExcelData excelData = null;
List<Map<String,Object>> readMap = new ArrayList<>();
String regex="^[+]?\\d+(\\.\\d+)?$";
// Read the Sheet
for (int numSheet = 0; numSheet < xssfWorkbook.getNumberOfSheets(); numSheet++) {
XSSFSheet xssfSheet = xssfWorkbook.getSheetAt(numSheet);
if (xssfSheet == null) {
continue;
}
// Read the Row
for (int rowNum = 1; rowNum <= xssfSheet.getLastRowNum(); rowNum++) {
HashMap paramMap = new HashMap();
XSSFRow xssfRow = xssfSheet.getRow(rowNum);
if (xssfRow != null) {
excelData = new ExcelData();
if(null!=getValue(xssfRow.getCell(0)) && StringUtils.isNotBlank(xssfRow.getCell(0).toString())){
XSSFCellStyle cellStyle = xssfRow.getCell(0).getCellStyle();//使用XSSFCellStyle获取到当前行当前单元格的样式
cellStyle.setBorderTop(BorderStyle.NONE);//将上方单元格边框样式去除
cellStyle.setBorderBottom(BorderStyle.NONE);//将下方单元格边框样式去除
cellStyle.setBorderLeft(BorderStyle.NONE);//将左方单元格边框样式去除
cellStyle.setBorderRight(BorderStyle.NONE);//将右方单元格边框样式去除
excelData.setCustomerId(getValue(xssfRow.getCell(0)).trim());
paramMap.put("value1",getValue(xssfRow.getCell(0)).trim());//获得单元格内的数据
logger.info("value1======={}",paramMap.get("value1").toString());
}
if(null!=getValue(xssfRow.getCell(1)) && StringUtils.isNotBlank(xssfRow.getCell(1).toString())){
XSSFCellStyle cellStyle = xssfRow.getCell(1).getCellStyle();//使用XSSFCellStyle获取到当前行当前单元格的样式
cellStyle.setBorderTop(BorderStyle.NONE);//将上方单元格边框样式去除
cellStyle.setBorderBottom(BorderStyle.NONE);//将下方单元格边框样式去除
cellStyle.setBorderLeft(BorderStyle.NONE);//将左方单元格边框样式去除
cellStyle.setBorderRight(BorderStyle.NONE);//将右方单元格边框样式去除
excelData.setTemplateName(getValue(xssfRow.getCell(1)).trim());
paramMap.put("value2", getValue(xssfRow.getCell(1)).trim());
logger.info("value2======={}", paramMap.get("value2").toString());
}
if(null!=getValue(xssfRow.getCell(2)) && StringUtils.isNotBlank(xssfRow.getCell(2).toString())){
XSSFCellStyle cellStyle = xssfRow.getCell(2).getCellStyle();//使用XSSFCellStyle获取到当前行当前单元格的样式
cellStyle.setBorderTop(BorderStyle.NONE);//将上方单元格边框样式去除
cellStyle.setBorderBottom(BorderStyle.NONE);//将下方单元格边框样式去除
cellStyle.setBorderLeft(BorderStyle.NONE);//将左方单元格边框样式去除
cellStyle.setBorderRight(BorderStyle.NONE);//将右方单元格边框样式去除
excelData.setTemplateName(getValue(xssfRow.getCell(2)).trim());
paramMap.put("value3", getValue(xssfRow.getCell(2)).trim());
logger.info("value3======={}", paramMap.get("value3").toString());
}
if(null!=getValue(xssfRow.getCell(3)) && StringUtils.isNotBlank(xssfRow.getCell(3).toString())){
XSSFCellStyle cellStyle = xssfRow.getCell(3).getCellStyle();//使用XSSFCellStyle获取到当前行当前单元格的样式
cellStyle.setBorderTop(BorderStyle.NONE);//将上方单元格边框样式去除
cellStyle.setBorderBottom(BorderStyle.NONE);//将下方单元格边框样式去除
cellStyle.setBorderLeft(BorderStyle.NONE);//将左方单元格边框样式去除
cellStyle.setBorderRight(BorderStyle.NONE);//将右方单元格边框样式去除
excelData.setTemplateName(getValue(xssfRow.getCell(3)).trim());
paramMap.put("value4", getValue(xssfRow.getCell(3)).trim());
logger.info("value4======={}", paramMap.get("value4").toString());
}
logger.info("paramMap======={}",paramMap);
if(!paramMap.isEmpty()){ //问题就出在这里,之前new了一个map来存放解析出来的数据,在单元格style带边框的情况下,我也会将空的map给add进readMap中,从而将readMap返回到业务层进行处理的时候和里面数据比对发现对不上,而不带边框的话,我们是不进行解析的也不会把值放进map
readMap.add(paramMap);
}
}
}
}
if (xssfWorkbook != null) {
xssfWorkbook.close();
}
return readMap;
}

POI解析Excel时,如何获取单元格样式以及单元格Style的一些操作的更多相关文章

  1. 使用POI解析Excel时,出现org.xml.sax.SAXParseException: duplicate attribute 'o:relid'的解决办法

    1.使用org.apache.poi解析excle,.xlsx类型文件InputStream is = new FileInputStream(strFileName);XSSFWorkbook wb ...

  2. java读写excel文件( POI解析Excel)

    package com.zhx.base.utils; import org.apache.poi.hssf.usermodel.HSSFWorkbook; import org.apache.poi ...

  3. poi解析Excel内容

    poi可以将指定目录下的Excel中的内容解析.读取到java程序中.下面是一个Demo: 使用poi需要导下包,如下: 首先是准备读取的Excel表,存放在"E:\programming\ ...

  4. 用POI导出excel时,较长的数字不想被自动变为科学计数法的解决方式(转)

    做过很多次导出excel了.都碰到一个问题,内容里如果包含一个比较长的数字,比如订单号“2546541656596”,excel会自动变成科学计数法... 弄过好几次都没有解决,最近又要导出excel ...

  5. poi解析Excel文件版本问题

    poi解析Excel文件时有两种格式: HSSFWorkbook格式用来解析Excel2003(xls)的文件 XSSFWorkbook格式用来解析Excel2007(xlsx)的文件 如果用HSSF ...

  6. C# 解析excel时,字段内有内容,却读取不到的解决方法

    C# 解析excel时,字段内有内容,却读取不到的解决方法:"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + filepath + ...

  7. jxl解析excel时,处理中文乱码问题

    jxl解析excel时,处理中文乱码问题 一般出现较多的问题是,当exce中包含了中文或特殊字符时,在解析时候就会出现乱码现象. 解决方法为: InputStream in = new FileInp ...

  8. poi导出Excel报表多表头双层表头、合并单元格

    效果图: controller层方法: /**     *      * 导出Excel报表     * @param request     * @return     *      */    @ ...

  9. 复杂的POI导出Excel表格(多行表头、合并单元格)

    poi导出excel有两种方式: 第一种:从无到有的创建整个excel,通过HSSFWorkbook,HSSFSheet HSSFCell, 等对象一步一步的创建出工作簿,sheet,和单元格,并添加 ...

随机推荐

  1. 最小生成树——Kruskal与Prim算法

    最小生成树——Kruskal与Prim算法 序: 首先: 啥是最小生成树??? 咳咳... 如图: 在一个有n个点的无向连通图中,选取n-1条边使得这个图变成一棵树.这就叫“生成树”.(如下图) 每个 ...

  2. 英飞凌TC297 PSPR与DSPR

    TC297的系统架构图如下,3个核CPU0/1/2有各自的RAM,分为程序RAM和数据RAM,即PSPR和DSPR.PSPR(或者叫做PRAM)主要用于放置静态函数,提高函数执行效率,或放置flash ...

  3. MySQL必知必会(Create, Alter)

    CREATE DATABASE mysql_crash_course_db; USE mysql_crash_course_db; CREATE TABLE customers ( cust_id i ...

  4. zabbix分布式监控服务 安装与配置

    zabbix安装与配置   一.什么是zabbix及优缺点(对比cacti和nagios) Zabbix能监视各种网络参数,保证服务器系统的安全运营:并提供灵活的通知机制以让系统管理员快速定位/解决存 ...

  5. LightOj-1027 A Dangerous Maze(期望)

    You are in a maze; seeing n doors in front of you in beginning. You can choose any door you like. Th ...

  6. (全国多校重现赛一)E-FFF at Valentine

    At Valentine's eve, Shylock and Lucar were enjoying their time as any other couples. Suddenly, LSH, ...

  7. 视频发布 2019 中国.NET 开发者峰会

    2019 年,注定会是 .NET Core 社区发展的关键一年,诸多重大事件在这一年发生!正如大家所期待的那样,刷新中国 .NET 社区的年度盛会--2019 中国 .NET 开发者峰会(.NET C ...

  8. Orleans[NET Core 3.1] 学习笔记(二)Hello World

    项目结构 开始Orleans之前,我们都知道Orleans主要可以分为俩部分,Host和Client. 所以我们可以创建如下的项目结构: IGrain 一个包含Grain接口的库(.NET Stand ...

  9. centos7制作U盘启动盘

    一.准备相关软件 1.8G以上U盘 2.UltraISO虚拟光驱(试用版即可)最新版 下载地址:https://cn.ultraiso.net/xiazai.html  点击下载试用 3.CentOS ...

  10. Vue ---- 项目与环境搭建 初始项目结构 Vue生命周期

    目录 1. vue环境搭建 2. Vue项目搭建 pycharm配置并启动vue项目 3 . 认识项目 1. vue项目目录结构 2. 配置文件:vue.config.js 3. main.js 4. ...