Possible? Convert DataTable to MemoryStream then to CSV then ZIP it.

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • yoda
    Contributor
    • Dec 2006
    • 291

    Possible? Convert DataTable to MemoryStream then to CSV then ZIP it.

    Hi everyone I'm fairly new to the C# programming language and was wonder if it is possible to Convert a DataTable to a MemoryStream then output that into a CSV file and then Zip that file.

    Also note I know how to get to the CSV File part but don't know how to take that file and Zip it without creating it on a clients computer and reading it in and Zipping it.

    But this Zip file must be created and zipped on the webserver and then Zip file can be downloaded as an attachment.

    A little more context to the situation. What I'm basically doing is creating a CSV file from a select statement from a database but only when the user clicks on a button on the ASP page.

    Here's the code I use to just make a csv file.

    Note: In this code there is no MemoryStream, but I do know how to create a CSV that way.
    Code:
    try
                {
                    GetSqlData(); //get sql data for the csv.
    
                    HttpContext context = HttpContext.Current;
                    context.Response.Clear();
    
                    foreach (DataColumn column in FullDT.Columns)
                    {
                        context.Response.Write(column.ColumnName.ToString() + ",");
                    }
                    context.Response.Write(Environment.NewLine);
    
                    foreach (DataRow row in FullDT.Rows)
                    {
                        for (int i = 0; i < row.ItemArray.Length; i++)
                        {
                            string rowText = row.ItemArray[i].ToString();
                            if (rowText.Contains(","))
                            {
                                rowText = rowText.Replace(",", "/");
                            }
    
                            context.Response.Write(rowText + ",");
                        }
                        context.Response.Write(Environment.NewLine);
                    }
    
                    context.Response.ContentType = "text/csv";
                    context.Response.AppendHeader("Content-Disposition", "attachment; filename="+ OutputFileName +".csv");
                    context.Response.End();
                }
                catch (Exception ex)
                {
                    Debug.WriteLine("Can Not Generate CSV File");
                    throw ex;
                }
    Is this even possible with out the help of an additional library outside of C#?

    Thanks,

    Yoda.
  • yoda
    Contributor
    • Dec 2006
    • 291

    #2
    So I wasn't able to use do this without the aid of a external library because I was using .NET 2.0. But with the external SharpZipLib Library I was able to create this code fairly easily.

    Basic Idea is to place the datatable into a memory stream like so:
    Code:
    MemoryStream mem = new MemoryStream(); // create a memory stream to hold the datatable.
                StreamWriter sw = new StreamWriter(mem); // write the datatable to the memory stream.
    
                //Loop through the columns and rows and add a comma to the end for the csv.
                foreach (DataColumn column in Datatbl.Columns)
                {
                    sw.Write(column.ColumnName.ToString() + ",");
                }
    
                sw.WriteLine();
    
                foreach (DataRow row in Datatbl.Rows)
                {
                    for (int i = 0; i < row.ItemArray.Length; i++)
                    {
                        string rowText = row.ItemArray[i].ToString();
                        if (rowText.Contains(","))
                        {
                            rowText = rowText.Replace(",", "/");
                        }
    
                        sw.Write(rowText + ",");
                    }
                    sw.WriteLine();
                }
                sw.Flush();
                return mem;
    And then use the External Library to help you place the file or files into the zip file for download.

    Code:
    Stream fs = null; // create the streams so they can be closed if an expection is caught.
                ZipOutputStream zipOutputStream = null;
    
                try
                {
                    Response.ContentType = "application/zip";
                    // If the browser is receiving a mangled zipfile, IIS Compression may cause this problem. Some members have found that
                    //    Response.ContentType = "application/octet-stream"     has solved this. May be specific to Internet Explorer.
    
                    Response.AppendHeader("content-disposition", "attachment; filename=\"" + OutputFileName + ".zip\"");
                    Response.CacheControl = "Private";
                    Response.Cache.SetExpires(DateTime.Now.AddMinutes(3)); // or put a timestamp in the filename in the content-disposition
    
    
    
                    zipOutputStream = new ZipOutputStream(Response.OutputStream);
                    zipOutputStream.SetLevel(3); //0-9, 9 being the highest level of compression
    
                    fs = (Stream)GetStream();	// or any suitable inputstream
                    fs.Position = 0;
    
                    ZipEntry entry = new ZipEntry("" + OutputFileName + ".csv");
                    entry.Size = fs.Length;
                    // Setting the Size provides WinXP built-in extractor compatibility,
                    //  but if not available, you can set zipOutputStream.UseZip64 = UseZip64.Off instead.
    
                    zipOutputStream.PutNextEntry(entry);
    
                    byte[] bytes = new byte[fs.Length];
                    int numBytesToRead = (int)fs.Length;
    
                    while (numBytesToRead > 0)
                    {
                        int n = fs.Read(bytes, 0, 4096);
                        if (n == 0)
                        {
                            break;
                        }
                        zipOutputStream.Write(bytes, 0, n);
                        numBytesToRead -= n;
                        Response.Flush();
                    }
                }
                catch (Exception ex)
                {
                    throw ex;
                }
    
                finally
                {
                    fs.Close();
                    zipOutputStream.Close();
    
                    Response.Flush();
                    Response.End();
                }
    I used the SharpZipLib site as a reference: http://wiki.sharpdevelop.net/SharpZi...hment_in_IIS_2

    As well as used the Stream.Read() on MSDN to help me figure out how to read the stream and put it into the zip file.

    Comment

    • PsychoCoder
      Recognized Expert Contributor
      • Jul 2010
      • 465

      #3
      Thanks for sharing your solution. If someone comes along with a similar issue there's a possible solution available.

      Comment

      Working...