最近,公司運營平台需要上傳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,有些地方比較亂,勿噴。
代碼段:
1 public static List<Map<String,Object>> readXls(InputStream is) throws IOException{ 2 HSSFWorkbook hssfWorkbook = new HSSFWorkbook(is); 3 List<Map<String,Object>> readMap = new ArrayList<>(); 4 // Read the Sheet 5 for (int numSheet = 0; numSheet < hssfWorkbook.getNumberOfSheets(); numSheet++) { 6 HSSFSheet hssfSheet = hssfWorkbook.getSheetAt(numSheet); 7 if (hssfSheet == null) { 8 continue; 9 } 10 // Read the Row 11 for (int rowNum = 1; rowNum <= hssfSheet.getLastRowNum(); rowNum++) { 12 HashMap paramMap = new HashMap(); 13 HSSFRow xssfRow = hssfSheet.getRow(rowNum); 14 if (xssfRow != null) { 15 if(null!=xssfRow.getCell(0) && xssfRow.getCell(0).getStringCellValue().length()>0 && xssfRow.getCell(0).getStringCellValue().trim().length()>0){ 16 logger.info("============value1==========={}",xssfRow.getCell(0)); 17 HSSFCellStyle cellStyle = xssfRow.getCell(0).getCellStyle();//使用XSSFCellStyle獲取到當前行當前單元格的樣式 18 cellStyle.setBorderTop(BorderStyle.NONE);//將上方單元格邊框樣式去除 19 cellStyle.setBorderBottom(BorderStyle.NONE);//將下方單元格邊框樣式去除 20 cellStyle.setBorderLeft(BorderStyle.NONE);//將左方單元格邊框樣式去除 21 cellStyle.setBorderRight(BorderStyle.NONE);//將右方單元格邊框樣式去除 22 paramMap.put("value1", getValue(xssfRow.getCell(0)).trim()); 23 } 24 if(null!=xssfRow.getCell(1) && xssfRow.getCell(1).getStringCellValue().length()>0 && xssfRow.getCell(1).getStringCellValue().trim().length()>0) { 25 logger.info("============value2==========={}",xssfRow.getCell(1)); 26 HSSFCellStyle cellStyle = xssfRow.getCell(1).getCellStyle();//使用XSSFCellStyle獲取到當前行當前單元格的樣式 27 cellStyle.setBorderTop(BorderStyle.NONE);//將上方單元格邊框樣式去除 28 cellStyle.setBorderBottom(BorderStyle.NONE);//將下方單元格邊框樣式去除 29 cellStyle.setBorderLeft(BorderStyle.NONE);//將左方單元格邊框樣式去除 30 cellStyle.setBorderRight(BorderStyle.NONE);//將右方單元格邊框樣式去除 31 paramMap.put("value2", getValue(xssfRow.getCell(1)).trim()); 32 } 33 if(null!=xssfRow.getCell(2) && xssfRow.getCell(2).getStringCellValue().length()>0 && xssfRow.getCell(2).getStringCellValue().trim().length()>0) { 34 logger.info("============value3==========={}",xssfRow.getCell(2)); 35 HSSFCellStyle cellStyle = xssfRow.getCell(2).getCellStyle();//使用XSSFCellStyle獲取到當前行當前單元格的樣式 36 cellStyle.setBorderTop(BorderStyle.NONE);//將上方單元格邊框樣式去除 37 cellStyle.setBorderBottom(BorderStyle.NONE);//將下方單元格邊框樣式去除 38 cellStyle.setBorderLeft(BorderStyle.NONE);//將左方單元格邊框樣式去除 39 cellStyle.setBorderRight(BorderStyle.NONE);//將右方單元格邊框樣式去除 40 paramMap.put("value3", getValue(xssfRow.getCell(2)).trim()); 41 42 } 43 if(null!=xssfRow.getCell(3) && xssfRow.getCell(3).getStringCellValue().length()>0 && xssfRow.getCell(3).getStringCellValue().trim().length()>0) { 44 logger.info("============value4==========={}",xssfRow.getCell(3)); 45 HSSFCellStyle cellStyle = xssfRow.getCell(3).getCellStyle();//使用XSSFCellStyle獲取到當前行當前單元格的樣式 46 cellStyle.setBorderTop(BorderStyle.NONE);//將上方單元格邊框樣式去除 47 cellStyle.setBorderBottom(BorderStyle.NONE);//將下方單元格邊框樣式去除 48 cellStyle.setBorderLeft(BorderStyle.NONE);//將左方單元格邊框樣式去除 49 cellStyle.setBorderRight(BorderStyle.NONE);//將右方單元格邊框樣式去除 50 paramMap.put("value4", getValue(xssfRow.getCell(3)).trim()); 51 } 52 logger.info("paramMap======{}",paramMap); 53 if(!paramMap.isEmpty()){ 54 readMap.add(paramMap); 55 } 56 } 57 } 58 } 59 if (hssfWorkbook != null) { 60 hssfWorkbook.close(); 61 } 62 return readMap; 63 }
1 public static List<Map<String,Object>> readXlsx(InputStream is) throws IOException { 2 XSSFWorkbook xssfWorkbook = new XSSFWorkbook(is); 3 ExcelData excelData = null; 4 List<Map<String,Object>> readMap = new ArrayList<>(); 5 String regex="^[+]?\\d+(\\.\\d+)?$"; 6 // Read the Sheet 7 for (int numSheet = 0; numSheet < xssfWorkbook.getNumberOfSheets(); numSheet++) { 8 XSSFSheet xssfSheet = xssfWorkbook.getSheetAt(numSheet); 9 if (xssfSheet == null) { 10 continue; 11 } 12 // Read the Row 13 for (int rowNum = 1; rowNum <= xssfSheet.getLastRowNum(); rowNum++) { 14 HashMap paramMap = new HashMap(); 15 XSSFRow xssfRow = xssfSheet.getRow(rowNum); 16 if (xssfRow != null) { 17 excelData = new ExcelData(); 18 if(null!=getValue(xssfRow.getCell(0)) && StringUtils.isNotBlank(xssfRow.getCell(0).toString())){ 19 XSSFCellStyle cellStyle = xssfRow.getCell(0).getCellStyle();//使用XSSFCellStyle獲取到當前行當前單元格的樣式 20 cellStyle.setBorderTop(BorderStyle.NONE);//將上方單元格邊框樣式去除 21 cellStyle.setBorderBottom(BorderStyle.NONE);//將下方單元格邊框樣式去除 22 cellStyle.setBorderLeft(BorderStyle.NONE);//將左方單元格邊框樣式去除 23 cellStyle.setBorderRight(BorderStyle.NONE);//將右方單元格邊框樣式去除 24 excelData.setCustomerId(getValue(xssfRow.getCell(0)).trim()); 25 paramMap.put("value1",getValue(xssfRow.getCell(0)).trim());//獲得單元格內的數據 26 logger.info("value1======={}",paramMap.get("value1").toString()); 27 } 28 if(null!=getValue(xssfRow.getCell(1)) && StringUtils.isNotBlank(xssfRow.getCell(1).toString())){ 29 XSSFCellStyle cellStyle = xssfRow.getCell(1).getCellStyle();//使用XSSFCellStyle獲取到當前行當前單元格的樣式 30 cellStyle.setBorderTop(BorderStyle.NONE);//將上方單元格邊框樣式去除 31 cellStyle.setBorderBottom(BorderStyle.NONE);//將下方單元格邊框樣式去除 32 cellStyle.setBorderLeft(BorderStyle.NONE);//將左方單元格邊框樣式去除 33 cellStyle.setBorderRight(BorderStyle.NONE);//將右方單元格邊框樣式去除 34 excelData.setTemplateName(getValue(xssfRow.getCell(1)).trim()); 35 paramMap.put("value2", getValue(xssfRow.getCell(1)).trim()); 36 logger.info("value2======={}", paramMap.get("value2").toString()); 37 } 38 if(null!=getValue(xssfRow.getCell(2)) && StringUtils.isNotBlank(xssfRow.getCell(2).toString())){ 39 XSSFCellStyle cellStyle = xssfRow.getCell(2).getCellStyle();//使用XSSFCellStyle獲取到當前行當前單元格的樣式 40 cellStyle.setBorderTop(BorderStyle.NONE);//將上方單元格邊框樣式去除 41 cellStyle.setBorderBottom(BorderStyle.NONE);//將下方單元格邊框樣式去除 42 cellStyle.setBorderLeft(BorderStyle.NONE);//將左方單元格邊框樣式去除 43 cellStyle.setBorderRight(BorderStyle.NONE);//將右方單元格邊框樣式去除 44 excelData.setTemplateName(getValue(xssfRow.getCell(2)).trim()); 45 paramMap.put("value3", getValue(xssfRow.getCell(2)).trim()); 46 logger.info("value3======={}", paramMap.get("value3").toString()); 47 } 48 if(null!=getValue(xssfRow.getCell(3)) && StringUtils.isNotBlank(xssfRow.getCell(3).toString())){ 49 XSSFCellStyle cellStyle = xssfRow.getCell(3).getCellStyle();//使用XSSFCellStyle獲取到當前行當前單元格的樣式 50 cellStyle.setBorderTop(BorderStyle.NONE);//將上方單元格邊框樣式去除 51 cellStyle.setBorderBottom(BorderStyle.NONE);//將下方單元格邊框樣式去除 52 cellStyle.setBorderLeft(BorderStyle.NONE);//將左方單元格邊框樣式去除 53 cellStyle.setBorderRight(BorderStyle.NONE);//將右方單元格邊框樣式去除 54 excelData.setTemplateName(getValue(xssfRow.getCell(3)).trim()); 55 paramMap.put("value4", getValue(xssfRow.getCell(3)).trim()); 56 logger.info("value4======={}", paramMap.get("value4").toString()); 57 } 58 logger.info("paramMap======={}",paramMap); 59 if(!paramMap.isEmpty()){ //問題就出在這里,之前new了一個map來存放解析出來的數據,在單元格style帶邊框的情況下,我也會將空的map給add進readMap中,從而將readMap返回到業務層進行處理的時候和里面數據比對發現對不上,而不帶邊框的話,我們是不進行解析的也不會把值放進map 60 readMap.add(paramMap); 61 } 62 } 63 } 64 } 65 if (xssfWorkbook != null) { 66 xssfWorkbook.close(); 67 } 68 return readMap; 69 }