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");
}
});