嘿嘿,我來啦,最近忙啦幾天,使用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); } }
好啦,就寫到這里啦,嘿嘿,項目最后一個就是下載的啦,昨天上午已完成,坐等接下來的任務啦,加油加油,我不知道的太多啦,希望友友們知道的幫忙哈。。。