programing

EPPlus와 MemoryStream의 사용

cafebook 2023. 4. 13. 21:08
반응형

EPPlus와 MemoryStream의 사용

EPplus를 사용하여 C#에 XLSX 파일을 생성하고 있습니다.Excel 패키지를 메모리 스트림으로 인스턴스화하면 다음 오류가 나타납니다.

"쓰기 작업 중 디스크 오류가 발생했습니다. (HRESULT: 0x8003001D(STG_E_WRITEFAULT)의 예외)"

코드는 다음과 같습니다.

MemoryStream stream = new MemoryStream();

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

이거 본 사람 있어?

다른 어떤 답변도 도움이 되지 않았지만(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.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# 코드는 정확할 겁니다.Excel Package에는 스트림을 지원하는 기능이 내장되어 있습니다.

스트림을 계속 사용하려면(예: 응답).OutputStream)은 빈 컨스트럭터로 ExcelPackage를 생성하여 SaveAs(Stream OutputStream) 메서드를 사용할 수 있습니다.

Excel 패키지입니다. 빈 스트림을 요, 빈 스트림을 드리면요.System.IO.Packaging.Package.Open는 패키지를 비워 둘 수 없음을 나타내는 예외를 발생시킵니다.

이 코드는 파일이 존재하지 않는 경우에도 작동합니다.

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

컨스트럭터 오버로드에 대한 문서에는 스트림이 비어 있는 것이 나타나 있으므로 EPplus 문제 트래커에서 이 문제를 제기할 것을 권장합니다.

빈 생성자를 사용하여 Excel Package를 생성할 수 있습니다.자체 내부 버퍼를 처리합니다.

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

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
}

또한 Excel Builder 클래스의 Build Result File 함수는 다음과 같습니다.

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

을 4.5, 는 블록의 을 4.5.1에서 .BuildResultFile★★★★★★ 。

GitHub에서는 왜 이것이 변경되었는지, 심지어 제대로 구현하고 있는지 문서를 찾을 수 없는 것 같습니다.

기존 엑셀 파일을 열려고 했을 때도 같은 문제에 직면하여 며칠을 보냈습니다.제 경우 암호화로 인해 "쓰기 작업 중 디스크 오류가 발생했습니다. (HRESULT: 0x8003001D(STG_E_WRITEFAULT)"라는 예외가 발생했습니다.

비밀번호를 입력하여 .xlsx 파일을 읽을 수 있었습니다.저 같은 경우에는 빈 문자열로 충분했습니다.

당신의 경우 비밀번호를 가진 컨스트럭터를 사용하여 패키지를 초기화해 보십시오.

public ExcelPackage(Stream newStream, string Password)

package = new ExcelPackage(stream, "");

Excel Package 소스 코드(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);
 }

...

암호는 비어 있지만 NULL은 아닌 경우에도 코드는 Excel 스트림의 암호를 해독하려고 시도합니다.

그러나 암호화되지 않은 파일의 패키지를 초기화하려고 하면 예외가 발생합니다.

'스트림이 올바르거나 지원되는 암호화된 문서가 아닙니다.'

저도 같은 오류를 겪고 있었지만 다른 답변은 전혀 도움이 되지 않았습니다.

결국 이 코드를 추가한 후 파일을 열려고 하면 문제가 해결되었습니다.

Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);

코드 페이지가 없어 EPPlus가 ZIP을 열지 못한 것이 근본 원인인 것 같습니다. Stack Overflow 답변 덕분에 이 작업이 가능해졌습니다.

언급URL : https://stackoverflow.com/questions/5738123/using-epplus-with-a-memorystream

반응형