【问题标题】:How to download a file using JS being the file a result from an action method (.NET Core 2 MVC)如何使用 JS 作为操作方法的结果下载文件(.NET Core 2 MVC)
【发布时间】:2019-03-18 16:28:43
【问题描述】:

我有一个控制器操作方法,它返回一个文件以供下载。 我需要通过 Jquery 调用这个动作方法,那么,我如何获取文件以供下载?

我知道怎么通过ajax调用或者window.location来调用action方法,但是由于action方法结果是一个文件,我怎么把它放到JQuery里面供用户下载呢?

这是我的操作方法:

public async Task<IActionResult> ExportClientes()
    {
        var model = new BasesDadosViewModel();

        model.Clientes = await _db.Clientes.ToListAsync();
        model.ClienteObj = new Clientes();

        DataTable dt = new DataTable();

        List<string> DontUse_Field = typeof(Clientes).GetProperties().Where(x => x.GetCustomAttributes(typeof(ObjAttributes), true).Any(ca => ((ObjAttributes)ca).DontUse)).Select(x => x.Name).ToList();

        var cliente_fields = model.ClienteObj.GetType().GetProperties();

        //formatar colunas da datatable
        foreach (var field in cliente_fields)
        {
            DataColumn col = dt.Columns.Add(field.Name, field.PropertyType);
        }

        foreach (var cliente in model.Clientes)
        {
            DataRow export_row = dt.NewRow();

            //Preenche dados
            int c = 0;
            foreach (var field in cliente_fields)
            {
                if (!DontUse_Field.Contains(field.Name))
                {
                    export_row[c] = field.GetValue(cliente);
                    c++;
                }

            }

            dt.Rows.Add(export_row);
        }

        ExcelPackage excel = new ExcelPackage();
        var workSheet = excel.Workbook.Worksheets.Add("Clientes_Export");

        for (int i = 1; i < dt.Columns.Count; i++)
        {
            workSheet.Cells[1, i].Value = dt.Columns[i - 1];
        }

        int index = 2;
        foreach (DataRow row in dt.Rows)
        {
            for (int i = 1; i < dt.Columns.Count; i++)
            {
                workSheet.Cells[index, i].Value = row[i - 1];
            }

            index++;
        }

        //Autofit columns
        for (int i = 1; i < dt.Columns.Count; i++)
        {
            workSheet.Column(i).AutoFit();
        }

        var filename = "Clientes_Export.xlsx";
        //var path = Path.Combine(_appEnvironment.WebRootPath, @"exports", filename);
        using (var fileStream = new FileStream(filename, FileMode.Create))
        {
            excel.SaveAs(fileStream);
        }


        var memory = new MemoryStream();
        using (var stream = new FileStream(filename, FileMode.Open))
        {
            stream.CopyTo(memory);
        }

        memory.Position = 0;
        ContentTypes contentType = new ContentTypes();
        return File(memory, contentType.GetContentType(filename), filename);

    }

谢谢

【问题讨论】:

    标签: jquery .net asp.net-core-2.0


    【解决方案1】:
    $.ajax({
        url: '/url/for/file',
        method: 'GET',
        xhrFields:{
            responseType: 'blob'
        },
        success: function (data) {
            let a = document.createElement('a');
            a.href = window.URL.createObjectURL(data);
            a.download = 'filename.ext';
            document.body.append(a);
            a.click();
            window.URL.revokeObjectURL(url);
    });
    

    总而言之,您需要使用$.ajax 调用(而不是$.get 之类的调用),以便您可以传递选项。其中一个选项必须是xhrFields,因此您可以指定blob 的响应类型。然后,在您的成功函数中,您将动态创建一个新的a 元素,将download 属性设置为您希望文件下载为的文件名+扩展名,使用对象URL 设置href 属性(由 blob 数据组成),然后将此元素附加到您的正文中。之后,在这个动态创建的元素上触发点击事件就很简单了。

    【讨论】:

    • 嗨,克里斯,首先,非常感谢您对我的帮助。但是,您的建议不起作用。也许是因为我的行动方法?我用 action 方法更新了我的问题。谢谢
    猜你喜欢
    • 2020-06-15
    • 2017-08-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-04
    • 2019-02-10
    相关资源
    最近更新 更多