最近几天做下载文件,首先多选文件肯定是要压缩以后下载出来为最佳。然后在网上找的资源都不怎么完整。
所以现在整合成一篇。
这是我看到的ASP.NET下载文件的博文:ASP.NET : 如何将服务端的多个文件打包下载
这是我看到的另外一片文章:ajax无刷新下载文件 虚拟form
//*****************分割线*****************
原本我是想用ajax来做下载文件。一直实现不了。后来查询得知ajax不能用来下载文件。表单提交才可以下载文件。
首先在Nuget里面去下载包 ICSharpCode.SharpZipLib.Zip 。
后台引用 using ICSharpCode.SharpZipLib.Zip; 引入包。
这是我的前端代码:
//下载选中的文件或文件夹(多个)
function DownloadSeveralFiles(_data) {
//定义一个form表单
var form = $("<form>");
//该form表单的样式
form.attr("style", "display:none");
form.attr("target", "");
//POST提交方式
form.attr("method", "post");
//form表单所提交的地址
form.attr("action", "CustomerFileManage.aspx?Func=PackagingDownloadFiles");
//定义一个input标签
var dataSet = $("<input>");
//该标签为不可见
dataSet.attr("type", "hidden");
//设置标签的name属性
dataSet.attr("name", "Data");
//标签的值
dataSet.attr("value", JSON.stringify(_data));
//将表单放置在web中
$("body").append(form);
//将标签放入到form表单里面
form.append(dataSet);
//表单提交
form.submit();
alert("已经添加到下载列表!");
}
这是我的后台代码(分为两段):
//命名
public class NameTransfom : ICSharpCode.SharpZipLib.Core.INameTransform
{
public string TransformDirectory(string name)
{
string rootPath = HttpContext.Current.Server.MapPath(HttpContext.Current.Request.ApplicationPath.ToString()) +
ConfigurationManager.AppSettings["userFileDirectory"].Replace("/", "") + @"\";
return name.Replace(rootPath, "");
}
public string TransformFile(string name)
{
string rootPath = HttpContext.Current.Server.MapPath(HttpContext.Current.Request.ApplicationPath.ToString()) +
ConfigurationManager.AppSettings["userFileDirectory"].Replace("/", "") + @"\";
return name.Replace(rootPath, "");
}
}
以上代码是对压缩文件名的重写、 两个方法里面的代码可以根据自己的逻辑来。
第一个方法是文件夹名的重写、你可能会问。如果不重写呢?
例如这里有一个文件夹路径 D:\Beyond\assets\css
如果不对文件夹进行重写:打开压缩文件里面你看到的第一个文件夹是Beyond 而不是我想要的css。这样会导致用户体验很差。
第二个方法是对文件名的重写。
你需要把 img.png 放入到css文件夹里面去。就需要 重写文件夹的路径为css/img.png
//打包下载文件(zip压缩包)
private void PackagingDownloadFiles()
{
var Data = Request.Params["Data"]; //数据
List<CustomerFiles> cfs = JsonConvert.DeserializeObject<List<CustomerFiles>>(Data);
MemoryStream ms = new MemoryStream();
byte[] buffer = null;
using (ZipFile file = ZipFile.Create(ms))
{
file.BeginUpdate();
file.SetComment("打包的文件");
file.NameTransform = new NameTransfom();
string tmpRootDir = HttpContext.Current.Server.MapPath(HttpContext.Current.Request.ApplicationPath.ToString()).TrimEnd('\\');
foreach (var cf in cfs)
{
string urlPath = tmpRootDir + cf.path + @"\" + cf.Name; //转换成绝对路径
if (cf.FileType == "Folder")
{
//添加文件夹
file.AddDirectory(urlPath);
//*********************
//压缩文件夹里面的内容
//*********************
int CfId = (int)cf.ID; //文件夹ID
int cycleNum = 1; //循环次数
for (int i = 0; i < cycleNum; i++)
{
List<CustomerFiles> sonCfs = CustomerFilesBll.GetFileAndFolder(CfId, this.SessionUserID, "");
if (sonCfs != null)
{
foreach (CustomerFiles sonCf in sonCfs)
{
string sonUrlPath = tmpRootDir + sonCf.path + @"\" + sonCf.Name;
if (sonCf.FileType == "Folder")
{
file.AddDirectory(sonUrlPath);
//实现伪递归
CfId = (int)sonCf.ID;
cycleNum++;
}
else
{
file.Add(sonUrlPath);
}
}
}
}
}
else
{
//添加文件
file.Add(urlPath);
}
}
file.CommitUpdate();
buffer = new byte[ms.Length];
ms.Position = 0;
ms.Read(buffer, 0, buffer.Length);
}
Response.AddHeader("content-disposition", "attachment;filename=Files.zip");
Response.BinaryWrite(buffer);
Response.Flush();
Response.End();
}
当你压缩文件夹的时候,文件夹里面的东西是不会跟着压缩进来。也就是说你的文件夹肯定是空的。
需要自己添加。 如上的:你需要把 img.png 放入到css文件夹里面去。就需要 重写文件夹的路径为css/img.png
当你开始写的时候,可以先省略掉 for (int i = 0; i < cycleNum; i++) 及其内容。 这里面的内容是把文件或文件夹压缩到父文件夹里面去