我正在执行一项任务,用户可以下载 Excel 格式的数据。 数据是动态生成的(作为通用列表),然后写入 Excel 文件,运行完美。
问题:
我面临的问题是,当数据很大时,下载文件需要几秒钟的时间。在此期间,我需要向最终用户显示某种进度/指示(比方说,下载......消息)。使用当前代码,我无法跟踪文件下载何时完成......
这是我的代码,
传递Web api方法和搜索条件的JS代码
var request = {};
request.Code = codeDdl.find(':selected').val();
$.blockUI({ message: '<h3>Downloading...</h3>' });
//Export to Excel all records
$().largeDownload("api/FileDownload/GetWorkQueueList", {
'request': JSON.stringify(request)
});
读取搜索条件并将其传递给 Web api 方法的 JS 代码:
(function (d) {
d.fn.largeDownload = function (a, b, c) { void 0 !== c ? (c = c.toUpperCase(), "GET" != c && (c = "POST")) : c = "POST"; if (void 0 === b || !1 == b) b = d().parse_url(a), a = b.url, b = b.params; var e = d("<form></form"); e.attr("method", c); e.attr("action", a); for (var f in b) a = d("<input />"), a.attr("type", "hidden"), a.attr("name", f), a.attr("value", b[f]), a.appendTo(e); d("body").append(e); e.bind("submit", DownloadedCallback); e.submit() }; d.fn.parse_url = function (a) {
if (-1 == a.indexOf("?")) return { url: a, params: {} }; var b = a.split("?"), a = b[0], c = {}, b = b[1].split("&"), e = {}, d; for (d in b) {
var g =
b[d].split("="); e[g[0]] = g[1]
} c.url = a; c.params = e; return c
}
})(jQuery);
Web API
[HttpPost]
public HttpResponseMessage GetWorkQueueList()
{
var resp = new HttpResponseMessage(HttpStatusCode.OK);
var currentContext = HttpContext.Current;
try
{
string strRequest = currentContext.Request.Form["request"];
var serializer = new JavaScriptSerializer();
var request = serializer.Deserialize<ViewRequest>(strRequest);
request.QueryAllRecords = true;
var workQueueList = MappingManager.GetWorkQueueList(request);
var legacyExcelView = //get data as generic list
....
....
var fileBytes = ExcelManager.GetExcelData<WQExcelView>(legacyExcelView);
var stream = new MemoryStream(fileBytes);
resp.Content = new StreamContent(stream);
resp.Content.Headers.ContentType = new MediaTypeHeaderValue("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
resp.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment") { FileName = "WorkQueueList.xlsx" };
resp.Content.Headers.Add("Content-Encoding", "UTF-8");
return resp;
}
catch (Exception ex)
{
resp.Content = new StringContent(ex.Message);
return resp;
}
}
我尝试过的:
在largeDownload javascript函数中,我添加了DownloadedCallback,但它似乎没有按我的预期工作。它会在下载完成之前立即触发。
问题:
如何在Web API方法中检查文件下载是否完成...我应该如何做才能显示进度条,直到显示文件下载对话框?
最佳答案
我们通常通过 2-3 个 API 调用来解决问题。我们的应用程序是用 Java 编写的;然而,同样的基本原则也适用于此。
第一个调用是在单独的线程中启动大型 SQL 查询、大型文件创建等。该请求会立即返回,有时会带有一个 id 来引用原始请求。
当在生成的线程中写入 CSV 中的行时,我们在原始线程中写入两个属性值,分别表示已处理的行数和总行数。如果它是一个大型 SQL 语句,我们通常会将语句本身批处理为几个有限的 SQL 语句,以便可以增量设置并显示进度值,而不是暂时处于 0%,然后突然达到 100%。分解 SQL 语句通常只会增加几毫秒的成本,但在用户体验方面提供了大量的值(value)。
我们有第二个 API 调用,该调用会被轮询,然后返回已处理数量和总计数的属性值。这就是我们用来制作进度条动画的东西。当达到 100% 或该调用响应上的状态标志发生变化时,我们通常会在单独的 API 调用中请求完成的文件。您还可以在同一进度调用中返回文件指针/路径。
关于javascript - 如何在 Web API 中检查文件下载是否完成,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31335402/