關於Excel檔案上傳到後端問題
最近做一個專案,遇到excel上傳問題,在此記錄下問題以及解決方案。由於開發全棧,前端後端都要寫,前端使用vue+element.ui,沒有使用官方推薦的那一套寫法。而是用了最傳統的方法,程式碼如下: 由於接觸vue不深,可能寫的不太好。下面是後端程式碼,由於客戶需求,excel有三種不同的格式,.xls、.xlsx、.cxv。在網上找了一些資料,使用poj解析.xls和.xlsx,都是這樣寫:
Workbook book = null; try { book = new XSSFWorkbook(excelFile); } catch (Exception ex) { book = new HSSFWorkbook(new FileInputStream(excelFile)); }
但是卻報錯:org.apache.poi.poifs.filesystem.OfficeXmlFileException: The supplied data appears to be in the Office 2007+ XML. You are calling the part of POI that deals with OLE2 Office Documents. You need to call a different part of POI to process this data (eg XSSF instead of HSSF) 然後發現自己用的是poi3.7版本。對於.xls和.xlsx都要用 book = new XSSFWorkbook(excelFile); 才能解析程式碼如下:`@Override public String uploadExcel(String base64, String fileType, String fileName) { String path = “E:\Leezai\agros\agros\WebRoot\doc\knowledge\uploadExcel”; try { BASE64Decoder decoder = new BASE64Decoder();
// 獲取檔案的編碼(不包含檔案型別) String fileStr = base64.substring(base64.indexOf(",") + 1); // 得到檔案路徑 fileName = fileName + "." + fileType; path = path + "/" + fileName; // 將編碼轉換並且輸出到檔案中 byte[] b = decoder.decodeBuffer(fileStr); for (int i = 0; i < b.length; i++) { if (b[i] < 0) { b[i] += 256; } } OutputStream os = new FileOutputStream(path); os.write(b); os.flush(); os.close(); } catch (IOException e) { e.printStackTrace(); } return path; } // 匯入excel資料到資料庫1,將excel資料儲存到map public List<Map<String, String>> excelToList(String path, String fileType) { boolean flag = true; List<Map<String, String>> list = new ArrayList<>(); if (fileType.equals("xls") || fileType.equals("xlsx")) { list = getListOfXlsx(path); } else if (fileType.equals("csv")) { list = getListOfCsv(path); } return list; } private List<Map<String, String>> getListOfXlsx(String path) { Workbook wb = null; Sheet sheet = null; List<Map<String, String>> list = new ArrayList<>(); Row row = null; InputStream is = null; String columns[] = {"cropname", "periodname", "climatename", "effect", "advise"}; try { is = new FileInputStream(path); wb = new XSSFWorkbook(is); sheet = wb.getSheetAt(0); // 獲取最大行數 int rownum = sheet.getPhysicalNumberOfRows(); // 獲取第一行 row = sheet.getRow(0); // 獲取最大列數 int colnum = row.getPhysicalNumberOfCells(); String cellData = null; for (int i = 1; i < rownum; i++) { Map<String, String> map = new LinkedHashMap<>(); row = sheet.getRow(i); if (row != null) { for (int j = 0; j < colnum; j++) { if (row.getCell(j) != null && row.getCell(j).getStringCellValue() != null) { cellData = row.getCell(j).getStringCellValue(); map.put(columns[j], cellData); } else { map.put(columns[j], "無"); } } } else { break; } list.add(map); } } catch (Exception e) { e.printStackTrace(); } return list; }
` 這樣就可以了