使用 EPPLUS C# 创建 Excel XLSX 文件的 ZipArchive
Create ZipArchive of Excel XLSX file with EPPLUS C#
我的 ASP.NET MVC 应用程序具有 return FileStreamResult
的以下功能。
/// <summary>
/// Generates a FileStreamResult containing a zip file with the EXCEL file in it
/// </summary>
/// <typeparam name="T">Type of object in the object list parameter</typeparam>
/// <param name="objectList">The object list enumerable. This contains the data for the EXCEL file</param>
/// <param name="fileName">The file name of the EXCEL</param>
/// <returns>FileStreamResult</returns>
public FileStreamResult CreateZipFileFileStreamResult<T>(IEnumerable<T> objectList, string fileName)
{
var ms = new MemoryStream();
var contentType = System.Net.Mime.MediaTypeNames.Application.Zip;
ExcelPackage excelPackage = null;
ZipArchive archive = null;
try
{
excelPackage = new ExcelPackage(ms);
var workSheet1 = excelPackage.Workbook.Worksheets.Add("Sheet1");
workSheet1.Cells["A1"].LoadFromCollection<T>(objectList, true);
excelPackage.SaveAs(ms);
ms.Seek(0, SeekOrigin.Begin);
archive = new ZipArchive(excelPackage.Stream, ZipArchiveMode.Create, true);
var newEntry = archive.CreateEntry(fileName, System.IO.Compression.CompressionLevel.Fastest);
var newEntryStream = newEntry.Open();
var fsr = new FileStreamResult(excelPackage.Stream, contentType);
fsr.FileDownloadName = fileName + ".zip";
return fsr;
}
catch (Exception ex)
{
if (archive != null)
archive.Dispose();
if (excelPackage != null)
excelPackage.Dispose();
if (ms != null)
ms.Dispose();
throw;
}
}
函数 return 有点东西,但它是拆分 XML 方式而不是一个 XLSX 文件。
我希望它成为 return 压缩的单个文件。
这是当前结果的样子。
在@kuujinbo 的帮助下,我创建了这个函数。
请注意,出于某种原因,FileContentResult 有效而 FileStreamResult 无效。
/// <summary>
/// Generates a FileStreamResult containing a zip file with the EXCEL file in it
/// </summary>
/// <typeparam name="T">Type of object in the object list parameter</typeparam>
/// <param name="objectList">The object list enumerable. This contains the data for the EXCEL file</param>
/// <param name="fileName">The file name of the EXCEL</param>
/// <returns>FileStreamResult</returns>
public FileContentResult CreateZipFileFileContentResult<T>(IEnumerable<T> objectList, string fileName)
{
var contentType = System.Net.Mime.MediaTypeNames.Application.Zip;
using (var memoryStream = new System.IO.MemoryStream())
{
using (Ionic.Zip.ZipFile zip = new Ionic.Zip.ZipFile())
{
using (var package = new OfficeOpenXml.ExcelPackage())
{
var workSheet1 = package.Workbook.Worksheets.Add("Sheet1");
workSheet1.Cells["A1"].LoadFromCollection<T>(objectList, true);
var firstRow = workSheet1.Row(1);
if (firstRow != null)
firstRow.Style.Font.Bold = true;
zip.AddEntry(fileName, package.GetAsByteArray());
zip.Save(memoryStream);
var fcr = new FileContentResult(memoryStream.ToArray(), contentType); //NOTE: Using a File Stream Result will not work.
fcr.FileDownloadName = fileName + ".zip";
return fcr;
}
}
}
}
因为 EPPlus 内部 使用 DotNetZip , (take a look at the source code) try and do the same. IMHO their design decision tells a lot about why some choose not to use ZipArchive.
的版本
class TestObject
{
public int Id { get; set; }
public string Name { get; set; }
}
IEnumerable<TestObject> objectList = new List<TestObject>()
{
{ new TestObject() {Id = 0, Name = "zero" } },
{ new TestObject() {Id = 1, Name = "one" } }
};
string ExcelName = "test.xlsx";
string ZipName = "test.zip";
public ActionResult DotnetZip()
{
using (var stream = new MemoryStream())
{
using (ZipFile zip = new ZipFile())
{
using (var package = new ExcelPackage())
{
var sheet = package.Workbook.Worksheets.Add("Sheet1");
sheet.Cells["A1"].LoadFromCollection<TestObject>(objectList, true);
zip.AddEntry(ExcelName, package.GetAsByteArray());
zip.Save(stream);
return File(
stream.ToArray(),
System.Net.Mime.MediaTypeNames.Application.Zip,
ZipName
);
}
}
}
}
已测试并正常工作:
我的 ASP.NET MVC 应用程序具有 return FileStreamResult
的以下功能。
/// <summary>
/// Generates a FileStreamResult containing a zip file with the EXCEL file in it
/// </summary>
/// <typeparam name="T">Type of object in the object list parameter</typeparam>
/// <param name="objectList">The object list enumerable. This contains the data for the EXCEL file</param>
/// <param name="fileName">The file name of the EXCEL</param>
/// <returns>FileStreamResult</returns>
public FileStreamResult CreateZipFileFileStreamResult<T>(IEnumerable<T> objectList, string fileName)
{
var ms = new MemoryStream();
var contentType = System.Net.Mime.MediaTypeNames.Application.Zip;
ExcelPackage excelPackage = null;
ZipArchive archive = null;
try
{
excelPackage = new ExcelPackage(ms);
var workSheet1 = excelPackage.Workbook.Worksheets.Add("Sheet1");
workSheet1.Cells["A1"].LoadFromCollection<T>(objectList, true);
excelPackage.SaveAs(ms);
ms.Seek(0, SeekOrigin.Begin);
archive = new ZipArchive(excelPackage.Stream, ZipArchiveMode.Create, true);
var newEntry = archive.CreateEntry(fileName, System.IO.Compression.CompressionLevel.Fastest);
var newEntryStream = newEntry.Open();
var fsr = new FileStreamResult(excelPackage.Stream, contentType);
fsr.FileDownloadName = fileName + ".zip";
return fsr;
}
catch (Exception ex)
{
if (archive != null)
archive.Dispose();
if (excelPackage != null)
excelPackage.Dispose();
if (ms != null)
ms.Dispose();
throw;
}
}
函数 return 有点东西,但它是拆分 XML 方式而不是一个 XLSX 文件。
我希望它成为 return 压缩的单个文件。
这是当前结果的样子。
在@kuujinbo 的帮助下,我创建了这个函数。 请注意,出于某种原因,FileContentResult 有效而 FileStreamResult 无效。
/// <summary>
/// Generates a FileStreamResult containing a zip file with the EXCEL file in it
/// </summary>
/// <typeparam name="T">Type of object in the object list parameter</typeparam>
/// <param name="objectList">The object list enumerable. This contains the data for the EXCEL file</param>
/// <param name="fileName">The file name of the EXCEL</param>
/// <returns>FileStreamResult</returns>
public FileContentResult CreateZipFileFileContentResult<T>(IEnumerable<T> objectList, string fileName)
{
var contentType = System.Net.Mime.MediaTypeNames.Application.Zip;
using (var memoryStream = new System.IO.MemoryStream())
{
using (Ionic.Zip.ZipFile zip = new Ionic.Zip.ZipFile())
{
using (var package = new OfficeOpenXml.ExcelPackage())
{
var workSheet1 = package.Workbook.Worksheets.Add("Sheet1");
workSheet1.Cells["A1"].LoadFromCollection<T>(objectList, true);
var firstRow = workSheet1.Row(1);
if (firstRow != null)
firstRow.Style.Font.Bold = true;
zip.AddEntry(fileName, package.GetAsByteArray());
zip.Save(memoryStream);
var fcr = new FileContentResult(memoryStream.ToArray(), contentType); //NOTE: Using a File Stream Result will not work.
fcr.FileDownloadName = fileName + ".zip";
return fcr;
}
}
}
}
因为 EPPlus 内部 使用 DotNetZip , (take a look at the source code) try and do the same. IMHO their design decision tells a lot about why some choose not to use ZipArchive.
的版本class TestObject
{
public int Id { get; set; }
public string Name { get; set; }
}
IEnumerable<TestObject> objectList = new List<TestObject>()
{
{ new TestObject() {Id = 0, Name = "zero" } },
{ new TestObject() {Id = 1, Name = "one" } }
};
string ExcelName = "test.xlsx";
string ZipName = "test.zip";
public ActionResult DotnetZip()
{
using (var stream = new MemoryStream())
{
using (ZipFile zip = new ZipFile())
{
using (var package = new ExcelPackage())
{
var sheet = package.Workbook.Worksheets.Add("Sheet1");
sheet.Cells["A1"].LoadFromCollection<TestObject>(objectList, true);
zip.AddEntry(ExcelName, package.GetAsByteArray());
zip.Save(stream);
return File(
stream.ToArray(),
System.Net.Mime.MediaTypeNames.Application.Zip,
ZipName
);
}
}
}
}
已测试并正常工作: