欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

.Net Core导出Excel防止重提交

程序员文章站 2024-01-21 14:44:34
...

在项目中导出Excel时,由于需要处理的数据量较大导致后台执行时间过长,造成前台页面长时间没反应,用户误以为点击失败从而再次点击导出按钮,因此出现了重提交的情况。
为了避免用户重复点击按钮,我们应该在用户第一次点击导出按钮时将按钮置为不可用,直到导出成功后才可再次导出。

一、解决思路

1、用户第一次点击导出按钮后,将导出按钮置为不可用状态并修改按钮text为“正在导出”
2、后台导出成功后往缓存中插入特定key-value键值对
3、前台通过定时检查缓存的值来判断Excel是否导出成功
4、若未导出成功则继续执行定时检查功能
5、若已导出成功则将导出按钮置为可用状态、修改按钮text为“导出”、取消定时操作并删除key-value键值对

注意:

此方法,不仅适用于Excel导出时防止重提交,其他防止重提交的情况也可以试试看。

二、示例代码

1、前台HTML

<form class="form-horizontal" id="dataForm">    
    <div class="form-group" style="text-align:center;margin-top:10px;">
        //不能防止重提交
        <button type="submit" class="btn btn-blue btnWidth120 boxShadowNone" οnclick='this.form.action="@Url.Action("ExportToCsv")";'>导出</button>
        //可以防止重提交
        <button type="button" class="btn btn-blue btnWidth120 boxShadowNone" id="btnExport">导出</button>
    </div>
</form>

2、前台js

var exportInterval = null;
$("#btnExport").click(function () {
    $("#btnExport").attr("disabled", "disabled");
    $("#btnExport").text("正在导出");
    //动态指定form的action并提交
    $("#dataForm").attr("action", "/Account/AccountInfo/ExportToCsv");
    $("#dataForm").submit();
    exportInterval = setInterval(clearExportDisable, 1000, "AccountInfoExport", $("#btnExport")[0], "导出");
});

function clearExportDisable(sessionKey, control, buttonText) {
    $.ajax({
        type: "get",
        url: "/Session/GetSession",
        data: "key=" + sessionKey,
        dataType: "json",
        success: function (data) {
            if (data.value == "Success") {
                $.ajax({
                    type: "get",
                    url: "/Session/RemoveSession",
                    data: "key=" + sessionKey,
                    dataType: "json",
                    success: function (data) {
                        if (data.success) {
                            $(control).text(buttonText);
                            $(control).removeAttr("disabled");
                            clearInterval(exportInterval);
                        }
                        else {
                            alert("移除Session失败");
                        }
                    },
                    error: function (err) {
                        alert("移除Session失败");
                    }
                });
            }
        },
        error: function (err) {
            alert("获取Session失败");
        }
    });
}

3、后台导出Excel的代码

public FileResult ExportToCsv(Sync_EngineerAccount model, DateTime? createDateEnd)
{
    string where = GetWhere(model, createDateEnd);
    List<Sync_EngineerAccount> list = new BaseRepository<Sync_EngineerAccount>().GetModelList(where, parameters: null).ToList();
    using (ExcelPackage package = new ExcelPackage())
    {
        ExcelWorksheet sheet = package.Workbook.Worksheets.Add("工程师信息");
        sheet.Cells[1, 1].Value = "账号类型";
        sheet.Cells[1, 2].Value = "管理员工号";
        sheet.Cells[1, 3].Value = "账号名称";
        sheet.Cells[1, 4].Value = "账号信息";
        sheet.Cells[1, 5].Value = "一级部门 ";
        sheet.Cells[1, 6].Value = "二级部门";
        sheet.Cells[1, 7].Value = "三级部门";
        sheet.Cells[1, 8].Value = "是否有效";
        sheet.Cells[1, 9].Value = "备注";
        

        for (int i = 0; i < list.Count; i++)
        {
            sheet.Cells["A" + (i + 2)].Value = list[i].AccountType + "(" + list[i].AccountTypeName + ")";
            sheet.Cells["B" + (i + 2)].Value = list[i].ManagerCode;
            sheet.Cells["C" + (i + 2)].Value = list[i].AccountName;
            sheet.Cells["D" + (i + 2)].Value = list[i].AccountMsg;
            sheet.Cells["E" + (i + 2)].Value = list[i].Dept1Name;
            sheet.Cells["F" + (i + 2)].Value = list[i].Dept2Name;
            sheet.Cells["G" + (i + 2)].Value = list[i].Dept3Name;
            sheet.Cells["H" + (i + 2)].Value = list[i].Dept1Name;
            sheet.Cells["I" + (i + 2)].Value = list[i].IsActive == 0 ? "有效" : "无效";
            sheet.Cells["J" + (i + 2)].Value = list[i].Remark;
        }

        sheet.Cells.AutoFitColumns(0);

        System.IO.MemoryStream output = new System.IO.MemoryStream();
        package.SaveAs(output);
        output.Position = 0;
        //导出成功后往Session中插入特定key-value键值对
        ServiceContext.SetSessionData("AccountInfoExport", "Success");
        return File(output, "application/vnd.ms-excel", string.Format("工程师信息{0}.xls", DateTime.Now.ToString("yyyyMMddHHmm")));
    }
}