先上图:
前端代码:
1 @(Html.DevExtreme().DataGrid<MettingReportViewModel>() 2 .ID("gridMetting") 3 .OnToolbarPreparing("toolbar_preparing") 4 ) 5 6 7 @(Html.DevExtreme().FileUploader() 8 .ID("file-uploader") 9 .UploadUrl(Url.Action("ImportExcelFile", "MettingReport")) 10 .DialogTrigger("#btnImport") @*将上传控件的触发事件绑定到按钮上,这样点击按钮就会弹出文件选择框了*@ 11 .Name("formFile") 12 .Accept("*") 13 .ChunkSize(2000) @* 分段上传必须设置*@ 14 .Visible(false) @* 将上传控件隐藏*@ 15 .OnUploadError("fileUploader_UploadError") 16 .OnUploaded("fileUploader_uploaded") 17 .OnUploadStarted("fileUploader_uploadStarted") 18 .OnProgress("onUploadProgress") 19 20 ) 21 22 23 <style> 24 .btnImport { 25 38px; 26 height: 36px; 27 background-color: #fff; 28 border: solid 1px #ddd; 29 border-radius: 4px; 30 } 31 32 .btnImport:hover { 33 background-color: #f5f5f5; 34 } 35 .chunk { 36 border-top: 0 solid #0080008a; 37 38px; 38 position: absolute; 39 top: 36px; 40 border-radius: 5px; 41 } 42 43 </style> 44 45 <script> 46 function toolbar_preparing(e) { 47 e.toolbarOptions.items.unshift( 48 { 49 location: "after", 50 template: "<div><button class='btnImport' id='btnImport' title='上传文件扩展名为:.xls 或 .xlsx'><i class='dx-icon dx-icon-upload'></i></button><div class='chunk' id='chunkDiv'></div></div>" 51 } 52 ); 53 } 54 55 var totalChunk = 36; 56 function fileUploader_UploadError(e) { 57 // 上传失败提示; 58 alterError(e.error.responseText); 59 displayChunkDiv(); 60 } 61 function fileUploader_uploaded(e) { 62 // console.log(e); 63 alterSuccess("上传成功"); 64 dataGrid.refresh(true); 65 $("#chunkDiv").css({ "border-top-width": totalChunk + "px", "top": "0" }); 66 67 displayChunkDiv(); 68 } 69 70 function displayChunkDiv() { 71 setTimeout(function () { 72 $("#chunkDiv").css({ "border-top-width": "0", "top": totalChunk + "px" }); 73 $("#btnImport").attr("disabled", false); 74 }, 1000); 75 } 76 77 function fileUploader_uploadStarted(e) { 78 // console.log(e); 79 $("#btnImport").attr("disabled", true); 80 } 81 82 function onUploadProgress(e) { 83 // console.log(e.segmentSize + " " + e.bytesLoaded + " " + e.bytesTotal); 84 var w = e.bytesLoaded / e.bytesTotal * totalChunk; 85 //console.log(w); 86 if (w <= (totalChunk - totalChunk / 6)) { 87 //显示 低于1/6 的进度条,用于页面效果 88 $("#chunkDiv").css({ "border-top-width": w + "px", "top": (totalChunk - w) + "px" }); 89 } 90 } 91 </script>
后端代码:
1 2 public class FileUploaderChunkMetaData 3 { 4 public int Index { get; set; } 5 public int TotalCount { get; set; } 6 public int FileSize { get; set; } 7 public string FileName { get; set; } 8 public string FileType { get; set; } 9 public string FileGuid { get; set; } 10 } 11 public class MettingReportController : Controller 12 { 13 [HttpPost] 14 public async Task<ActionResult> ImportExcelFile([FromServices] IWebHostEnvironment environment, IFormFile formFile, string chunkMetadata) 15 { 16 var temResult = new MessageModel<bool>(); 17 18 try 19 { 20 var currentDate = DateTime.Now; 21 var webRootPath = environment.WebRootPath; 22 var filePath = $"/UploadFiles/{currentDate:yyyyMMdd}/"; 23 24 //创建每日存储文件夹 25 if (!Directory.Exists(webRootPath + filePath)) 26 { 27 Directory.CreateDirectory(webRootPath + filePath); 28 } 29 30 var fileRoot = webRootPath + filePath; 31 32 if (!string.IsNullOrEmpty(chunkMetadata) && formFile!=null) 33 { 34 var metaDataObject = JsonConvert.DeserializeObject<FileUploaderChunkMetaData>(chunkMetadata); 35 36 //文件后缀 37 var fileExtension = Path.GetExtension(metaDataObject.FileName);//获取文件格式,拓展名 38 string[] allowExtensions = { ".xls", ".xlsx" }; 39 if (!allowExtensions.Any(n => n.Equals(fileExtension, StringComparison.CurrentCultureIgnoreCase))) 40 { 41 throw new Exception("上传的文件格式不正确"); 42 } 43 44 var tempFilePath = Path.Combine(fileRoot, metaDataObject.FileGuid + ".tmp"); 45 using (var stream = new FileStream(tempFilePath, FileMode.Append, FileAccess.Write)) 46 { 47 //追加到文件流 48 formFile.CopyTo(stream); 49 50 //判断文件大小 51 var fileSize = stream.Length; 52 if (fileSize > 1024 * 1024 * 10) //10M TODO:(1mb=1024X1024b) 53 { 54 throw new Exception("上传的文件不能大于10M"); 55 } 56 57 } 58 59 60 if (metaDataObject.Index == metaDataObject.TotalCount - 1) 61 { 62 //保存的文件名称(以名称和保存时间命名) 63 var saveName = metaDataObject.FileName.Substring(0, metaDataObject.FileName.LastIndexOf('.')) + "_" + currentDate.ToString("HHmmss") + fileExtension; 64 //完整的文件路径 65 var completeFilePath = Path.Combine(fileRoot, saveName); 66 67 //重名检查 68 if (System.IO.File.Exists(completeFilePath)) 69 { 70 throw new Exception("上传的文件异常,请重新上传"); 71 } 72 73 //保存文件 74 System.IO.File.Copy(tempFilePath, completeFilePath); 75 //删除临时文件 76 System.IO.File.Delete(tempFilePath); 77 78 //处理导入文件(业务相关) 79 80 81 //返回成功 82 temResult.Success = temImportResult.Success; 83 temResult.Msg = temImportResult.Msg; 84 temResult.Response = temImportResult.Response; 85 } 86 else 87 { 88 temResult.Success = true; 89 temResult.Response = true; 90 } 91 } 92 else { 93 temResult.Success = false; 94 temResult.Msg = $"导入失败,未检测上传的文件信息"; 95 temResult.Response = false; 96 97 throw new Exception("未检测上传的文件信息"); 98 } 99 100 } 101 catch (Exception ex) 102 { 103 temResult.Success = false; 104 temResult.Msg = $"导入失败:{ex.Message}"; 105 temResult.Response = false; 106 //return BadRequest($"导入失败:{ex.Message}"); 107 } 108 109 if (temResult.Success == true && temResult.Response == true) 110 { 111 return Ok(); 112 } 113 else 114 { 115 return BadRequest($"{temResult.Msg}"); 116 } 117 } 118 }