最近,公司運營平臺需要上傳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 }