web-dev-qa-db-fra.com

Utiliser EPPlus avec un MemoryStream

J'utilise EPPlus pour générer un fichier XLSX en C #. Dès que j'instancie ExcelPackage avec un flux de mémoire, le message d'erreur suivant s'affiche:

"Une erreur de disque s'est produite lors d'une opération d'écriture. (Exception de HRESULT: 0x8003001D (STG_E_WRITEFAULT))"

Le code est:

MemoryStream stream = new MemoryStream();

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

Quelqu'un d'autre a-t-il vu cela?

38
dan

Aucune des autres réponses ne m'a vraiment amené là-bas (la feuille de calcul Excel était toujours vide), mais cela a fonctionné pour moi:

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

Je sais que la question a reçu une réponse plusieurs mois auparavant, mais voici comment je le fais pour toute référence ultérieure à ceux qui tentent:

En VB.NET:

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

En C #:

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

Le code C # devrait être correct, autant que je sache. Et ExcelPackage a un support intégré pour les flux.

15
Reigo Hein

Si vous souhaitez continuer à utiliser un flux (par exemple Response.OutputStream), vous pouvez créer un ExcelPackage avec un constructeur vide et utiliser la méthode SaveAs (Stream OutputStream) .

12
Danny

Il semble que vous rencontriez un bogue dans le gestionnaire d'erreurs du constructeur ExcelPackage. Si vous essayez de lui attribuer un flux vide, System.IO.Packaging.Package.Open génère une exception indiquant qu'un package ne peut pas être vide.

Ce code fonctionne même si le fichier n'existe pas:

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

Étant donné que la documentation relative à la surcharge du constructeur indique que le flux est autorisé à être vide, je vous recommande de soulever ce problème dans le suivi des problèmes EPPlus.

9
Mike Goatly

Nous avons rencontré un problème similaire lors de la conversion de code utilisant la version 4.1.1 de EPPlus vers la version 4.5.1.

À l'origine, nous utilisions le modèle suivant:

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
}

Et notre classe ExcelBuilder, fonction BuildResultFile:

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

Pour que cela fonctionne avec la version 4.5.1, nous avons dû supprimer using block de la fonction BuildResultFile

Je n'arrive pas à trouver de documentation dans GitHub avec pourquoi cela a changé ou même si je l'implémente correctement. 

1
Electric_Wizard

Vous pouvez créer un ExcelPackage avec un constructeur vide. Il gérera son propre tampon interne. 

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

1
Hamid

J'avais affaire à la même erreur, mais aucune des autres réponses n'a fourni d'aide.

En fin de compte, le problème a été résolu après l'ajout de ce code avant d'essayer d'ouvrir le fichier:

Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);

Il semble que la cause principale soit qu'EPPlus n'ait pas pu ouvrir le fichier Zip à cause d'une page de code manquante ... J'ai obtenu que cela fonctionne grâce à cette réponse StackOverflow .

0
Kristof Verbiest