在MVC中實現和網站不同服務器的批量文件下載以及NPOI下載數據到Excel的簡單學習


                              嘿嘿,我來啦,最近忙啦幾天,使用MVC把應該實現的一些功能實現了,說起來做項目,實屬感覺蠻好的,即可以學習新的東西,又可以增加自己之前知道的知識的鞏固,不得不說是雙豐收啊,其實這周來就開始面對下載在掙扎啦,不知道從哪下手,而且自己針對一個文件下載的小小練習還是寫過的,但是和項目中的下載完全就是兩個世界,所以我只能抱着學習的心情查找資料啦,剛開始由於leader沒有說怎么個下載的辦法,我只能自己看些有關下載的資料啦,周一只是在猜測的學習,然后通過詢問各路大神。就新學習了NOPI,當我看到Nopi下載表格數據的時間,我發現NOPI好優越啊,我之前還不知道的那,所以簡單的學習一下的啦。

                              一.NPOI的簡單學習

                              下面就簡單的總結一個最簡單的表格下載方法:

        public static void GetDownLoaMonthExal(List<UserModel> model)
        {
            //表頭
            string[] exalHead = { "用戶名", "密碼"};
            var workbook = new HSSFWorkbook();
            //表格顯示的名字
            var sheet = workbook.CreateSheet("報表");
            //記得在這里創建表頭部對象,不能每次創建
            //sheet.CreateRow(0).CreateCell(0).SetCellValue(exalHead[i])
            var col = sheet.CreateRow(0);
            //遍歷表頭在exal表格中
            for (int i = 0; i < exalHead.Length; i++)
            {
                //報表的頭部
                col.CreateCell(i).SetCellValue(exalHead[i]);
            }
            int a = 1;
            //遍歷表數據
            foreach (var item in model)
            {
                var row = sheet.CreateRow(a);
                row.CreateCell(0).SetCellValue(item.TAISYOU_GTD);
                row.CreateCell(1).SetCellValue(item.TEIKEI_CNT_1);
                a++;
            }
            var file = new FileStream(AppDomain.CurrentDomain.BaseDirectory + "1.xls", FileMode.Create);
            workbook.Write(file);
            file.Close();
        }

                                上面就是簡單的把網頁上面的數據下載到Excel文件中,僅僅限制於簡單的表格,並沒有設置表格的樣式以及顏色的;不過說起來使用NPOI,首先要下載NPOI,或者添加Nuget包即可,然后添加引用NPOI.HSSF.UserModel的引用,我們即可使用類HSSFWorkbook,然后創建對象,設計我們的表頭和表數據。

                  好啦下面總結一下在MVC中實現和網站不同服務器的批量文件下載,其實周三Lender告訴我要實現這樣的一個下載,我就不知打所措啦,在網上找了一些資料,感覺好多,但是有些亂,而且大家都理解為是在網站的根目錄,這樣據友友說並沒有那么難的啦,我不知道怎么去實現,后來只能求助或者仍然尋找資料啦,昨天我是這樣解決的,就總結一下吧。

                                二.下載服務器上Excel文件保存在本機

                               首先我們會涉及到兩個View頁面,在這里我舉例的是Index和ShowDl,首先在Index頁面上面有個要下載的按鈕,我們點擊按鈕即可跳到下一個頁面,即ShowDl,代碼如下:

        //第一個參數為顯示的文本,第二個參數為Action的名字,第三個為Controller的名字
        @Html.ActionLink("下載文件", "Show", "Download")

                                當我們跳轉到ShowDl的Action之后,我們需要查詢我們需要下載的文件在此頁面上面,即代碼如下:

        public ActionResult ShowDl()
        {
            //文件路徑配置在webconfig中的appconfig中,因此獲取文件路徑即可
            string filePath = ConfigurationManager.AppSettings["Download"]; 
            //獲取文件的絕對路徑以及文件名
            string[] fPath = Directory.GetFiles(filePath);
            List<string> fileName = new List<string>();
            //僅僅獲取文件名
            foreach (var item in fPath)
            {
                fileName.Add(Path.GetFileName(item));
            }
            //創建一個ViewData,在view上面遍歷文件名字
            ViewData["fileName"] = fileName;
            return View();
        }

                               View頁面的顯示文件名字如下:

<table>
    @{ List<string> fileName = ViewData["fileName"] as List<string>;}
    @if (fileName.Count > 0)
    {
        foreach (string item in fileName)
        {
            <tr>
                <td>文件名:</td>
                <td>@item</td>
                <td><input type="checkbox" class="dDown" value="@item" />選擇下載</td>
            </tr>
        }
    }
    <tr>
        <td><input type="button" id="download" value="下載文件" onclick="Download()" /></td>
        <td><input type="button" id="allCheck" value="全選" onclick="checkAll()" /></td>
    </tr>
</table>
<script>
    function Download() {
        var str = [];//定義一個數組
        $('.dDown:checked').each(function () {//遍歷每一個名字為dol的復選框,其中選中的執行函數
            str.push($(this).val());//將選中的值添加到數組str中
        });
        $.ajax({
            type: "POST",
            url: "/Home/DownloadFile",
            contentType: "application/json",
            data: JSON.stringify(str)
        });
    };
    function checkAll() {
        $('.dDown').each(function () {
            $(this).attr("checked", "checked"); //設置屬性為全部選中
        });
    };
</script>

                                 此時我們選擇了在ShowDl頁面上顯示的所有文件的名字,然后我們在此頁面上面設置了兩個按鈕,一個是點擊按鈕現在文件,一個是全選,當點擊下載按鈕時間,用的是ajax直接異步跳到下面的HomeController中DownloadFile,代碼如下:

        [HttpPost]
        public FileResult DownloadFile(List<string> list)
        {
            //獲取服務器中的文件路徑
            string filePath = ConfigurationManager.AppSettings["Download"];
            //要壓縮的文件夾,把需要打包的文件存放在此文件夾
            string dPath = @"E:\文件";
            //壓縮后的文件存放路徑
            string destFile = @"E:\文件\Download";
            if (list.Count > 1)
            {
                foreach (string fileName in list)
                {
                    string sourceFileName = Path.Combine(filePath, fileName) + ".xls";
                    string destFileName = Path.Combine(dPath, fileName) + ".xls";
                    //true為覆蓋同名文件
                    System.IO.File.Copy(sourceFileName, destFileName, true);
                }
                FileDown fileDown = new FileDown();
                //返回壓縮后的文件提供下載
                fileDown.ZipFileFromDirectory(dPath, destFile, 9);
                //參數為文件存放路徑,下載的文件格式,文件名字
                return File(destFile, "application/octet-stream", Path.GetFileName(destFile));
            }
            else
            {
                //單個文件下載,不需要打包
                foreach (string fileName in list)
                {
                    string sourceFileName = Path.Combine(filePath, fileName) + ".xls";
                    string destFileName = Path.Combine(dPath, fileName) + ".xls";
                    System.IO.File.Copy(sourceFileName, destFileName, true);
                }
                //參數為文件存放路徑,下載的文件格式,文件名字
                return File(destFile, "application/csv", Path.GetFileName(destFile));
            }
        }

                             上面是在Action中實現了下載,其實這個友友也幫啦好多忙的,嘿嘿,首先說在WebConfig中配置但是在上面中調用了一位友友修改的方法,我就直接拿來用啦,蠻好用的,嘿嘿,而且我看了ZipFile類中的幾個方法,下面是那個方法,我也貼出來啦,嘿嘿,又有看到不要介意哈。

 /// 所有文件緩存  
        List<string> files = new List<string>();

        /// 所有空目錄緩存  
        List<string> paths = new List<string>();  


        /// <summary>  
        /// 壓縮目錄(包括子目錄及所有文件)  
        /// </summary>  
        /// <param name="rootPath">要壓縮的根目錄</param>  
        /// <param name="destinationPath">保存路徑</param>  
        /// <param name="compressLevel">壓縮程度,范圍0-9,數值越大,壓縮程序越高</param>  
        public  void ZipFileFromDirectory(string rootPath, string destinationPath, int compressLevel)
        {
            GetAllDirectories(rootPath);
            //得到當前路徑的位置,以備壓縮時將所壓縮內容轉變成相對路徑。  
            string rootMark = rootPath + "\\";
            //Crc32校驗
            Crc32 crc = new Crc32();
            //zip輸出類
            ZipOutputStream outPutStream = new ZipOutputStream(File.Create(destinationPath));
            // 0-9程序的壓縮,設置壓縮程度
            outPutStream.SetLevel(compressLevel); 
            //將文件讀入壓縮流
            foreach (string file in files)
            {
                FileStream fileStream = File.OpenRead(file);
                byte[] buffer = new byte[fileStream.Length];
                fileStream.Read(buffer, 0, buffer.Length);
                //設置文件的一些參數
                ZipEntry entry = new ZipEntry(file.Replace(rootMark, string.Empty));
                entry.DateTime = DateTime.Now;
                entry.Size = fileStream.Length;
                fileStream.Close();
                //計算Crc32檢驗碼
                crc.Reset();
                crc.Update(buffer);
                //設置校驗碼
                entry.Crc = crc.Value;
                //將當前文件的zip文件流寫入輸出流
                outPutStream.PutNextEntry(entry);
                outPutStream.Write(buffer, 0, buffer.Length);
            }
            this.files.Clear();
            foreach (string emptyPath in paths)
            {
                ZipEntry entry = new ZipEntry(emptyPath.Replace(rootMark, string.Empty) + "/");
                outPutStream.PutNextEntry(entry);
            }
            this.paths.Clear();
            outPutStream.Finish();
            outPutStream.Close();
            GC.Collect();
        }

        /// <summary>  
        /// 取得目錄下所有文件及文件夾,分別存入files及paths  
        /// </summary>  
        /// <param name="rootPath">根目錄</param>  
        private void GetAllDirectories(string rootPath)
        {
            //獲取所有的子目錄  
            string[] subPaths = Directory.GetDirectories(rootPath);
            foreach (string path in subPaths)
            {
                //找到子目錄並將當前目錄的文件名存入List  
                GetAllDirectories(path);
            }
            string[] files = Directory.GetFiles(rootPath);
            foreach (string file in files)
            {
                //將當前目錄中的所有文件全名存入文件list  
                this.files.Add(file);
            }
            //判斷是否是空目錄  
            if (subPaths.Length == files.Length && files.Length == 0)
            {
                //如果是空目錄則記錄空目錄 
                this.paths.Add(rootPath); 
            }
        }

                                  好啦,就寫到這里啦,嘿嘿,項目最后一個就是下載的啦,昨天上午已完成,坐等接下來的任務啦,加油加油,我不知道的太多啦,希望友友們知道的幫忙哈。。。

                               


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM