Search code examples
javascriptangularjsasp.net-mvcsystem.io.compression

How can i generate and download zip file from server in angularJs application?


My code is below:

    [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 code from component:

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();
                }
            });
        }

After all code its downloading zip file but when I am trying to open zip file its giving me error. Invalid zip file.

Please note I have used System.IO.Compression libraries to generate and download zip file.


Solution

  • I fixed this issue by doing following:

        [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}");
        }
    

    In the AngularJs code :

    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();
                });
            }
    

    This will catch zipped file url in response.data and download it by javascript code. Hope this will helpful to others too.