问题描述
我使用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个元素的数组,控制器将识别出该元素,生成文件并使其从浏览器自动下载?
如果您可以提供一些很棒的代码,但给我正确的方向也是有帮助的。
谢谢。
解决方法
您可以使用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,这是很常见的情况。