.Net Core导出Excel防止重提交

在项目中导出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" onclick='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")));
    }
}

三、使用bind()防止连续点击

$(document).ready(function () {
    $("#btnExport").bind("click", ExportApplication);
});

//本意:submit()执行完毕后再重新绑定按钮
//实际:重新绑定发生在后台方法执行完毕之前,目前没找到改进方法
//意义:对于非submit()可以利用ajax+bind+unbind来防止连续点击
function ExportApplication() {
    $("#btnExport").unbind("click");
    $("#btnExport").text("正在导出");
    $("#dataForm").attr("action", "/Account/ApplicationInfo/ExportToCsv");
    $("#dataForm").submit();
    alert("submit()之后");
    $("#btnExport").text("导出");
    $("#btnExport").bind("click", ExportApplication);
    alert("重新bind()之后");
}

如果您觉得本文对您有一些帮助请点赞、评论支持一下 ,谢谢!

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

changuncle

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值