Using EPPlus with a MemoryStream

本文关键字:MemoryStream with EPPlus Using | 更新日期: 2023-09-27 17:51:26

我使用EPPlus在c#中生成XLSX文件。只要我实例化ExcelPackage与内存流-我得到错误:

"写操作过程中出现磁盘错误。(异常from HRESULT: 0x8003001D (STG_E_WRITEFAULT))"

代码是:

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

还有人看到这个吗?

Using EPPlus with a MemoryStream

其他答案都没有让我找到答案(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());
}

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

VB。净:

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内置了对流的支持

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

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

下面的代码可以工作,即使文件不存在:

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

考虑到构造函数重载的文档表明允许流为空,我建议在EPPlus问题跟踪器中提出这个问题。

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

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

我们在将使用4.1.1版本的EPPlus转换为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上为什么这改变了,或者如果我甚至正确实现了这一点。

当我试图打开现有的excel文件并花了几天时间时,我遇到了同样的问题。在我的情况下,我收到了提到的异常"在写操作期间发生磁盘错误"。(Exception from HRESULT: 0x8003001D (STG_E_WRITEFAULT))" due to encryption.

我可以通过传递密码读取。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流,即使password为空,但不是NULL。

但是,如果您尝试为未加密的文件初始化包,则会出现异常:

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

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

最后,在尝试打开文件之前添加以下代码后,问题得到了解决:
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);

似乎根本原因是由于缺少代码页,EPPlus无法打开ZIP。我得到了这个工作感谢这个StackOverflow的答案