51

I am using EPPlus to generate an XLSX file in C#. As soon as I instantiate the ExcelPackage with a memory stream - I get the error:

"A disk error occurred during a write operation. (Exception from HRESULT: 0x8003001D (STG_E_WRITEFAULT))"

Code is:

MemoryStream stream = new MemoryStream();

using (ExcelPackage package = new ExcelPackage(stream))
{
    ...
}

Has anyone else seen this?

4

8 回答 8

77

其他答案都没有让我到达那里(Excel工作表总是空的),但这对我有用:

using (var package = new ExcelPackage())
{
    var worksheet = package.Workbook.Worksheets.Add("Worksheet Name");

    worksheet.Cells["A1"].LoadFromCollection(data);

    var stream = new MemoryStream(package.GetAsByteArray());
}
于 2012-12-27T02:05:28.723 回答
26

我知道这个问题在几个月前就已经得到了回答,但我就是这样做的,以供将来尝试的人参考:

在 VB.NET 中:

Dim stream As New MemoryStream
Using package As New ExcelPackage(stream)
    'Here goes the ExcelPackage code etc 
    package.Save()
End Using

在 C# 中:

MemoryStream stream = new MemoryStream();
using (ExcelPackage package = new ExcelPackage(stream))
{
    //Here goes the ExcelPackage code etc
    package.Save()
}

据我所知,C# 代码应该是正确的。ExcelPackage 内置了对流的支持。

于 2011-11-28T11:06:34.483 回答
14

如果您想继续使用流(例如 Response.OutputStream),您可以创建一个带有空构造函数的 ExcelPackage 并使用SaveAs(Stream OutputStream )方法。

于 2011-06-23T21:46:32.623 回答
9

看起来您在 ExcelPackage 构造函数的错误处理程序中遇到了错误。如果您尝试给它一个空流,则会System.IO.Packaging.Package.Open引发异常指示包不能为空。

即使文件不存在,此代码也有效:

var file = new FileInfo("test.xlsx");
using (ExcelPackage package = new ExcelPackage(file))
{
}

鉴于构造函数重载的文档表明允许流为空,我建议在 EPPlus 问题跟踪器中提出此问题。

于 2011-04-21T13:13:57.490 回答
1

您可以使用空构造函数创建 ExcelPackage。它将处理自己的内部缓冲区。

http://epplus.codeplex.com/wikipage?title=WebapplicationExample

于 2011-05-19T18:14:27.847 回答
1

在将使用 EPPlus 4.1.1 版本的代码转换为 4.5.1 版本时,我们遇到了类似的问题。

最初,我们使用以下模式:

using (var ms = new MemoryStream())
{
    new ExcelBuilder().BuildResultFile(result, ms);
    ms.Position = 0;    // <-- Cannot access a closed Stream error thrown here
    // Send Excel file to Azure storage
}

还有我们的 ExcelBuilder 类 BuildResultFile 函数:

public void BuildResultFile(List<ResultSet> resultSets, Stream stream)
{
    using (var package = new ExcelPackage(stream))
    {
        // Create Excel file from resultSets
        package.Save();
    }
}

为了使它与 4.5.1 一起工作,我们必须从BuildResultFile函数中删除 using 块。

我似乎在 GitHub 上找不到任何文档 w/r/t 为什么会发生这种变化,或者我什至是否正确地实现了这一点。

于 2018-03-30T15:19:16.267 回答
0

当我试图打开现有的 excel 文件并花了几天时间时,我遇到了同样的问题。就我而言,由于加密,我收到了提到的异常“写入操作期间发生磁盘错误。(来自 HRESULT 的异常:0x8003001D(STG_E_WRITEFAULT))”。

我能够通过传递密码来读取 .xlsx 文件。在我的情况下,空字符串“”就足够了。

在您的情况下,请尝试使用带密码的构造函数初始化包:

public ExcelPackage(Stream newStream, string Password)

package = new ExcelPackage(stream, "");

查看 ExcelPackage 源代码http://epplus.codeplex.com/SourceControl/latest#EPPlus/ExcelPackage.cs

有一种方法

private void Load(Stream input, Stream output, string Password) 

用于加载excel文件。

private void Load(Stream input, Stream output, string Password) 

...

if (Password != null)

{
  Stream encrStream = new MemoryStream();
  CopyStream(input, ref encrStream);
  EncryptedPackageHandler eph = new EncryptedPackageHandler();
  Encryption.Password = Password;
  ms = eph.DecryptPackage((MemoryStream)encrStream, Encryption);
}
else
{
  ms = new MemoryStream();
  CopyStream(input, ref ms);
 }

...

即使密码为空,代码也会尝试解密 excel 流,但不是 NULL。

但是,如果您尝试为未加密的文件初始化包,您将遇到异常:

'该流不是有效/受支持的加密文档。'

于 2018-01-26T11:08:06.580 回答
0

我正在处理同样的错误,但其他答案都没有提供任何帮助。

最后,在尝试打开文件之前添加此代码后,问题得到解决:

Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);

似乎根本原因是 EPPlus 由于缺少代码页而无法打开 ZIP。多亏了这个 StackOverflow 答案,我才得以工作。

于 2018-02-20T15:43:58.297 回答