無實體檔案,並多檔案一併打包下載,使用 DotNetZip 的解決方案

  • 9985
  • 0
  • 2016-06-09

如何將 DataTable 的每筆 row 的資料,寫成存放在記憶體中的 txt 格式檔案,並多檔案一併打包下載,使用 DotNetZip 的解決方案~
前陣子有個需求,原先同仁的功能,可讓 User 將 DB 的資料寫入 txt 檔,再存放至 Server 資料夾中,到時再一併打包下載到 Cilent 端。
經過溝通後,希望能做到,User 下載時,才產生檔案 (但非實體資料,而是放在記憶體中的檔案),再透過 Zip 元件將記憶體中的多筆檔案一併打包的新方法。以下是這需求的解決方案:

前言

前陣子有個需求,原先同仁的功能,可讓 User 將 DB 的資料寫入 txt 檔,再存放至 Server 資料夾中,到時再一併打包下載到 Cilent 端。

經過溝通後,希望能做到,User 下載時,才產生檔案 (但非實體資料,而是放在記憶體中的檔案),再透過 Zip 元件將記憶體中的多筆檔案一併打包的新方法。

以下是這需求的解決方案,做個紀錄:

構想圖

實作

protected void Button1_Click(object sender, EventArgs e)
{
    //================================================
    //
    //  1. 加入參考 Ionic.Zip
    //  2. using Ionic.Zip;
    //  參考資料 http://dotnetzip.codeplex.com/
    //  參考資料 http://blog.miniasp.com/post/2009/01/11/Introduce-SharpZipLib-and-DotNetZip-Library-for-NET.aspx#continue
    //
    //================================================

    Response.Clear();
    Response.BufferOutput = false;

    ZipFile zip = new ZipFile();

    //創造 DataTable,準備來接資料
    DataTable sourceDt = new DataTable();
    sourceDt.Columns.Add("EMPNO", typeof(string));
    sourceDt.Columns.Add("LOGIN_TM", typeof(string));
    sourceDt.Columns.Add("LOGIN_IP", typeof(string));
    sourceDt.Columns.Add("LOGIN_ERR", typeof(string));

    //產生幾筆row先寫在datatable
    for (int i = 0; i < 10; i++)
    {
        DataRow dr = sourceDt.NewRow();
        dr["EMPNO"] = i.ToString();
        dr["LOGIN_TM"] = "a" + i.ToString() + "測試1";
        dr["LOGIN_IP"] = "b" + i.ToString() + "測試2";
        dr["LOGIN_ERR"] = "c" + i.ToString() + "測試3";
        sourceDt.Rows.Add(dr);
    }

    StringBuilder str = new StringBuilder();

    //增加 TXT 檔案至壓縮檔中
    for (int i = 0; i < sourceDt.Rows.Count; i++)
    {
        // zip.AddEntry(檔案名稱 , 內容 , 編碼)
        zip.AddEntry(sourceDt.Rows[i][0].ToString() + ".txt", sourceDt.Rows[i][1].ToString() + "-" + sourceDt.Rows[i][2].ToString(), Encoding.Default);
    }

    //設定下載的 ZIP 檔名
    string archiveName = String.Format("XX{0}.zip", DateTime.Now.ToString("yyyy-MM-dd-HHmmss"));
    Response.ContentType = "application/zip";
    Response.AddHeader("content-disposition", "filename=" + archiveName);

    zip.Save(Response.OutputStream);
    Response.Close();
}

結果圖

結語

其實在處理這個問題時,有很多不同的方法;

EX:如何將 DataTable 的每筆 row 的資料,寫成 txt 格式的檔案,再轉成 FileStream,再將這些 FileStream,用 SharpZipLib 一併打包給 User 下載。

花了不少時間,追根還是觀念不熟悉,需要繼續加強自己的基礎。當天自己找出答案後,就留下噗浪的留言....

困惱三天的問題,今天下班前終於解決了;剛剛再來Google一下,看到保哥的文章,馬上看到解法...
回頭想想碰到問題時,依問題反向思考、反向搜尋,或者更加有效率阿

以上的示範,寫法、觀念上不足之處,請大家見諒,也麻煩大家不吝給予指教,感恩。

Source Code:NonPathFileDownLoad.zip

參考資料

1. Will 保哥 - 介紹幾款好用的壓縮函示庫:SharpZipLib 與 DotNetZip

2. DotNetZip Library - DotNetZip Examples