I have a button in my web page that will export CSV files. There are 5 files in total. When the client clicks the button, the server will create the files, compress them into one ZIP file, then send the ZIP file to the client for download.
I have heard around the forums about SharpZipLab
and DotNetZip
, but I haven't explored any yet. I have also heard using System.IO.Compression
. Which of these methods would you recommend?
I have this code to create the 5 CSV files:
StringBuilder sb = new StringBuilder();
DataTable[] dtCSV =
{
file1BLO.SelectFile1ForCSV(),
file2BLO.SelectFile2ForCSV(),
file3BLO.SelectFile3ForCSV(),
file4BLO.SelectFile4ForCSV(),
file5BLO.SelectFile5ForCSV()
};
for (int i = 0; i <= 4; i++)
{
DataTable dt = dtCSV[i];
foreach (DataRow dr in dt.Rows)
{
string[] fields = dr.ItemArray.Select(field => field.ToString()).ToArray();
sb.AppendLine(string.Join("|", fields));
}
Response.ContentType = "application/text";
Response.AddHeader("content-disposition", "attachment;filename=CAPRES-FILE" +
(i + 1) + "-" + DateTime.Now.ToString("yyyyMMdd-HHmmss") + ".txt");
Response.Output.Write(sb);
Response.Flush();
sb.Clear();
}
Response.End();
EDIT I'm using ASP.NET v4.0.
EDIT 2 Apparently I have System.IO.Compression
, which is weird because I though it is only supported in v4.5. Coincidentally, I don't have System.IO.Packaging
.
With the help of Sachu, we were able to accomplish this requirement. We used
DotNetZip
overSharpZipLib
due to its licensing issues.In facilitate our development of this functionality, I ought to create a program flow based on my requirements:
Zip
formatResponse
Step 0 - Setup Project
Before we start the process, we must prepare the project. This include adding necessary folders and instantiate variables.
First we add a folder to which we will 'temporarily' add the text files. This folder will also be the one that will get compressed. I decided to create the folder in the root directory of the project with the name
CSV
.Now we'll be using the
DotNetZip
library. You can download it here. Add the library to your project references. Then add the using, which isusing Ionic.Zip;
.Then we instantiate the variables such as the
zipFileName
,textFileName
, etc. The names speak for themselves.The data that I'll be using for the text files will be from the
DataTable[]
array, which eachDataTable
corresponding to a specific SQL query.Step 1 - Create Text Files
This is fairly easy. I used a
StringBuilder
to convert the results from theDataTables
. Using this, I then used aStreamWriter
to build the text files themselves.Notice how I used the
textFileNameTemplate
variable. I append the iterator and a.txt
file extension. Therefore, we will have files namedfile1.txt
,file2.txt
,file3.txt
, etc.Step 3 & 4 - Compress The Folder & Send To Client
Now we can proceed with the zipping. We modified the code in Step 2 to accommodate the library.
zip.AddFile(textFileName, @"\");
adds the text file to an archive. The@"\"
means thatDotNetZip
will not create subfolders that lead to the file, e.g. if my file is in this path:C:\User\Documents\...\file1.txt
, the archive would have a similar structure of folders. With@"\"
, the archive will only contain the text file.Also take note of
sb.Clear();
and its position in the code. It's important that it is inside the for loop but after thetextFile.WriteLine(sb.ToString());
line. This makes sure that strings written before are cleared before looping again. This avoid carrying over strings fromFile1
toFile2
, andFile2
toFile3
, and so on.zip.Save(Response.OutputStream);
will directly output the Zip file to theResponse
and does not save the file in the server.Step 5 - Delete Files
This step depends on your requirements. For me, we will delete the generated files. Using
System.IO.File
, we will delete the text files. After theusing ZipFile zip = new ZipFile())
code block, we'll add the following lines:My code probably isn't the most optimized code. But it works. If anyone can suggest a better code that would be great. But for now, I'll be using this code. Many thanks! Especially to Sachu, a really helpful person.