it-swarm.com.de

EPPlus mit einem MemoryStream verwenden

Ich verwende EPPlus, um eine XLSX-Datei in C # zu generieren. Sobald ich das ExcelPackage mit einem Speicherstrom instanziiere, erhalte ich den Fehler:

"Ein Plattenfehler ist während eines Schreibvorgangs aufgetreten. (Ausnahme von HRESULT: 0x8003001D (STG_E_WRITEFAULT))"

Code lautet:

MemoryStream stream = new MemoryStream();

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

Hat das noch jemand gesehen?

38
dan

Keine der anderen Antworten hat mich wirklich dort hin gebracht (das Excel-Arbeitsblatt war immer leer), aber das funktionierte für mich:

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

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

    var stream = new MemoryStream(package.GetAsByteArray());
}
59
Noah Heldman

Ich weiß, dass die Frage schon vor Monaten beantwortet wurde, aber so mache ich es für den zukünftigen Verweis auf jeden, der versucht:

In VB.NET:

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

In c #:

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

Der C # -Code sollte meines Wissens nach korrekt sein. Und das ExcelPackage bietet integrierte Unterstützung für Streams.

15
Reigo Hein

Wenn Sie weiterhin einen Stream (z. B. Response.OutputStream) verwenden möchten, können Sie ein ExcelPackage mit einem leeren Konstruktor erstellen und die Methode SaveAs (Stream OutputStream) verwenden.

12
Danny

Es sieht so aus, als ob Sie einen Fehler im Fehlerbehandlungsprogramm des ExcelPackage-Konstruktors finden. Wenn Sie versuchen, einen leeren Stream anzugeben, gibt System.IO.Packaging.Package.Open eine Ausnahme aus, die darauf hinweist, dass ein Paket nicht leer sein kann.

Dieser Code funktioniert auch, wenn die Datei nicht existiert:

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

Da die Dokumentation für die Konstruktorüberladung darauf hinweist, dass der Stream leer sein darf, würde ich empfehlen, dieses Problem im EPPlus-Issue-Tracker zu melden.

9
Mike Goatly

Bei der Konvertierung von Code, der die Version 4.1.1 von EPPlus verwendete, in die Version 4.5.1 war ein ähnliches Problem aufgetreten.

Ursprünglich verwendeten wir das folgende Muster:

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
}

Und unsere ExcelBuilder-Klasse BuildResultFile-Funktion:

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

Damit dies mit 4.5.1 funktioniert, mussten wir using block aus der BuildResultFile-Funktion entfernen. 

Ich kann anscheinend keine Dokumentation in GitHub finden, wieso sich dies geändert hat oder ob ich das überhaupt richtig implementiere. 

1
Electric_Wizard

Sie können ein ExcelPackage mit einem leeren Konstruktor erstellen. Es wird seinen eigenen internen Puffer behandeln. 

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

1
Hamid

Beim Versuch, eine vorhandene Excel-Datei zu öffnen, trat das gleiche Problem auf und ich verbrachte einige Tage damit. In meinem Fall habe ich die erwähnte Ausnahme "Ein Festplattenfehler ist während eines Schreibvorgangs aufgetreten. (Ausnahme von HRESULT: 0x8003001D (STG_E_WRITEFAULT))" aufgrund von Verschlüsselung erhalten.

Ich konnte die XLSX-Datei lesen, indem ich ein Passwort übermittelte. In meinem Fall hat die leere Zeichenfolge "" gereicht.

versuchen Sie in Ihrem Fall, das Paket mit dem Konstruktor mit dem Kennwort zu initialisieren:

public ExcelPackage(Stream newStream, string Password)

package = new ExcelPackage(stream, "");

Sehen Sie sich den ExcelPackage-Quellcode an http://epplus.codeplex.com/SourceControl/latest#EPPlus/ExcelPackage.cs

Es gibt eine Methode

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

welche verwendet wird, um Excel-Datei zu laden.

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);
 }

...

Der Code versucht, den Excel-Stream zu entschlüsseln, auch wenn das Kennwort leer ist, ABER NICHT NULL.

Wenn Sie jedoch versuchen, das Paket für eine nicht verschlüsselte Datei zu initialisieren, tritt eine Ausnahme auf:

'Der Stream ist kein gültiges/unterstütztes verschlüsseltes Dokument.'

0
Artem

Ich habe mich mit dem gleichen Fehler befasst, aber keine der anderen Antworten hat mir geholfen.

Am Ende wurde das Problem behoben, nachdem der Code vor dem Öffnen der Datei hinzugefügt wurde:

Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);

Es scheint, dass die Hauptursache darin bestand, dass EPPlus den Zip aufgrund einer fehlenden Codepage nicht öffnen konnte. Ich bekam dies dank dieser StackOverflow-Antwort zum Laufen.

0