首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >在NPOI workbook.write之后,MemoryStream似乎关闭了?

在NPOI workbook.write之后,MemoryStream似乎关闭了?
EN

Stack Overflow用户
提问于 2014-04-08 16:28:54
回答 3查看 19.5K关注 0票数 33

我在一个ASP.NET Web API项目中使用NPOI将DataTable转换为Excel。

但我从回复中什么也没得到。下面是我的代码:

代码语言:javascript
复制
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

我哪里错了?

EN

回答 3

Stack Overflow用户

发布于 2019-03-27 22:03:50

我不知道这是不是还需要,但是有一个overload

代码语言:javascript
复制
Write(Stream stream, bool leaveOpen)

其中,如果设置了leaveOpen = true,则会使MemoryStream保持打开状态

票数 12
EN

Stack Overflow用户

发布于 2016-04-13 06:03:05

正如alun上面所说的,在this问题中,你可以将流提供给另一个MemoryStream:

代码语言:javascript
复制
...
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文件时才需要这样做。

票数 7
EN

Stack Overflow用户

发布于 2016-04-13 06:16:54

我遇到过关闭/处理不属于自己的流的API的类似问题。我不熟悉NPOI,但我假设Write方法接受流,而不是MemoryStream。如果是这种情况,您可以创建一个wrapper Stream类,将所有调用(读/写/查找等)转发到内部流(在本例中是您的MemoryStream ),但不转发对close/dispose的调用。将包装器传递给Write方法,当它返回时,您的MemoryStream应该包含所有内容并且仍然是“打开的”。

此外,您可能需要ms.Seek(0, SeekOrigin.Begin)。在调用Write之后,内存流将定位在流的末尾,所以如果您尝试从该位置读取,它将显示为emtpy。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/22931582

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档