首页 > 解决方案 > 有没有办法将数组发布到 web api 或 mvc 控制器并获取文件以下载结果?

问题描述

我使用一个 html 表格,它的内容可以通过实现鼠标拖放来更改。从技术上讲,您可以将数据从任何表格单元格移动到另一个表格单元格。表格大小为 50 行 * 10 列,每个单元格都有一个唯一标识符。我想使用 C# EPPlus 库将其导出为 .xlsx 格式,并将导出的文件返回给客户端。

所以我需要在按下按钮时传递整个表格数据并将其发布到 web api 或 mvc 控制器,创建一个 excel 文件(如原始 html 表格数据)并将其发送回浏览器下载。

所以想法是创建一个包含每个表格单元格值的数组(当然该数组中应该有空单元格),并将该数组发布到控制器。

这种方法的问题在于下载,如果我使用常规 jquery 的 ajax.post 调用 api 或 mvc 控制器,它不会将响应识别为文件。

ajax发布后的C#代码:

  [HttpPost]
    public IHttpActionResult PostSavedReportExcel([FromBody]List<SavedReports> savedReports, [FromUri] string dateid)
    {
        //some excel creation code
                          HttpResponseMessage response = new HttpResponseMessage(HttpStatusCode.OK)
            {
                Content = new StreamContent(new MemoryStream(package.GetAsByteArray()))

            };
            response.Content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
            response.Content.Headers.ContentDisposition = new System.Net.Http.Headers.ContentDispositionHeaderValue("attachment")
            {
                FileName = dateid + "_report.xlsx"
            };
            ResponseMessageResult responseMessageResult = ResponseMessage(response);
            return responseMessageResult;
    }

通常,对于这种结果,我可以window.location = myurltocontroller用来正确下载,但这仅适用于 GET 请求,POST 任何事情都是不可能的。

我找到了一些可以帮助我解决这个主题的答案: JavaScript post request like a form submit

这指出我应该创建一个传递值的表单,但我不知道如何在数组的情况下这样做(表包含 50*10 = 500 个值,我必须在表单中传递)

我尝试了一些针对 html-excel 导出问题的前端解决方案,当然不需要在 api 端构建文件,但不推荐使用免费的 jquery 插件,不可自定义,仅处理 .xls 格式等。

我发现 EPPlus nuget 包是一个高度可定制的工具,这就是为什么我首先要尝试这个。

所以问题是:如何发布一个包含 500 个元素的数组,控制器将识别、生成文件并使其自动从浏览器下载?

如果你能提供一些很棒的代码,但给我正确的方向也是有帮助的。

谢谢你。

标签: javascriptc#jqueryexcelasp.net-mvc

解决方案


您可以使用fetch()( docs ) 从 JS 前端发送请求。当浏览器 (JS) 收到响应时,它可以提供其二进制内容作为下载。像这样的东西:

fetch("http://your-api/convert-to-excel", // Send the POST request to the Backend
    {
        method:"POST",
        body: JSON.stringify(
            [[1,2],[3,4]] // Here you can put your matrix
        )
    })
    .then(response => response.blob())
    .then(blob => {
        // Put the response BLOB into a virtual download from JS
        if (navigator.appVersion.toString().indexOf('.NET') > 0) {
            window.navigator.msSaveBlob(blob, "my-excel-export.xlsx");
        } else {
            var a = window.document.createElement('a');
            a.href = URL.createObjectURL(blob);
            a.download = "my-excel-export.xlsx";
            a.click();
        }});

所以浏览器的JS部分实际上是先在后台下载文件,完成后才会触发从浏览器内存“下载”到HD上的文件中。这是需要不记名令牌身份验证的 REST API 的常见场景。


推荐阅读