1. 程式人生 > >poi解析excel驗證檔案是否符合模板,以及前端提示後端上傳驗證結果

poi解析excel驗證檔案是否符合模板,以及前端提示後端上傳驗證結果

1.前端使用fileinput外掛上傳

    $("#file2").fileinput({
        language: 'zh',
        uploadUrl: basePath + 'uploadVehicleFile',
        maxFileCount: 40, //表示允許同時上傳的最大檔案個數
        maxFileSize: 20480000,
        showCaption: true, //是否顯示標題
        browseClass: "btn btn-primary", //按鈕樣式
        showPreview: true,
        allowedFileExtensions: ["xls","xlsx"],
        uploadAsync: true,
        showUpload: true, //是否顯示上傳按鈕        
        maxImageWidth: 80,
        maxImageHeight: 80,
        enctype: 'multipart/form-data', //不對傳送的字元進行編碼
        previewFileIcon: "<i class='glyphicon glyphicon-king'></i>",
        msgFilesTooMany: "選擇上傳的檔案數量({n}) 超過允許的最大數值{m}!",
        uploadExtraData: function(previewId, index) {
            var data = {
                bidId: null, 
                planProId: "專案主鍵", 
                belongProject: "所屬專案",
                firstMenu: "一級選單",
                secondMenu: "二級選單",
                fileType: "檔案型別",
                workingstageId: "工作空間",
                parentTreeId: "父類樹id"
            };
            return data;
        },
        previewFileIconSettings: {
            'doc': '<i class="fa fa-file-word-o text-primary"></i>',
            'xls': '<i class="fa fa-file-excel-o text-success"></i>',
            'ppt': '<i class="fa fa-file-powerpoint-o text-danger"></i>',
            'jpg': '<i class="fa fa-file-photo-o text-warning"></i>',
            'pdf': '<i class="fa fa-file-pdf-o text-danger"></i>',
            'zip': '<i class="fa fa-file-archive-o text-muted"></i>',
            'htm': '<i class="fa fa-file-code-o text-info"></i>',
            'txt': '<i class="fa fa-file-text-o text-info"></i>',
            'mov': '<i class="fa fa-file-movie-o text-warning"></i>',
            'mp3': '<i class="fa fa-file-audio-o text-warning"></i>',
        },
        previewFileExtSettings: {
            'doc': function(ext) {
                return ext.match(/(doc|docx)$/i);
            },
            'xls': function(ext) {
                return ext.match(/(xls|xlsx)$/i);
            },
            'ppt': function(ext) {
                return ext.match(/(ppt|pptx)$/i);
            },
            'zip': function(ext) {
                return ext.match(/(zip|rar|tar|gzip|gz|7z)$/i);
            },
            'htm': function(ext) {
                return ext.match(/(php|js|css|htm|html)$/i);
            },
            'txt': function(ext) {
                return ext.match(/(txt|ini|md)$/i);
            },
            'mov': function(ext) {
                return ext.match(/(avi|mpg|mkv|mov|mp4|3gp|webm|wmv)$/i);
            },
            'mp3': function(ext) {
                return ext.match(/(mp3|wav)$/i);
            },
        }
    });

2.後端接收,使用springmvc方式

controller層

       @RequestMapping("/uploadVehicleFile")  
    public String uploadAndParseRoadConfirmFile(@RequestParam("file") MultipartFile[] files, HttpServletRequest request,HttpServletResponse response) {
        try {
            String planProId = request.getParameter("planProId");
            if(examineFileListService.chooseProId(planProId)) {
                return robPlandRoadConfirmService.uploadAndParseRoadConfirmFile(files,request,response);
            }else {
                return new Message(100,"檔案上傳解析失敗,請選擇所屬專案!").toJson(); 
            }
        } catch (Exception e) {
              return new Message(Message.ERROR,"檔案上傳有誤!").toJson();
        }
    }

service層:

public String uploadVehicleFile(MultipartFile[] files, HttpServletRequest request, HttpServletResponse response) {
        Message message = new Message();     
        try {
            if(files!=null && files.length>0){
                  request.setCharacterEncoding("utf-8");   
                  response.setCharacterEncoding("utf-8");  
                  List<RobPlancqCplan> robPlancqCplanList = new ArrayList<RobPlancqCplan>();
                  for (int i = 0; i < files.length; i++) {
                      robPlancqCplanList.clear();
                     MultipartFile file = files[i];
                     String md5 = DigestUtils.md5Hex(file.getInputStream());             //這裡不能用fileInput,試了好久     
                     String filePath=examineFileListService.getSaveMinioPath(request);   //儲存在minio中的目錄結構
                     String fileName = file.getOriginalFilename();                       //檔名字
                      String hql = "select * from 檔案表 where file_md5='"+md5+"' and file_path='"+filePath+"'";  //驗證檔案是否存在,不存在再上傳
                     List<ExamineFileList> existExamineFileList = super.getDao().findBySql(hql, ExamineFileList.class);
                     if(existExamineFileList != null && existExamineFileList.size()>0) {  //指定目錄下已經存在此檔案,不進行上傳操作  
                          message.setType(100);
                          message.setMsg(fileName+"已經上傳過,不再重複上傳,檔案上傳失敗");
                     }else{
                         InputStream fileInput = file.getInputStream();                      //輸入流
                         Workbook workBook = examineFileListService.getWorkBook(fileInput,fileName); 
                          if(workBook != null){
                               String planProId = request.getParameter("planProId");         
                              message = parseFileAndSave(workBook,robPlancqCplanList,planProId,fileName);        //解析和儲存檔案
                              if(message.getType()==200){                                    //解析沒有問題才上傳到Minio中和儲存到資料庫中
                                  robPlancqCplanRepository.save(robPlancqCplanList);
                                  message = examineFileListService.uploadFileOne(file,request,response);
                              }
                          }else {     
                              message.setType(100);
                              message.setMsg(fileName+"為空,檔案上傳失敗");
                          }
                     }
                  }
            }else {
                  message.setType(100);
                  message.setMsg("上傳檔案數量少於1,檔案上傳失敗");
            }
        } catch (Exception e) {
              message.setType(Message.ERROR);
              message.setMsg("請檢測excel必填專案完善文件,檔案上傳失敗");
        }
        return message.toJson();
    }

    /**
     * @Description 解析和儲存檔案
     * @author [zhanglizeng] Tel:
     * @createDate 2018年11月22日 下午3:21:04
     */
    private Message parseFileAndSave(Workbook workBook, List<RobPlancqCplan> robPlancqCplanList, String planProId,String fileName) {
        Message message = new Message();
        try {
            for(int sheetNum=0;sheetNum< workBook.getNumberOfSheets();sheetNum++){
                Sheet sheet = workBook.getSheetAt(sheetNum);
                if(sheet.getLastRowNum() == 0 &&  sheet.getPhysicalNumberOfRows() == 0){      
                    continue; 
                }        
                message = parseSheet(sheet,robPlancqCplanList,planProId,fileName);
                if(message.getType() != 200){    //有一個sheet不符合判斷此解析文件無效
                    return message;         
                }
              }
        } catch (Exception e) {
            return new Message(Message.ERROR,fileName+"檔案解析失敗");
        }
        return message;
    }

    /**
     * @Description 解析sheet
     * @author [zhanglizeng] Tel:
     * @createDate 2018年11月22日 下午3:23:09
     */
    private Message parseSheet(Sheet sheet, List<RobPlancqCplan> robPlancqCplanList, String planProId,String fileName) {
        Message message = new Message();   
        try {      
            String title = examineFileListService.parseCell(sheet.getRow(0).getCell(0));  //得到標題      
            if(title != null && title.length()>0){                   //判斷標題是否合法
                 if(checkColTitle(sheet)){                           //判斷excel的列標題是否和模板一致
                     message = parseCell(sheet,robPlancqCplanList,planProId,fileName);     //解析檔案
                 }else{
                    message.setType(100);    
                    message.setMsg("檔案中的列標題順序不符合要求,請參照模板填寫,"+fileName+"解析失敗!");
                 }
            }else {
                return new Message(100,"sheet沒有標題,"+fileName+"檔案解析失敗");
            }
        } catch (Exception e) { 
           return new Message(Message.ERROR,"存在為空的sheet,建議刪除空sheet,檔案解析失敗");
        }
        return message;
    }

    /**
     * @Description 解析檔案
     * @author [zhanglizeng] Tel:
     * @createDate 2018年11月22日 下午3:43:34
     */
    private Message parseCell(Sheet sheet, List<RobPlancqCplan> robPlancqCplanList, String planProId, String fileName) {
        int temp=0;     
        try {      
            for(int rowNum = 2;rowNum <= sheet.getPhysicalNumberOfRows();++rowNum){  
                Row row = sheet.getRow(rowNum);       
                if(row == null){   
                    continue;
                }  
                temp = rowNum;       
                parseRow(row,robPlancqCplanList,planProId);         //解析每一行資料
             }
        } catch (Exception e) {     
            return new Message(Message.ERROR,(temp+1)+"行文字內容不符合模板要求,"+fileName+"解析失敗");      
        }
        return new Message(Message.OK,fileName+"檔案上傳成功");
    }

    /**
     * @Description 解析每一行資料
     * @author [zhanglizeng] Tel:
     * @createDate 2018年11月22日 下午3:45:33
     */
    private void parseRow(Row row, List<RobPlancqCplan> robPlancqCplanList, String planProId)throws Exception {
        String carType = examineFileListService.parseCell(row.getCell(0)).trim();    
        String carUnit = examineFileListService.parseCell(row.getCell(1)).trim();   
        String carPlates = examineFileListService.parseCell(row.getCell(2)).trim(); 
        String carVtime = examineFileListService.parseCell(row.getCell(3)).trim();  
        String carRemark = examineFileListService.parseCell(row.getCell(4)).trim(); 
        if((carType!=null && carType.length()>0) || (carUnit!=null && carUnit.length()>0) || 
            (carPlates!=null && carPlates.length()>0) || (carVtime!=null && carVtime.length()>0)  
            || (carRemark!=null && carRemark.length()>0)) {   
            RobPlancqCplan robPlancqCplan = new RobPlancqCplan();   
            robPlancqCplan.setCarType(carType);
            robPlancqCplan.setCarUnit(carUnit);
            robPlancqCplan.setCarPlates(carPlates);
            if(carVtime != null && carVtime.length()>0) {
               robPlancqCplan.setCarVtime(examineFileListService.getDateByString(carVtime)); //轉成日期格式
            }
            robPlancqCplan.setCarRemark(carRemark);
            robPlancqCplan.setCreateTime(new Date());   
            robPlancqCplan.setCreateUserCode(getUserCode());
            robPlancqCplan.setCreateUserName(getUserName());
            robPlancqCplan.setGuid(getUUID());   
            robPlancqCplan.setPlanProId(planProId);  
            robPlancqCplanList.add(robPlancqCplan);
        }      
    }

    /**
     * @Description 判斷excel的列標題是否和模板一致
     * @author [zhanglizeng] Tel:
     * @createDate 2018年11月22日 下午3:25:28
     */
    private boolean checkColTitle(Sheet sheet) {
        String carType = examineFileListService.parseCell(sheet.getRow(1).getCell(0)).trim();    //車輛用途
        String carUnit = examineFileListService.parseCell(sheet.getRow(1).getCell(1)).trim();    //車輛單位
        String carPlates = examineFileListService.parseCell(sheet.getRow(1).getCell(2)).trim();  //車輛牌照
        String carVtime = examineFileListService.parseCell(sheet.getRow(1).getCell(3)).trim();   //校驗完成時間
        String carRemark = examineFileListService.parseCell(sheet.getRow(1).getCell(4)).trim();  //備註
        if("車輛用途".equals(carType) && "車輛單位".equals(carUnit) && "車輛牌照".equals(carPlates) 
          && "校驗完成時間".equals(carVtime) && "備註".equals(carRemark)) {
            return true;
        }else {
            return false;
        }
    }
3.頁面接收上傳結果:

$("#file2").on('fileuploaded', function(event, data, previewId, index) {
        var message = mini.decode(data);
        if(message.response.type == 200) {
            if(!flag2){    //手動點選上傳
                   showMsg("xx檔案上傳成功","success",800,"center","center");
               }else{         //點選確定時檢測到沒有上傳,採取的上傳操作
                   if(getFileTotal2()==1){     
                       if(getFileTotal1()==0 && getFileTotal3()==0){   //其它檔案都上傳完了,可以在個方法中關閉視窗 
                           showMsg("xx上傳成功","success",1800,"center","center",closeWindow);                       
                       }else{
                           showMsg("xx件上傳成功","success",800,"center","center");   
                       }
                   }
               }
        }else if(message.response.type == 150){
               showMsg("請選擇所屬專案再上傳xx檔案,檔案上傳失敗","warning",2000,"center","center");
           }else {
            showMsg(message.response.msg, "warning", 1200, "center", "center");
        }
    });