Как загрузить файл с использованием JS, являющегося файлом в результате метода действия (.NET Core 2 MVC) - PullRequest
0 голосов
/ 18 марта 2019

У меня есть метод действия контроллера, который возвращает файл для загрузки. Мне нужно вызвать этот метод действия через Jquery, так как мне получить файл для загрузки?

Я знаю, как вызвать метод действия с помощью вызова Ajax или window.location, но поскольку результатом метода действия является файл, как я могу поместить его для загрузки пользователем через 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);

    }

Спасибо

1 Ответ

0 голосов
/ 18 марта 2019
$.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 имя файла + расширение, для которого вы хотите загрузить файл, установите атрибут href с URL-адресом объекта (состоит из данных BLOB-объектов), а затем добавьте этот элемент в ваше тело.После этого достаточно просто вызвать событие click для этого динамически создаваемого элемента.

...