我在一个ASP.NET Web API项目中使用NPOI将DataTable转换为Excel。
但我从回复中什么也没得到。下面是我的代码:
public HttpResponseMessage GetExcelFromDataTable(DataTable dt)
{
IWorkbook workbook = new XSSFWorkbook(); // create *.xlsx file, use HSSFWorkbook() for creating *.xls file.
ISheet sheet1 = workbook.CreateSheet();
IRow row1 = sheet1.CreateRow(0);
for (int i = 0; dt.Columns.Count > i; i++)
{
row1.CreateCell(i).SetCellValue(dt.Columns[i].ColumnName);
}
for (int i = 0; dt.Rows.Count > i; i++)
{
IRow row = sheet1.CreateRow(i + 1);
for (int j = 0; dt.Columns.Count > j; j++)
{
row.CreateCell(j).SetCellValue(dt.Rows[i][j].ToString());
}
}
MemoryStream ms = new MemoryStream();
workbook.Write(ms);
HttpResponseMessage result = new HttpResponseMessage(HttpStatusCode.OK);
result.Content = new StreamContent(ms);
result.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
result.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment");
result.Content.Headers.ContentDisposition.FileName = string.Format("{0}.xlsx", dt.TableName);
return result;
}
我设置了一个断点来检查workbook.Write(ms)
之后的ms.Length
,但它返回了一个异常:System.ObjectDisposedException
。
我哪里错了?
发布于 2019-03-27 22:03:50
我不知道这是不是还需要,但是有一个overload
Write(Stream stream, bool leaveOpen)
其中,如果设置了leaveOpen = true
,则会使MemoryStream保持打开状态
发布于 2016-04-13 06:03:05
正如alun上面所说的,在this问题中,你可以将流提供给另一个MemoryStream:
...
MemoryStream ms = new MemoryStream();
using(MemoryStream tempStream = new MemoryStream)
{
workbook.Write(tempStream);
var byteArray = tempStream.ToArray();
ms.Write(byteArray, 0, byteArray.Length);
HttpResponseMessage result = new HttpResponseMessage(HttpStatusCode.OK);
result.Content = new StreamContent(ms);
result.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
result.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment");
result.Content.Headers.ContentDisposition.FileName = string.Format("{0}.xlsx", dt.TableName);
return result;
}
必须这样做会有一点代码的味道。但是,由于涉及的第三方库处理流的方式,只有在输出.xlsx文件时才需要这样做。
发布于 2016-04-13 06:16:54
我遇到过关闭/处理不属于自己的流的API的类似问题。我不熟悉NPOI,但我假设Write方法接受流,而不是MemoryStream。如果是这种情况,您可以创建一个wrapper Stream类,将所有调用(读/写/查找等)转发到内部流(在本例中是您的MemoryStream ),但不转发对close/dispose的调用。将包装器传递给Write方法,当它返回时,您的MemoryStream应该包含所有内容并且仍然是“打开的”。
此外,您可能需要ms.Seek(0, SeekOrigin.Begin)
。在调用Write之后,内存流将定位在流的末尾,所以如果您尝试从该位置读取,它将显示为emtpy。
https://stackoverflow.com/questions/22931582
复制相似问题