iT邦幫忙

0

asp.net mvc ZipArchive多個檔案壓縮下載

各位先進好,想要請教如何實作多個檔案壓縮下載的功能,主要參考實作文章如下
1.https://www.jitbit.com/alexblog/278-returning-a-zip-file-from-aspnet-mvc-actions---in-pure-net/
2.https://dotblogs.com.tw/gelis/2016/09/04/161341
實作以下靜態的範例是可以運作的沒問題

[HttpPost]
public ActionResult ExportPapersZip(PaperViewModel PV)
{
    string sourceFile1 = @"K:\程式專案\ASPNET\Submission1\Submission1\Areas\Users\SubmissionFiles\1\14\RUP\1.docx";
    string sourceFile2 = @"K:\程式專案\ASPNET\Submission1\Submission1\Areas\Users\SubmissionFiles\1\14\RUP\2.docx";

    FileStream f1 = new FileStream(sourceFile1, FileMode.Open, FileAccess.Read);
    FileStream f2 = new FileStream(sourceFile2, FileMode.Open, FileAccess.Read);

    using (var ms = new MemoryStream())
    {
        using (var archive =
            new System.IO.Compression.ZipArchive(ms, ZipArchiveMode.Create, true))
        {
            byte[] bytes1 = fileSrv.BinaryReadToEnd(f1);
            var zipEntry = archive.CreateEntry("1.docx",
                CompressionLevel.Fastest);
            using (var zipStream = zipEntry.Open())
            {
                zipStream.Write(bytes1, 0, bytes1.Length);
            }
            
            byte[] bytes2 = fileSrv.BinaryReadToEnd(f2);
            var zipEntry2 = archive.CreateEntry("2.docx",
                CompressionLevel.Fastest);

            using (var zipStream = zipEntry2.Open())
            {
                zipStream.Write(bytes2, 0, bytes2.Length);
            }
        }
        return File(ms.ToArray(), "application/zip", "Images.zip");
    }
}

最終想要實作的功能為多個檔案壓縮下載,就是從DB抓取N筆資料後,然後統一壓縮打包下載

問題1.範例的每個檔案都有一組記錄檔案資訊的變數,然後再寫入Memory,最後再統一輸出成壓縮檔。當我從DB抓取N筆資料跑廻圈時,要如何即時動態的產生這些儲存資料的變數資訊呢?

string sourceFile2 = @"K:\程式專案\ASPNET\Submission1\Submission1\Areas\Users\SubmissionFiles\1\14\RUP\2.docx";
FileStream f2 = new FileStream(sourceFile2, FileMode.Open, FileAccess.Read);
byte[] bytes2 = fileSrv.BinaryReadToEnd(f2);
var zipEntry2 = archive.CreateEntry("2.docx",
    CompressionLevel.Fastest);

using (var zipStream = zipEntry2.Open())
{
    zipStream.Write(bytes2, 0, bytes2.Length);
}

問題2.假定問題1解決了,依目前範例產生出來的壓縮檔只有一層的目錄結構,如果我想要在壓縮檔裡將檔案分類存放,該如何處理呢?例如想要產生以下目錄資料

SubmissionFiles\1\14\RUP\2.docx
SubmissionFiles\1\14\RUP\3.docx
SubmissionFiles\1\15\RUP\2.docx
SubmissionFiles\1\15\RUP\3.docx
SubmissionFiles\2\14\RUP\2.docx
SubmissionFiles\2\14\RUP\3.docx
SubmissionFiles\2\15\RUP\2.docx
SubmissionFiles\2\15\RUP\3.docx

先感謝各位先進指教了,謝謝

1 個回答

1
浩瀚星空
iT邦大師 1 級 ‧ 2020-01-15 09:14:25
最佳解答

我用的是php的ZipArchive。
不過理論上操作原理因該一樣。

在其 ZipArchive 在內置指定檔名時,其檔名是可以給它目錄的。
這樣建出來的就是有目錄了。

不過我對asp的物件操作不了解。你就往這方面去研究。
目前目測因該是

CreateEntry("1.docx"

這邊才對。將其「1.docx」改成「/test/1.docx」就會有對應的test目錄了。

leo226 iT邦新手 5 級 ‧ 2020-01-15 17:26:08 檢舉

感謝分享,參考後,自己改一下有試出來多檔匯出的功能了~謝謝

List<ConferencePaperFilesViewModel> cpfVM = new List<ConferencePaperFilesViewModel>();
cpfVM = fileSrv.GetConferencePaperFilesList(PV.ConferenceId);
FileStream sFile;
byte[] toBytes;
using (var ms = new MemoryStream())
{
    using (var archive = new System.IO.Compression.ZipArchive(ms, ZipArchiveMode.Create, true))
    {
        cpfVM.ForEach(x =>
        {
            sFile = new FileStream(x.SysPath + x.OriginalFileName, FileMode.Open, FileAccess.Read);
            toBytes = fileSrv.BinaryReadToEnd(sFile);
            var zipEntry = archive.CreateEntry(x.FilePath, CompressionLevel.Fastest);
            using (var zipStream = zipEntry.Open())
            {
                zipStream.Write(toBytes, 0, toBytes.Length);
            }
        });
    }
    return File(ms.ToArray(), "application/zip", "Images.zip");
}

我要發表回答

立即登入回答