最近,公司运营平台需要上传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. RAC环境查询JOB正在运行的信息

    需求: 客户环境12.2.0.1,三节点RAC需要,将一个正在运行的Job session kill掉, 但是通过DBA_JOBS_RUNNING发现,无法发现其它实例运行的JOB,因此需要登陆多台实 ...

  2. hibernate查询方式(二)

    1.HQL查询(hibernate query language) 操作的是实体类和属性 *查询所有记录 //1.hql查询操作会使用Query对象 // (1)写sql语句 创建Query对象, S ...

  3. 用Selenium自动化测试时,让ChromeDriver中不显示“正受到自动测试软件控制”

    背景: 在用Selenium做自动化测试的时候,默认ChromeDriver是会提示“Chrom正受到自动测试软件控制”的.如下图这样.但我们有些场景下,不希望这个提示出现.本文探索了几种语言去掉这个 ...

  4. vue 各种打包坑

    1,报错 Refused to load the image 'http://localhost:8080/favicon.ico' because it violates the following ...

  5. iOS库的种类

    一.什么是库? 库是共享程序代码的方式,一般分为静态库和动态库. 二.静态库与动态库的区别? 静态库:链接时完整地拷贝至可执行文件中,被多次使用就有多份冗余拷贝. 动态库:链接时不复制,程序运行时由系 ...

  6. iOS开发之压缩与解压文件

    ziparchive是基于开源代码”MiniZip”的zip压缩与解压的Objective-C 的Class,使用起来非常的简单 方法:从http://code.google.com/p/ziparc ...

  7. 移动开发在路上-- IOS移动开发系列 多线程一

    类似于什么是进程什么是线程在这里我就不多浪费时间了(Google一下什么都有)! 废话不多说先上图,我相信大家都是喜欢看图的人,俗话说得好,求图求真相吗?虽然这里只有屌丝一个但是真相还是会有的... ...

  8. [TimLinux] django 全局变量在WSGI多进程多线程环境中的研究

    场景1: 2个进程,每个进程1个线程,请求函数中设置了10秒sleep,9个请求同一URL: 结果: 1. 全局变量ID值,在每一个进程中相同,不同进程中不相同 2. 并行只能接受2个请求,同时发起多 ...

  9. CoderForces999F-Cards and Joy

    F. Cards and Joy time limit per test 2 seconds memory limit per test 256 megabytes input standard in ...

  10. Python3 常用模块1

    目录 os模块 对文件夹操作 对文件进行操作 sys模块 json 和pickle模块 logging模块 日志等级 longging模块的四大组件 自定义配置 os模块 通过os模块我们可以与操作系 ...