在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();
//遍历表头在exal表格中
for (int i = ; i < exalHead.Length; i++)
{
//报表的头部
col.CreateCell(i).SetCellValue(exalHead[i]);
}
int a = ;
//遍历表数据
foreach (var item in model)
{
var row = sheet.CreateRow(a);
row.CreateCell().SetCellValue(item.TAISYOU_GTD);
row.CreateCell().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 > )
{
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 > )
{
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, );
//参数为文件存放路径,下载的文件格式,文件名字
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, , 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, , 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 == )
{
//如果是空目录则记录空目录
this.paths.Add(rootPath);
}
}

好啦,就写到这里啦,嘿嘿,项目最后一个就是下载的啦,昨天上午已完成,坐等接下来的任务啦,加油加油,我不知道的太多啦,希望友友们知道的帮忙哈。。。

上一篇:bzoj 3223/tyvj 1729 文艺平衡树 splay tree


下一篇:OI数学 简单学习笔记