需求: 需要將用戶後買的圖片批量下載打包壓縮,並且分不同的文件夾(因:購買了多個用戶的圖片情況) 文章中用到了一個第三方的類庫,Nuget下載 SharpZipLib 目前用的 1.1的版本 效果: 伺服器目錄展示: 裡面對應目錄層級的圖片 前端提交POST請求案例: function DownAl ...
需求:
需要將用戶後買的圖片批量下載打包壓縮,並且分不同的文件夾(因:購買了多個用戶的圖片情況)
文章中用到了一個第三方的類庫,Nuget下載 SharpZipLib 目前用的 1.1的版本
效果:
伺服器目錄展示:
裡面對應目錄層級的圖片
前端提交POST請求案例:
function DownAllFile(filename, imgUrl, down) {
var urlStr = "";
//url字元串 (示例數據) (註意!: 使用 '逗號' 分隔文件名和 url 地址,使用 '$' 分隔 每個文件.)
if (filename != '' && imgUrl != '')
urlStr = filename + "," + imgUrl;
//form提交
var form = $('<form>');
form.attr('style', 'display:none');
form.attr('target', '');
form.attr('method', 'post');
form.attr('action', '/PayStripe.ashx?method=DownLoadImage'); //這裡寫對應的方法地址
var name1 = $('<input>');
name1.attr('type', 'text');
name1.attr('name', 'urlStr');
name1.attr('value', urlStr); //文件url
if (down == "P") {
var vals = "";
$.each($('input:checkbox:checked'), function () {
vals += $(this).val() + ",";
});
var checkbox1 = $('<input>');
checkbox1.attr('type', 'text');
checkbox1.attr('name', 'coid');
checkbox1.attr('value', vals); //文件url
form.append(checkbox1);
}
$('body').append(form);
form.append(name1);
form.submit();
form.remove();
}
後端實現代碼:
//得到文件信息(名字,地址) (去掉最後一個 '$' , 並用 '$' 分隔字元串. 取到每個文件的文件名和路徑 )
string[] urlArray = model.urlStr.TrimEnd('$').Split('$');
//存 文件名 和 數據流
Dictionary<string, Stream> dc = new Dictionary<string, Stream>();
//取出字元串中信息 (文件名和地址)
for (int i = 0; i < urlArray.Length; i++)
{
WebClient myWebClient = new WebClient();
//使用 ',' 分隔 文件名和路徑 [0]位置是文件名, [1] 位置是路徑
string[] urlSp = urlArray[i].Split(',');
//調用WebClient 的 DownLoadData 方法 下載文件
byte[] data = myWebClient.DownloadData(urlSp[1].Replace("_PB.jpg", "_B.jpg"));
Stream stream = new MemoryStream(data);//byte[] 轉換成 流
//放入 文件名 和 stream
dc.Add(urlSp[0] + ".jpg" + "," + urlSp[2], stream);//這裡指定為 .doc格式 (自己可以隨時改)
if (urlArray.Length == 1)
{
Image img = Image.FromStream(stream);
MemoryStream ms = new MemoryStream();
img.Save(ms, ImageFormat.Jpeg);
img.Dispose();
context.Response.ClearContent();
context.Response.ContentType = "application/octet-stream";
context.Response.AppendHeader("Content-Disposition", "attachment;filename=" + urlSp[0] + ".jpeg");//文件名和格式(格式可以自己定)
context.Response.ContentType = "image/jpeg";
context.Response.BinaryWrite(ms.ToArray());
return;
}
}
//調用壓縮方法 進行壓縮 (接收byte[] 數據)
byte[] fileBytes = ConvertZipStream(dc);
context.Response.ContentType = "application/octet-stream";
context.Response.AppendHeader("Content-Disposition", "attachment;filename=SoonnetImage.rar");//文件名和格式(格式可以自己定)
context.Response.AddHeader("Content-Length", fileBytes.Length.ToString());//文件大小
context.Response.BinaryWrite(fileBytes); //放入byte[]
context.Response.End();
context.Response.Close();
/// <summary>
/// ZipStream 壓縮
/// </summary>
/// <param name="streams">Dictionary(string, Stream) 文件名和Stream</param>
/// <returns></returns>
public static byte[] ConvertZipStream(Dictionary<string, Stream> streams)
{
byte[] buffer = new byte[6500];
MemoryStream returnStream = new MemoryStream();
var zipMs = new MemoryStream();
using (ICSharpCode.SharpZipLib.Zip.ZipOutputStream zipStream = new ICSharpCode.SharpZipLib.Zip.ZipOutputStream(zipMs))
{
zipStream.SetLevel(9);//設置 壓縮等級 (9級 500KB 壓縮成了96KB)
foreach (var kv in streams)
{
string[] fileName = kv.Key.Split(',');
using (var streamInput = kv.Value)
{
zipStream.PutNextEntry(new ICSharpCode.SharpZipLib.Zip.ZipEntry(fileName[1] + "/" + fileName[0])); //主要是這裡可以分文件夾自動壓縮
while (true)
{
var readCount = streamInput.Read(buffer, 0, buffer.Length);
if (readCount > 0)
{
zipStream.Write(buffer, 0, readCount);
}
else
{
break;
}
}
zipStream.Flush();
}
}
zipStream.Finish();
zipMs.Position = 0;
zipMs.CopyTo(returnStream, 5600);
}
returnStream.Position = 0;
//Stream轉Byte[]
byte[] returnBytes = new byte[returnStream.Length];
returnStream.Read(returnBytes, 0, returnBytes.Length);
returnStream.Seek(0, SeekOrigin.Begin);
return returnBytes;
}
註:
文章中代碼有牽扯到 1 長圖片點擊直接下載的功能,可以刪除部分邏輯實現,不同文件夾壓縮圖片功能。
該壓縮並非會壓縮圖片本身,解壓後,圖片的大小跟實際大小一致。