jQuery的Ajax上傳解析Excel表格

需求描述:一個Excel文檔中有三個sheet,需要根據不同的上傳按鈕,解析不同的sheet中的數據,組裝成一個List。數據都爲必填,如有空格或者null的數據直接去除。
一、首先展示HTML的代碼,其中js代碼爲了方便直接放在了html中。

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>文件上傳</title>
</head>
<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
<body>
<form enctype="multipart/form-data">
            <input type="file" name="file" id="file">
            <input name="query" type="button" value="導入excel">
 </form>
</body>
<script type="text/javascript">
    $('input[name="query"]').click(function(){
        var fd = new FormData();
         fd.append("sheetNo", 2); //上傳的參數名 參數值 k-v鍵值對
         fd.append("file", $("#file").get(0).files[0]);//上傳的文件file
         $.ajax({  
              url:"/jiexi",  
              type:"post",  
              data:fd,  
              cache: false,  
              processData: false,  
              contentType: false,  
              success:function(data){ 
                  console.log(data);
                    alert("操作成功!");  
              },  
              error:function(e){  
                  alert("網絡錯誤,請重試!!");  
               }  
              });  
    })

</script>
</html>

二、爲了數據的使用方便,我們根據表頭的長度和傳入的sheet1、sheet2、sheet3來判斷。直接放代碼

    /**
     * 功能描述:解析Excel接口
     * @param file MultipartFile
     * @param sheetNo int
     * @return Object
     * @author:qhyu 
     * @date:2018年8月15日
     */
    @PostMapping(value = "/jiexi")
    public Object jiexi(MultipartFile file,int sheetNo) throws IOException {
        String fileName = file.getOriginalFilename();
        // 判斷文件是.xlsx或者xls結尾。如果不是則拋出提示信息
        String suffix = fileName.substring(fileName.lastIndexOf(".") + 1);
        if (!"xlsx".equals(suffix) && !"xls".equals(suffix)) {
            System.out.println("請傳入excel文件");
        }
        return getList(suffix, file.getInputStream(),sheetNo);
    }

    /**
     * 功能描述: 獲取解析excel的數據
     * @param suffix String
     * @param inputStream InputStream
     * @param sheetNo int
     * @return ArrayList<Object>
     * @author:qhyu 
     * @date:2018年8月15日
     */
    private ArrayList<Object> getList(String suffix, InputStream inputStream,int sheetNo) throws IOException {
        ArrayList<Object> arrayList = new ArrayList<Object>();
        // 具體執行導入,可以引入策略模式
        // 解決excel2003和excel2007版本的問題
        if ("xlsx".equals(suffix)) {
            xlsxImp(inputStream, arrayList,sheetNo);
        }
        if ("xls".equals(suffix)) {
            xlsImp(inputStream, arrayList,sheetNo);
        }
        // 萬一新增一種新格式,對修改打開了,不符合oo編程規範
        return arrayList;
    }

    /**
     * 功能描述:2003xls導入查詢
     * @param inputStream InputStream
     * @param arrayList   ArrayList<Object>
     * @author:qhyu 
     * @date:2018年8月15日
     */
    private void xlsImp(InputStream inputStream, ArrayList<Object> arrayList, int index) throws IOException {
        // 初始整個Excel
        HSSFWorkbook workbook = new HSSFWorkbook(inputStream);
        // 獲取第一個sheet表
        HSSFSheet sheet = workbook.getSheetAt(0);
        for (int rowIndex = 2; rowIndex < sheet.getLastRowNum(); rowIndex++) {
            HashMap<String, Object> hashMap = new HashMap<String, Object>();
            HSSFRow row = sheet.getRow(rowIndex);
            //整行都爲空去掉
            if(row==null) {
                continue;
            }
            for (int cellIndex = 0; cellIndex < row.getLastCellNum(); cellIndex++) {
                HSSFCell cell = row.getCell(cellIndex);
                // 避免空指針異常
                if (cell == null) {
                    hashMap.put(getKey(inputStream, index, cellIndex), " ");
                    continue;
                }
                // 判斷格式
                if (cell.getCellType() == HSSFCell.CELL_TYPE_NUMERIC) {
                    SimpleDateFormat sFormat = new SimpleDateFormat("yyyy-MM-dd");
                    Date date = HSSFDateUtil.getJavaDate(cell.getNumericCellValue());
                    hashMap.put(getKey(inputStream, index, cellIndex), sFormat.format(date));
                } else if (cell.getCellType() == HSSFCell.CELL_TYPE_STRING) {
                    hashMap.put(getKey(inputStream, index, cellIndex), cell.getStringCellValue());
                } else if (cell.getCellType() == HSSFCell.CELL_TYPE_FORMULA) {
                    hashMap.put(getKey(inputStream, index, cellIndex), cell.getCellFormula().toString());
                } else if (cell.getCellType() == HSSFCell.CELL_TYPE_BLANK
                        || cell.getCellType() == HSSFCell.CELL_TYPE_BOOLEAN
                        || cell.getCellType() == HSSFCell.CELL_TYPE_ERROR) {
                    hashMap.put(getKey(inputStream, index, cellIndex), " ");
                }
            }
            if (hashMap.containsValue(" ") || hashMap.containsValue(null)
                    || hashMap.size() < sheet.getRow(0).getLastCellNum()) {
                continue;
            } else {
                arrayList.add(hashMap);
            }
        }
    }

    /**
     * 功能描述:2007xlsx導入查詢
     * @param inputStream InputStream
     * @param arrayList   ArrayList<Object>
     * @author:qhyu @date:2018年8月15日
     */
    private void xlsxImp(InputStream inputStream, ArrayList<Object> arrayList,int index) throws IOException {
        XSSFWorkbook xssfWorkbook = new XSSFWorkbook(inputStream);
        XSSFSheet sheet = xssfWorkbook.getSheetAt(index);
        for (int rowIndex = 2; rowIndex <= sheet.getLastRowNum(); rowIndex++) {
            HashMap<String, Object> hashMap = new HashMap<String, Object>();
            XSSFRow row = sheet.getRow(rowIndex);
            //整行都爲空去掉
            if(row==null) {
                continue;
            }
            for (int cellIndex = 0; cellIndex < row.getLastCellNum(); cellIndex++) {
                XSSFCell cell = row.getCell(cellIndex);
                // 避免空指針異常
                if (cell == null) {
                    hashMap.put(getKey(inputStream, index, cellIndex), " ");
                    continue;
                }
                // 判斷是否是日期格式
                if (cell.getCellType() == XSSFCell.CELL_TYPE_NUMERIC) {
                    SimpleDateFormat sFormat = new SimpleDateFormat("yyyy-MM-dd");
                    Date date = HSSFDateUtil.getJavaDate(cell.getNumericCellValue());
                    hashMap.put(getKey(inputStream, index, cellIndex), sFormat.format(date));
                } else if (cell.getCellType() == XSSFCell.CELL_TYPE_STRING) {
                    hashMap.put(getKey(inputStream, index, cellIndex), cell.getStringCellValue());
                } else if (cell.getCellType() == HSSFCell.CELL_TYPE_FORMULA) {
                    hashMap.put(getKey(inputStream, index, cellIndex), cell.getCellFormula().toString());
                } else if (cell.getCellType() == XSSFCell.CELL_TYPE_BLANK
                        || cell.getCellType() == XSSFCell.CELL_TYPE_BOOLEAN
                        || cell.getCellType() == XSSFCell.CELL_TYPE_ERROR) {
                    hashMap.put(getKey(inputStream, index, cellIndex), " ");
                }
            }
            if (hashMap.containsValue(" ") || hashMap.containsValue(null)
                    || hashMap.size() < sheet.getRow(0).getLastCellNum()) {
                continue;
            } else {
                arrayList.add(hashMap);
            }

        }
    }

    /**
     * 功能描述:根據表頭獲取key值
     * @param inputStream InputStream
     * @return String
     * @author:qhyu 
     * @date:2018年8月16日
     */
    public static String getKey(InputStream inputStream, int index, int cell) {
        String result = null;
        // sheet1(客票覈驗身份證查詢)
        if (index == 0) {
            switch (cell) {
            case 0:
                result="CardID";
                break;
            case 1:
                result="FlightNo";
                break;
            case 2:
                result="Segment";
                break;
            case 3:
                result="Time";
                break;
            default:
                break;
            }
        }
        // sheet2(客票覈驗票號查詢)
        if (index == 1) {
            switch (cell) {
            case 0:
                result="TicketNo";
                break;
            case 1:
                result="FlightNo";
                break;
            case 2:
                result="Segment";
                break;
            case 3:
                result="Time";
                break;
            default:
                break;
            }
        }
        // sheet3(客票追蹤)
        if (index == 2) {
            switch (cell) {
            case 0:
                result="TicketNo";
                break;
            default:
                break;
            }
        }
        return result;
    }

controller中的方法區分了2003和2007版本,也就是xls和xlsx的區別,測試的時候需要另存爲改後綴名,直接修改後綴是不行的。大部分是貼代碼,自己測試過沒有發現問題。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章