【问题标题】:Returning file from action and downloading with AJAX [duplicate]从操作中返回文件并使用 AJAX 下载 [重复]
【发布时间】:2020-04-15 14:51:31
【问题描述】:

这可能是重复的,但我还没有找到解决方案。

在我正在开发的应用程序中,有两个 export 按钮可以将 Excel 文件下载到用户的计算机上。

一个导出按钮执行一个 POST 表单方法,将参数路由到一个动作:

<input type="submit" value="EXPORT" id="exportButton" asp-action="ExportResultsData" 
asp-route-ClientID="@listItem.ClientID" asp-route-ProcessingType="@listItem.ProcessingType" 
asp-route-ProgressType="@Model.ProgressType" asp-route-FileName="@listItem.FileName" />

单击时,这些值将路由到控制器操作,它们用于创建文件并将其返回到下载文件的浏览器。都很好。

正如我所说,我有另一个按钮需要下载另一个 Excel 文件。但是,这个不同,因为视图模型不包含路由到其控制器操作所需的所有值。每次单击按钮时,我都需要调用一个 JavaScript 函数并获取一个具有以下结构的 JSON 对象:

{
  "draw": 1,
  "columns": [
    {
      "data": "Column1",
      "name": "Column1",
      "searchable": true,
      "orderable": true,
      "search": {
        "value": "",
        "regex": false
      }
    },
    {
      "data": "Column2",
      "name": "Column2",
      "searchable": true,
      "orderable": true,
      "search": {
        "value": "",
        "regex": false
      }
    },
    {
      "data": "Column3",
      "name": "Column3",
      "searchable": true,
      "orderable": true,
      "search": {
        "value": "",
        "regex": false
      }
    },
    {
      "data": "Column4",
      "name": "Column4",
      "searchable": true,
      "orderable": true,
      "search": {
        "value": "",
        "regex": false
      }
    }
  ],
  "order": [
    {
      "column": 0,
      "dir": "asc"
    }
  ],
  "start": 0,
  "length": 15,
  "search": {
    "value": "",
    "regex": false
  },
  "ClientID": 8,
  "FeedbackID": "8",
  "ProcessingType": "Import"
}

每次获取这些参数时,有些值可能会发生变化,列数可能会增加/减少。

我可以到达控制器动作,将参数绑定到模型,并成功生成 Excel 文件,但文件没有下载,只是返回到 AJAX success 部分:

function ExportFeedbackData(clientID, feedbackID, processingType) {
    var jqueryParams = GetJqueryParams();
    $.ajax({
        url: '/Client/ExportFeedbackData',
        type: 'POST',
        data: {
            DatatablesParameters: jqueryParams,
            ClientID: clientID,
            FeedbackID: feedbackID,
            ProcessingType: processingType,
        },
        success: function (exportedFile) {
            console.log(exportedFile);
            //file data just returns here and doesn't download
        },
        error: function (errormsg) {
            console.log(errormsg);
        }
    });
}

控制器动作:

//"DatatablesParameters" refers to parameters sent from a JS plugin called Datatables https://datatables.net/
//https://datatables.net/manual/server-side
public IActionResult ExporFeedbackData(DataTablesParameters DatatablesParameters, int ClientID, int FeedbackID, string ProcessingType)
{
    DataTable dt = _processingService.ReturnDataTable(DatatablesParameters, ClientID, FeedbackID, ProcessingType);

    using (ExcelPackage package = new ExcelPackage())
    {
        ExcelWorksheet worksheet = package.Workbook.Worksheets.Add(ProcessingType);
        worksheet.Cells["A1"].LoadFromDataTable(dt, PrintHeaders: true);
        for (var i = 0; i < dt.Columns.Count; i++)
        {
            worksheet.Cells.AutoFitColumns();
        }
        return File(package.GetAsByteArray(), XlsxContentType, $"{ProcessingType}.xlsx"); //Excel file returned
    }
}

所以,我想要的是能够使用 AJAX 下载文件,但我不知道该怎么做。该文件也可能很大。我也很想以某种方式消除 AJAX 并动态生成 &lt;input&gt; 标记,但每次我导出 jquery 对象中的值可能会有所不同。我也愿意接受其他解决方案。

我主要担心清洁度和可靠性。通过表单提交,您只需单击按钮即可下载。但是使用 AJAX 看起来会更加混乱。

【问题讨论】:

  • 这可能有效,我会尝试。帖子说“这消除了在服务器上创建和存储任何物理文件的需要”,但我查找了 TempData 及其存储在服务器上的内容。你知道吗?
  • TempData 由框架管理。结果,它也将被框架删除。该帖子讨论了您的代码 - 它不需要创建物理文件然后将其发送以供下载。该文件在内存中创建,然后下载。
  • 我让它与链接的解决方案一起工作。谢谢!

标签: javascript ajax asp.net-mvc asp.net-core download


【解决方案1】:

AJAX 请求是瘦客户端请求。响应不会自动发生任何事情;程序员需要对响应执行任何操作。由于要提示文件下载,所以需要在href中动态创建一个以文件数据为对象URL的锚链接,然后“点击”。

let a = document.createElement('a');
let url = window.URL.createObjectURL(exportedFile);
a.href = url;
a.download = 'myfile.xlsx';
document.body.append(a);
a.click();
a.remove();
window.URL.revokeObjectURL(url);

【讨论】:

  • 感谢您的回复。目前我无法让它工作,因为它看起来像 createObjectURL() 方法不再工作,因为浏览器正在禁用它。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-10-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-08-22
  • 2012-12-18
相关资源
最近更新 更多