OpenXML Excel 文档的 MemoryStream 为空
MemoryStream is empty for an OpenXML Excel document
我通常会使用 ClosedXML 生成 Excel 文件。核心项目迫使我只使用 OpenXML。
将下载生成的 Excel 文件。
我遇到了一个问题,即提供给 SpreadsheetDocument 的内存流是空的。
我尝试了多种方法来生成流。下面的代码代表了一个精简版本,只创建了基本要素。同样,内存流的长度为 0
。
我知道我应该使用 using()
等。这只是简化代码以尝试让它工作。
生成excel的代码;这是来自 File
对象的构造函数。 AsMemoryStream
是一个 属性 声明为 public MemoryStream AsMemoryStream { get; private set; }
public File(IList<T> items)
{
if (!items.Any())
throw new InvalidOperationException("items cannot be empty");
MemoryStream documentStream = new MemoryStream();
SpreadsheetDocument document = SpreadsheetDocument.Create(documentStream, DocumentFormat.OpenXml.SpreadsheetDocumentType.Workbook);
WorkbookPart workbookPart = document.AddWorkbookPart();
workbookPart.Workbook = new Workbook();
WorksheetPart worksheetPart = workbookPart.AddNewPart<WorksheetPart>();
worksheetPart.Worksheet = new Worksheet();
Sheets sheets = workbookPart.Workbook.AppendChild(new Sheets());
Sheet sheet = new Sheet { Id = workbookPart.GetIdOfPart(worksheetPart), SheetId = 1, Name = "Export" };
sheets.Append(sheet);
// have tried various Save() calls
// worksheetPart.Worksheet.Save();
// workbookPart.Workbook.Save();
AsMemoryStream = new MemoryStream();
documentStream.CopyTo(AsMemoryStream);
}
我在控制器中将文件下载为:
public IActionResult TransactionDetails(int transactionId)
{
IList<Partner> details = _dataService.GetTransactionPartners(transactionId).Result;
MemoryStream excelStream = _excelRepository.TransactionDetailExcel(details).AsMemoryStream;
ContentDisposition contentDisposition = new ContentDisposition
{
FileName = "transactionDetails.xlsx",
Inline = false
};
Response.Headers.Add("content-disposition", contentDisposition.ToString());
return File(excelStream.ToArray(), "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
}
文件已下载,但长度为 0 字节。与正在使用的任何内存流一样。
谁能指出我正确的方向?
SpreadSheetDocument
跟踪需要写入流的内容。它仅在调用 Close 或 Dispose 时这样做。在那一刻之前,它不会创建任何 OpenXmlPackage,因为它无法确定文档是否完整。
修复代码的方法如下:
MemoryStream documentStream = new MemoryStream();
using(SpreadsheetDocument document = SpreadsheetDocument.Create(documentStream, DocumentFormat.OpenXml.SpreadsheetDocumentType.Workbook))
{
WorkbookPart workbookPart = document.AddWorkbookPart();
workbookPart.Workbook = new Workbook();
WorksheetPart worksheetPart = workbookPart.AddNewPart<WorksheetPart>();
worksheetPart.Worksheet = new Worksheet();
Sheets sheets = workbookPart.Workbook.AppendChild(new Sheets());
Sheet sheet = new Sheet { Id = workbookPart.GetIdOfPart(worksheetPart), SheetId = 1, Name = "Export" };
sheets.Append(sheet);
document.Close();
}
// the stream is complete here
AsMemoryStream = new MemoryStream();
documentStream.CopyTo(AsMemoryStream);
我通常会使用 ClosedXML 生成 Excel 文件。核心项目迫使我只使用 OpenXML。
将下载生成的 Excel 文件。
我遇到了一个问题,即提供给 SpreadsheetDocument 的内存流是空的。
我尝试了多种方法来生成流。下面的代码代表了一个精简版本,只创建了基本要素。同样,内存流的长度为 0
。
我知道我应该使用 using()
等。这只是简化代码以尝试让它工作。
生成excel的代码;这是来自 File
对象的构造函数。 AsMemoryStream
是一个 属性 声明为 public MemoryStream AsMemoryStream { get; private set; }
public File(IList<T> items)
{
if (!items.Any())
throw new InvalidOperationException("items cannot be empty");
MemoryStream documentStream = new MemoryStream();
SpreadsheetDocument document = SpreadsheetDocument.Create(documentStream, DocumentFormat.OpenXml.SpreadsheetDocumentType.Workbook);
WorkbookPart workbookPart = document.AddWorkbookPart();
workbookPart.Workbook = new Workbook();
WorksheetPart worksheetPart = workbookPart.AddNewPart<WorksheetPart>();
worksheetPart.Worksheet = new Worksheet();
Sheets sheets = workbookPart.Workbook.AppendChild(new Sheets());
Sheet sheet = new Sheet { Id = workbookPart.GetIdOfPart(worksheetPart), SheetId = 1, Name = "Export" };
sheets.Append(sheet);
// have tried various Save() calls
// worksheetPart.Worksheet.Save();
// workbookPart.Workbook.Save();
AsMemoryStream = new MemoryStream();
documentStream.CopyTo(AsMemoryStream);
}
我在控制器中将文件下载为:
public IActionResult TransactionDetails(int transactionId)
{
IList<Partner> details = _dataService.GetTransactionPartners(transactionId).Result;
MemoryStream excelStream = _excelRepository.TransactionDetailExcel(details).AsMemoryStream;
ContentDisposition contentDisposition = new ContentDisposition
{
FileName = "transactionDetails.xlsx",
Inline = false
};
Response.Headers.Add("content-disposition", contentDisposition.ToString());
return File(excelStream.ToArray(), "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
}
文件已下载,但长度为 0 字节。与正在使用的任何内存流一样。
谁能指出我正确的方向?
SpreadSheetDocument
跟踪需要写入流的内容。它仅在调用 Close 或 Dispose 时这样做。在那一刻之前,它不会创建任何 OpenXmlPackage,因为它无法确定文档是否完整。
修复代码的方法如下:
MemoryStream documentStream = new MemoryStream();
using(SpreadsheetDocument document = SpreadsheetDocument.Create(documentStream, DocumentFormat.OpenXml.SpreadsheetDocumentType.Workbook))
{
WorkbookPart workbookPart = document.AddWorkbookPart();
workbookPart.Workbook = new Workbook();
WorksheetPart worksheetPart = workbookPart.AddNewPart<WorksheetPart>();
worksheetPart.Worksheet = new Worksheet();
Sheets sheets = workbookPart.Workbook.AppendChild(new Sheets());
Sheet sheet = new Sheet { Id = workbookPart.GetIdOfPart(worksheetPart), SheetId = 1, Name = "Export" };
sheets.Append(sheet);
document.Close();
}
// the stream is complete here
AsMemoryStream = new MemoryStream();
documentStream.CopyTo(AsMemoryStream);