public async Task <IActionResult> DownloadFileKPI(int year) { try { var folderName = string.Format("KPI{0}", DateTime.Now.ToString("yyyyMMddHHmmss")); var folderPath = Path.Combine(Directory.GetCurrentDirectory(), "Resources", "Report", folderName); if (!System.IO.Directory.Exists(folderPath)) { System.IO.Directory.CreateDirectory(folderPath); } //get data _UnitOfWork.Transaction = _UnitOfWork.Begin(); var listEmp = await _UnitOfWork.KPIRepository.GetKPIEmployeeAsync(year); //save file if (!listEmp.Any()) { return(BadRequest(new { message = "Not data" })); } // instantiate a html to pdf converter object var converter = new HtmlToPdf(); // specify the number of seconds the conversion is delayed converter.Options.MinPageLoadTime = 2; // set the page timeout (in seconds) converter.Options.MaxPageLoadTime = 30; converter.Options.MarginTop = 20; converter.Options.MarginBottom = 20; converter.Options.AutoFitWidth = HtmlToPdfPageFitMode.AutoFit; converter.Options.PdfPageSize = PdfPageSize.A4; converter.Options.PdfPageOrientation = PdfPageOrientation.Portrait; foreach (var item in listEmp) { var listData = await _UnitOfWork.KPIRepository.GetKPIReportAsync(year, item.EmpId.Value); var HtmlString = ""; HtmlString += TemplateGenerator.GetKPIHTMLString(listData, year, item.EmpName, item.DepartmentName); if (!string.IsNullOrEmpty(HtmlString)) { PdfDocument doc = converter.ConvertHtmlString(HtmlString); var fileName = string.Format("KPI{0}_{1}.pdf", year.ToString(), item.EmpName.Replace(" ", "_")); var filePath = Path.Combine(folderPath, fileName); doc.Save(filePath); // close pdf document doc.Close(); } } // download the constructed zip //get a list of files string[] filesToZip = Directory.GetFiles(folderPath, "*.*", SearchOption.AllDirectories); //final archive name (I use date / time) string zipFileName = string.Format("KPI{0}_{1:yyyyMMddHHmmss}.zip", year, DateTime.Now); var zipFilePath = Path.Combine(Directory.GetCurrentDirectory(), "Resources", "Report", zipFileName); using (MemoryStream zipMS = new MemoryStream()) { using (ZipArchive zipArchive = new ZipArchive(zipMS, ZipArchiveMode.Create, true)) { //loop through files to add foreach (string fileToZip in filesToZip) { //exclude some files? -I don't want to ZIP other .zips in the folder. if (new FileInfo(fileToZip).Extension == ".zip") { continue; } //exclude some file names maybe? if (fileToZip.Contains("node_modules")) { continue; } //read the file bytes byte[] fileToZipBytes = System.IO.File.ReadAllBytes(fileToZip); //create the entry - this is the zipped filename //change slashes - now it's VALID ZipArchiveEntry zipFileEntry = zipArchive.CreateEntry(fileToZip.Replace(folderPath, "").Replace('\\', '/')); //add the file contents using (Stream zipEntryStream = zipFileEntry.Open()) using (BinaryWriter zipFileBinary = new BinaryWriter(zipEntryStream)) { zipFileBinary.Write(fileToZipBytes); } } } using (FileStream finalZipFileStream = new FileStream(zipFilePath, FileMode.Create)) { zipMS.Seek(0, SeekOrigin.Begin); zipMS.CopyTo(finalZipFileStream); } } if (System.IO.Directory.Exists(folderPath)) { try { Directory.Delete(folderPath, true); } catch (IOException) { Directory.Delete(folderPath, true); } catch (UnauthorizedAccessException) { Directory.Delete(folderPath, true); } } const string contentType = "application/zip"; HttpContext.Response.ContentType = contentType; var result = new FileContentResult(System.IO.File.ReadAllBytes(zipFilePath), contentType) { FileDownloadName = zipFileName }; return(result); //return File(zipFilePath, "application/zip"); } catch (Exception ex) { _UnitOfWork.Dispose(); return(BadRequest(new { message = ex.Message })); } finally { _UnitOfWork.Dispose(); } }