【问题标题】:How can i generate and download zip file from server in angularJs application?如何在 angularJs 应用程序中从服务器生成和下载 zip 文件?
【发布时间】:2018-09-28 09:52:52
【问题描述】:

我的代码如下:

    [System.Web.Mvc.HttpPost]
    public ActionResult DownloaZipFile([FromBody] int id)
    {
        var result = _service.GetDocuments(id);
        var downloadFileName = $"Report{id}.zip";
        var downloadFilePath = Server.MapPath($"~/Uploads/TempZipDownload/{downloadFileName}");

        if (System.IO.File.Exists(downloadFilePath))
        {
            System.IO.File.Delete(downloadFilePath);
        }

        var zip = ZipFile.Open(downloadFilePath, ZipArchiveMode.Create);

        foreach (var file in result)
        {
            zip.CreateEntryFromFile(Server.MapPath(Path.Combine("~/Uploads/TempImageDownload/" + file.Filename)), file.Filename);
        }

        zip.Dispose();
        return File(downloadFilePath, "application/zip", downloadFileName);
    }

来自组件的 AngularJs 代码:

vm.downloadReport = function(id) {
            service.DownloadReport(id).then(function(response) {

                var file = new Blob([response.data],
                {
                    type: 'application/zip'
                });

                if (navigator.msSaveBlob) {
                    navigator.msSaveBlob(file);
                } else {
                    var fileUrl = URL.createObjectURL(file);
                    console.log(fileUrl);
                    var a = document.createElement('a');
                    a.href = fileUrl;
                    a.download = 'ReportDownload' + id + '.zip';
                    document.body.appendChild(a);
                    a.click();
                }
            });
        }

在所有代码下载 zip 文件之后,但是当我尝试打开 zip 文件时,它给了我错误。 zip 文件无效。

请注意,我使用 System.IO.Compression 库来生成和下载 zip 文件。

【问题讨论】:

  • 如果您直接下载 Zip(通过访问浏览器栏中的操作 URL,而不是通过您的 Javascript),它可以工作吗?我们需要缩小问题范围。
  • 是的,在这种情况下它工作得很好。它从保存在服务器上的位置下载文件。
  • 好吧,所以不要使用所有这些复杂的代码来下载一些内容,生成一个超链接并假装点击它,为什么不让你的脚本对那个 URL 执行一个 window.location 或 window.open 命令,然后它会正常下载。通常,通过 ajax 下载并不是一个很好的解决方案,它并不意味着以这种方式工作
  • 是的,我同意你的观点,我只是这样修复了它,我所做的是我将该压缩文件的 URL 作为 response.data 返回,然后在 javacript 中创建虚拟超链接并单击该超链接。所以解决了它。感谢您的时间和帮助。 :)
  • 你应该添加它作为答案,也许用一点代码 sn-p 来解释。您可以回答和接受您自己的问题。然后其他人可以在将来找到它(并可能对其进行投票)

标签: javascript angularjs asp.net-mvc system.io.compression


【解决方案1】:

我通过以下操作解决了这个问题:

    [System.Web.Mvc.HttpPost]
    public ActionResult DownloaZipFile([FromBody] int id)
    {
        var result = _service.GetDocuments(id);
        var downloadFileName = $"Report{id}.zip";
        var downloadFilePath = Server.MapPath($"~/Uploads/TempZipDownload/{downloadFileName}");

        if (System.IO.File.Exists(downloadFilePath))
        {
            System.IO.File.Delete(downloadFilePath);
        }

        var zip = ZipFile.Open(downloadFilePath, ZipArchiveMode.Create);

        foreach (var file in result)
        {
            zip.CreateEntryFromFile(Server.MapPath(Path.Combine("~/Uploads/TempImageDownload/" + file.Filename)), file.Filename);
        }

        zip.Dispose();
        return Json($"/Uploads/TempZipDownload/{downloadFileName}");
    }

在 AngularJs 代码中:

vm.downloadReport = function(id) {
            service.DownloadReport(id).then(function(response) {
                var a = document.createElement('a');
                a.href = response.data;
                a.download = 'ReportDownload';
                document.body.appendChild(a);
                a.click();
            });
        }

这将在 response.data 中捕获压缩文件 url 并通过 javascript 代码下载它。希望这对其他人也有帮助。

【讨论】:

  • 我认为你可以只做window.location.href = response.data 而不是创建一个虚拟超链接。 developer.mozilla.org/en-US/docs/Web/API/Location 。您还可以通过使用 window.location.href 访问单个操作 URL(例如 downloadZipFile)将整个事情简化为单个 HTTP 请求,该 URL 创建 zip 文件,然后将其作为 FileResult 发送以供下载。那么你不需要单独的 ajax 调用来获取文件的 URL。
  • @ADyson 你救了我。字面意思。
【解决方案2】:

我认为你可以只做window.location.href = response.data 而不是创建一个虚拟超链接。有关文档,请参阅 https://developer.mozilla.org/en-US/docs/Web/API/Location

您还可以通过使用 window.location.href 访问单个操作 URL(例如 /downloadZipFile)将整个事情简化为单个 HTTP 请求,该 URL 创建 ZIP 文件,然后将其作为 FileResult 立即发送以供下载。您甚至可以在内存中创建它而无需将其保存到磁盘。那么您就不需要单独的 AJAX 调用来获取文件的 URL。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-23
    • 2015-08-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多