1、导入效果
2、进度条HTML代码,需要引用boostrap相关的样式文件
<div id="pross" class="progress" style="width:400px;margin-top:10px;display:none;">
<div class="progress-bar progress-bar-striped active" role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100" style="width: 0%">
0%
</div>
</div>
<div id="div_import_result" style="display:none;color:red;word-break:break-all;width:400px;">
</div>
3、 JS 代码
this.resultProgress = function (loaded, total) {
var percent = loaded / total * 100;
var percentStr = String(percent);
if (percentStr == "100") {
percentStr = "100.0";
}
percentStr = percentStr.substring(0, percentStr.indexOf("."));
$("#div_import_result").hide();
$("#pross").show();
var timesRun = percentStr;
$("#pross .progress-bar").attr('aria-valuenow', timesRun);
$("#pross .progress-bar").css('width', timesRun + '%');
$("#pross .progress-bar").html(timesRun + '%');
}
this.ImprotUserBtnSave = function (event, ele) {
var formData = new FormData();
var fileInput = document.getElementById("fileField");
for (var i = 0; i < fileInput.files.length; i++) {
var file = fileInput.files[i];
formData.append("file" + i, file);
}
page.resultProgress((0), 1)
$.ajax({
url: "/User/ImportUser",
type: "POST",
data: formData,
contentType: false, //必须false才会自动加上正确的Content-Type
processData: false, //必须false才会避开jQuery对 formdata 的默认处理
enctype: 'multipart/form-data',
//xhr: function () {
// //获取ajax中的ajaxSettings的xhr对象 为他的upload属性绑定progress事件的处理函数
// var myXhr = $.ajaxSettings.xhr();
// if (myXhr.upload) {
// //检查其属性upload是否存在
// myXhr.upload.addEventListener("progress", page.resultProgress, false);
// }
// return myXhr;
//},
success: function (data) {
if (data.IsSuccess)
page.getImportUserProcess(data.Data);
//page.CloseModelDiv(ele);
},
error: function (data) {
console.log(data);
}
})
}
this.getImportUserProcess = function (guid) {
var timestamp = new Date().getTime();
$.ajax({
url: "/Common/GetImprotProcess?guid=" + guid + "&t=" + timestamp,
type: "get",
success: function (oD) {
if (oD.IsSuccess) {
page.resultProgress((oD.Data.SuccessCount + oD.Data.ErrorCount), oD.Data.Total)
if (oD.Data.IsSuccess) {
page.ClearProgress();
setTimeout(function () {
var message = "共" +oD.Data.Total+
"条数据,成功" +oD.Data.SuccessCount+
"条数据,失败" +oD.Data.ErrorCount+
"条数据";
$("#div_import_result").text(message);
$("#div_import_result").show();
if (oD.Data.ErrorCount > 0)
page.Down(null,"/Common/GetImportErrorResult?guid=" + guid,'导入失败日志.cvs');
}, 1000);
} else {
setTimeout(function () {
page.getImportUserProcess(guid)
}, 1000)
}
}
}
});
}
// 下载导入结果
this.Down = function (formData, url, name) {
return new Promise((resolve, reject) => {
var xhr = new XMLHttpRequest();
xhr.open("get", url, true); // 也可以使用POST方式,根据接口
xhr.responseType = "blob"; // 返回类型blob
// 定义请求完成的处理函数,请求前也可以增加加载框/禁用下载按钮逻辑
xhr.onload = function () {
// 请求完成
if (this.status === 200) {
// 返回200
var blob = this.response;
var reader = new FileReader();
reader.readAsDataURL(blob); // 转换为base64,可以直接放入a表情href
reader.onload = function (e) {
// 转换完成,创建一个a标签用于下载
var a = document.createElement("a");
a.download = name;
a.href = e.target.result;
$("body").append(a); // 修复firefox中无法触发click
a.click();
resolve(200)
$(a).remove();
};
}
};
// 发送ajax请求
xhr.send(formData);
})
};
4、后端代码
// 获取导入进度
[HttpGet]
[Route("GetImportProcess")]
public ResponseResult<ImportProcess> GetImportProcess(Guid guid)
{
...
}
// 获取导入结果(文件流的方式输出)
[HttpGet]
public IActionResult GetImportErrorResult(Guid guid)
{
var fileName = "导入结果.cvs";
var stream = Encoding.UTF8.GetBytes($"获取失败,{result.Error}");
return File(stream, "text/plain", fileName);
}
// 导入
[HttpPost]
public IActionResult ImportUser()
{
var files = Request.Form.Files;
if (files != null && files.Count > 0)
{
var lst = new List<string>();
using (var fileStream = item.OpenReadStream())
{
using (StreamReader streamReader = new StreamReader(fileStream))
{
while (streamReader.Peek() != -1)
{
string str = streamReader.ReadLine();
lst.Add(str);
}
}
}
Task.Run(()=>{
Import(lst);
});
}
return Json(new ResponseResult<string>()
{
IsSuccess = true,
Data = Guid.NewGuid()
});
}
5、设计思路:一共有三个接口,ImportUser、GetImportProcess、GetImportErrorResult。
5.1、导入接口(ImportUser)
上传文件、解析文件内容、检测数据是否合法并导入数据库。
生成一个唯一标识和导入进度(上传成功、失败数量)绑定并写入缓存。
返回唯一标识。
5.2、获取导入进度(GetImportProcess)
跟据导入接口返回的唯一标识到缓存中查询导入进度。前端需要不断的发送请求,直到上传完为止。
5.3、获取导入结果(GetImportErrorResult)
当导入过程中有失败的记录需要已文本文件的形式展示。
导入完成后并且有导入失败的记录那么会调用该接口获取。
通过导入接口返回的唯一标识到缓存中查询并将查询的结果已文件流的形式返回给前端下载。