最近做项目有一个这样的需求,导出列表上的数据,若勾选了多个则将所有数据导出文件打包到一个压缩包中导出,找了很多实现方式,最终实现的方式为:多个文件分别导出到指定文件夹,然后再将所有文件写入到压缩包中,最后再将所有文件删除掉,然后压缩包再以流的形式输出到浏览器,最后删除掉临时存放的压缩包文件,大概流程就是这样,下面具体讲解代码的实现过程:

文件转为inputstream java 文件转为压缩包_System

文件转为inputstream java 文件转为压缩包_System_02

1  public IActionResult ExportReceiveReport(string objectId)
 2         {
 3             string[] dataArr = objectId.Split(',');
 4 
 5             bool isZip = false;
 6             if (dataArr.Length > 1)
 7             {
 8                 isZip = true;
 9             }
10             List<string> fileList = new List<string>();
11             string savePath = AppDomain.CurrentDomain.BaseDirectory;
12             string templateFilePathName = _webHostEnvironment.WebRootPath + "//Template//ReceiveFile.xls";
13             System.IO.MemoryStream mStream = new MemoryStream();
14             string fixName = DateTime.Now.ToString("yyyyMMddHHmmss");
15             for (int i = 0; i < dataArr.Length; i++)
16             {
17                 DataTable dt = ReportServices.GetReceiveReport(dataArr[i]);
18                 dt.TableName = "Receive";
19                 //下载
20                 mStream = ReportServices.OutModelFileToStream(dt, templateFilePathName, "营收月报");
21                 if (isZip)
22                 {
23                     string savePath2 = savePath + "Doc//";
24                     if (!Directory.Exists(savePath2))//如果不存在就创建file文件夹
25                     {
26                         Directory.CreateDirectory(savePath2);
27                     }
28                     string FileNames = savePath2 + fixName + i + "营收月报.xls";
29                     if (System.IO.File.Exists(FileNames))
30                     {
31                         System.IO.File.Delete(FileNames);
32                     }
33 
34                     FileStream fs = new FileStream(FileNames, FileMode.Create, FileAccess.Write);
35                     BinaryWriter w = new BinaryWriter(fs);
36                     w.Write(mStream.ToArray());
37                     fs.Close();
38                     fs.Dispose();
39                     mStream.Close();
40                     fileList.Add(FileNames);
41                 }
42             }
43             if (!isZip)
44             {
45                 //客户端保存的文件名  
46                 string fileName = "营收月报" + fixName + ".xls";
47                 return File(mStream.ToArray(), "application/vnd.ms-excel", fileName);
48             }
49             else
50             {
51                 string saveZip = savePath + "Zip//";
52                 if (!Directory.Exists(saveZip))//如果不存在就创建file文件夹
53                 {
54                     Directory.CreateDirectory(saveZip);
55                 }
56                 string fsUrl = saveZip + "营收月报.zip";
57                 
58                 //压缩包里面写入文件
59                 ZipHelper.ZipFile(fsUrl, fileList);
60                 var fileInfo = new FileInfo(fsUrl);
61                 MemoryStream zipstream = new System.IO.MemoryStream();
62                 using (var fs = new FileStream(fileInfo.FullName, FileMode.Open))
63                 {
64                     fs.CopyTo(zipstream);
65                     fs.Close();
66                     fs.Dispose();
67                 }
68                 if (System.IO.File.Exists(fsUrl))
69                 {
70                     System.IO.File.Delete(fsUrl);
71                 }
72                 return File(zipstream.ToArray(), "application/x-zip-compressed", "营收月报.zip");
73             }
74         }

View Code

调用的生成压缩包文件帮助类对应方法也分享出来:

文件转为inputstream java 文件转为压缩包_System

文件转为inputstream java 文件转为压缩包_System_02

using ICSharpCode.SharpZipLib.Zip;
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;

namespace myProject
{
    public static class ZipHelper
    {
        static ZipHelper()
        {
            //消除文件名中文乱码
            ICSharpCode.SharpZipLib.Zip.ZipStrings.CodePage = Encoding.UTF8.CodePage;
            //旧版本
            //ICSharpCode.SharpZipLib.Zip.ZipConstants.DefaultCodePage = Encoding.UTF8.CodePage;
        }

        #region 压缩文件
        /// <summary>
        /// 压缩文件
        /// </summary>
        /// <param name="dest">目的文件,如: c:\test.zip</param>
        /// <param name="fileAbsPaths">文件来源列表,如: c:\test.txt,d:\test.db</param>
        public static void ZipFile(string dest, List<string> fileAbsPaths)
        {
           
            using (var fs = new FileStream(dest, FileMode.Create))
            {
                var zipOutputStream = new ZipOutputStream(fs);
                foreach (var i in fileAbsPaths)
                {
                    ZipSingleFile(zipOutputStream, i);
                    //删除源文件
                    File.Delete(i);
                };
                zipOutputStream.Finish();
                zipOutputStream.Close();
            }
            
        }

        private static void ZipSingleFile(ZipOutputStream zipOutputStream, string filePath, string folderName = "")
        {
            var fileInfo = new FileInfo(filePath);
            string fileName = Path.Combine(folderName, fileInfo.Name);
            ZipEntry zipEntry = new ZipEntry(Encoding.UTF8.GetString(Encoding.UTF8.GetBytes(fileName)));
            zipEntry.DateTime = DateTime.Now;
            zipEntry.Size = fileInfo.Length;
            zipOutputStream.PutNextEntry(zipEntry);
            using (var fs = new FileStream(fileInfo.FullName, FileMode.Open))
            {
                fs.CopyTo(zipOutputStream);
                fs.Close();
            }
        }

        private static void ZipSingleFolder(ZipOutputStream zipOutputStream, string folderPath, string folderName = "")
        {
            string[] directorys = Directory.GetDirectories(folderPath);
            foreach (var i in directorys)
            {
                var tmp = Path.Combine(folderName, new DirectoryInfo(i).Name);
                ZipSingleFolder(zipOutputStream, i, tmp);
            }
            string[] files = Directory.GetFiles(folderPath);
            foreach (var i in files)
            {
                ZipSingleFile(zipOutputStream, i, folderName);
            }
        }

        /// <summary>
        /// 递归压缩文件夹
        /// </summary>
        /// <param name="dest">目的文件名称,如: c:\test.zip</param>
        /// <param name="folderPaths">压缩的目录列表,如: c:\test,d:\jack</param>
        public static void ZipFolder(string dest, params string[] folderPaths)
        {
            using (var fs = new FileStream(dest, FileMode.Create))
            {
                var zipOutputStream = new ZipOutputStream(fs);
                foreach (var i in folderPaths)
                {
                    ZipSingleFolder(zipOutputStream, i, new DirectoryInfo(i).Name);
                };
                zipOutputStream.Finish();
                zipOutputStream.Close();
            }
        }

        /// <summary>
        /// 递归压缩文件夹里的内容,不包含文件夹本身(区别:ZipFolder() )
        /// </summary>
        /// <param name="dest">目的文件名称,如: c:\test.zip</param>
        /// <param name="folderPath">压缩的目录列表,如: c:\test</param>
        public static void ZipFolderContent(string dest, string folderPath)
        {
            using (var fs = new FileStream(dest, FileMode.Create))
            {
                var zipOutputStream = new ZipOutputStream(fs);
                string[] directorys = Directory.GetDirectories(folderPath);
                foreach (var i in directorys)
                {
                    var tmp = Path.Combine(new DirectoryInfo(i).Name);
                    ZipSingleFolder(zipOutputStream, i, tmp);
                }
                string[] files = Directory.GetFiles(folderPath);
                foreach (var i in files)
                {
                    ZipSingleFile(zipOutputStream, i);
                }
                zipOutputStream.Finish();
                zipOutputStream.Close();
            }
        }
        #endregion

        #region 解压缩文件
        /// <summary>
        /// 解压缩文件到指定文件夹
        /// </summary>
        /// <param name="srcZipFile">源压缩文件</param>
        /// <param name="destDir">目标文件夹</param>
        /// <returns></returns>
        public static void UnZipFile(string srcZipFile, string destDir)
        {
            if (!Directory.Exists(destDir)) Directory.CreateDirectory(destDir);
            using (var stream = new ZipInputStream(File.OpenRead(srcZipFile.Trim())))
            {
                ZipEntry entry;
                while ((entry = stream.GetNextEntry()) != null)
                {
                    if (entry.IsDirectory)
                    {
                        //目录,创建新目录即可
                        var path = Path.Combine(destDir, entry.Name);
                        if (!Directory.Exists(path)) Directory.CreateDirectory(path);
                        continue;
                    }
                    else if (entry.IsFile)
                    {
                        //文件,将文件解压缩
                        var path = Path.Combine(destDir, entry.Name);
                        var dir = Path.GetDirectoryName(path);
                        if (!Directory.Exists(dir)) Directory.CreateDirectory(dir);
                        using (var fs = File.Create(path))
                        {
                            int size = 2048;
                            byte[] data = new byte[2048];
                            while (true)
                            {
                                size = stream.Read(data, 0, data.Length);
                                if (size > 0)
                                {
                                    fs.Write(data, 0, size);
                                }
                                else
                                {
                                    break;
                                }
                            }
                        }
                    }
                }
            }
        }
        #endregion

    }
}

View Code

基本实现原理就是这样,如果大家有更好的方式欢迎下方留言交流~

生命不息,奋斗不止!只要相信,只要坚持,只要你真的是用生命在热爱,那一定是天赋使命使然,那就是一个人该坚持和努力的东西,无论梦想是什么,无论路有多曲折多遥远,只要是灵魂深处的热爱,就会一直坚持到走上属于自己的舞台!