从内存流 C# 创建 Zip 文件
基本上用户应该能够点击一个链接并下载多个pdf文件.但问题是我无法在服务器或任何地方创建文件.一切都必须在记忆中.
Basically the user should be able to click on one link and download multiple pdf files. But the Catch is I cannot create files on server or anywhere. Everything has to be in memory.
我能够创建内存流并将 Response.Flush() 它作为 pdf 但我如何在不创建文件的情况下压缩多个内存流.
I was able to create memory stream and Response.Flush() it as pdf but how do I zip multiple memory streams without creating files.
这是我的代码:
Response.ContentType = "application/zip";
// If the browser is receiving a mangled zipfile, IIS Compression may cause this problem. Some members have found that
// Response.ContentType = "application/octet-stream" has solved this. May be specific to Internet Explorer.
Response.AppendHeader("content-disposition", "attachment; filename=\"Download.zip\"");
Response.CacheControl = "Private";
Response.Cache.SetExpires(DateTime.Now.AddMinutes(3)); // or put a timestamp in the filename in the content-disposition
byte[] abyBuffer = new byte[4096];
ZipOutputStream outStream = new ZipOutputStream(Response.OutputStream);
outStream.SetLevel(3);
#region Repeat for each Memory Stream
MemoryStream fStream = CreateClassroomRoster();// This returns a memory stream with pdf document
ZipEntry objZipEntry = new ZipEntry(ZipEntry.CleanName("ClassroomRoster.pdf"));
objZipEntry.DateTime = DateTime.Now;
objZipEntry.Size = fStream.Length;
outStream.PutNextEntry(objZipEntry);
int count = fStream.Read(abyBuffer, 0, abyBuffer.Length);
while (count > 0)
{
outStream.Write(abyBuffer, 0, count);
count = fStream.Read(abyBuffer, 0, abyBuffer.Length);
if (!Response.IsClientConnected)
break;
Response.Flush();
}
fStream.Close();
#endregion
outStream.Finish();
outStream.Close();
Response.Flush();
Response.End();
这会创建一个 zip 文件,但里面没有文件
This creates a zip file but there's no file inside it
我正在使用使用 iTextSharp.text - 用于创建 pdf使用 ICSharpCode.SharpZipLib.Zip - 用于压缩
I am using using iTextSharp.text - for creating pdf using ICSharpCode.SharpZipLib.Zip - for Zipping
谢谢,卡维塔
此链接描述了如何使用 SharpZipLib 从 MemoryStream 创建 zip:https://github.com/icsharpcode/SharpZipLib/wiki/Zip-Samples#wiki-anchorMemory.使用它和 iTextSharp,我能够压缩在内存中创建的多个 PDF 文件.
This link describes how to create a zip from a MemoryStream using SharpZipLib: https://github.com/icsharpcode/SharpZipLib/wiki/Zip-Samples#wiki-anchorMemory. Using this and iTextSharp, I was able to zip multiple PDF files that were created in memory.
这是我的代码:
MemoryStream outputMemStream = new MemoryStream();
ZipOutputStream zipStream = new ZipOutputStream(outputMemStream);
zipStream.SetLevel(3); //0-9, 9 being the highest level of compression
byte[] bytes = null;
// loops through the PDFs I need to create
foreach (var record in records)
{
var newEntry = new ZipEntry("test" + i + ".pdf");
newEntry.DateTime = DateTime.Now;
zipStream.PutNextEntry(newEntry);
bytes = CreatePDF(++i);
MemoryStream inStream = new MemoryStream(bytes);
StreamUtils.Copy(inStream, zipStream, new byte[4096]);
inStream.Close();
zipStream.CloseEntry();
}
zipStream.IsStreamOwner = false; // False stops the Close also Closing the underlying stream.
zipStream.Close(); // Must finish the ZipOutputStream before using outputMemStream.
outputMemStream.Position = 0;
return File(outputMemStream.ToArray(), "application/octet-stream", "reports.zip");
CreatePDF 方法:
The CreatePDF Method:
private static byte[] CreatePDF(int i)
{
byte[] bytes = null;
using (MemoryStream ms = new MemoryStream())
{
Document document = new Document(PageSize.A4, 25, 25, 30, 30);
PdfWriter writer = PdfWriter.GetInstance(document, ms);
document.Open();
document.Add(new Paragraph("Hello World " + i));
document.Close();
writer.Close();
bytes = ms.ToArray();
}
return bytes;
}