2010-10-26 15 views
2

Supposons que j'écris une application Web ASP.net.Comment générer une feuille de calcul Excel avec des images d'ASP.net

Le designer original de l'application utilisait "PopChart" pour faire apparaître certaines images dans l'application web. Une des pages avait un bouton "Exporter vers Excel". Lorsque le bouton est cliqué, le contenu de la page est généré dans Excel comme dans ce didacticiel: http://aspalliance.com/articleViewer.aspx?aId=1&pId=. Fondamentalement, il produit du code HTML dans un fichier XLS et Excel l'interprète. Le problème est, je dois me débarrasser de PopChart. Je l'ai remplacé par un contrôle Web qui produit un fichier PNG (qui, incidemment, peut être enregistré dans un objet MemoryStream lors de l'exécution). PopChart fait référence à un composant Flash qui s'exécute à partir d'un serveur public. les données sur le "PopChart" sont intégrées dans le HTML. Cependant, une fois que j'ai commencé à utiliser le contrôle Web qui génère le PNG, toutes les données se trouvent dans un seul fichier PNG. Je ne vois pas comment il est possible de sortir le fichier PNG avec le HTML. J'ai essayé d'incorporer les données dans le img src=..., mais Excel ne l'interprétera pas. Excel ne peut pas non plus télécharger le fichier PNG à partir du serveur; le serveur est verrouillé et Excel n'a pas accès à la session du navigateur.

Que puis-je faire?

Mise à jour: Je trouve l'exemple de code suivant donné sur les forums MSDN:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 

using DocumentFormat.OpenXml; 
using DocumentFormat.OpenXml.Packaging; 
using DocumentFormat.OpenXml.Spreadsheet; 
using DocumentFormat.OpenXml.Validation; 
using DocumentFormat.OpenXml.Drawing.Spreadsheet; 

using System.IO; 
using System.Drawing; 

namespace ConsoleApplication4 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      string sFile = "ExcelOpenXmlWithImage.xlsx"; 
      if (File.Exists(sFile)) 
      { 
       File.Delete(sFile); 
      } 
      BuildWorkbook(sFile); 
     } 

     private static void BuildWorkbook(string filename) 
     { 
      try 
      { 
       using (SpreadsheetDocument xl = SpreadsheetDocument.Create(filename, SpreadsheetDocumentType.Workbook)) 
       { 
        WorkbookPart wbp = xl.AddWorkbookPart(); 
        WorksheetPart wsp = wbp.AddNewPart<WorksheetPart>();         
        Workbook wb = new Workbook(); 
        FileVersion fv = new FileVersion(); 
        fv.ApplicationName = "Microsoft Office Excel"; 
        Worksheet ws = new Worksheet(); 
        SheetData sd = new SheetData(); 

        //string sImagePath = "polymathlogo.png"; 
        string sImagePath = @"c:\temp\chartImg.png"; 
        DrawingsPart dp = wsp.AddNewPart<DrawingsPart>(); 
        ImagePart imgp = dp.AddImagePart(ImagePartType.Png, wsp.GetIdOfPart(dp)); 
        using (FileStream fs = new FileStream(sImagePath, FileMode.Open)) 
        { 
         imgp.FeedData(fs); 
        } 

        NonVisualDrawingProperties nvdp = new NonVisualDrawingProperties(); 
        nvdp.Id = 1025; 
        nvdp.Name = "Picture 1"; 
        nvdp.Description = "polymathlogo"; 
        DocumentFormat.OpenXml.Drawing.PictureLocks picLocks = new DocumentFormat.OpenXml.Drawing.PictureLocks(); 
        picLocks.NoChangeAspect = true; 
        picLocks.NoChangeArrowheads = true; 
        NonVisualPictureDrawingProperties nvpdp = new NonVisualPictureDrawingProperties(); 
        nvpdp.PictureLocks = picLocks; 
        NonVisualPictureProperties nvpp = new NonVisualPictureProperties(); 
        nvpp.NonVisualDrawingProperties = nvdp; 
        nvpp.NonVisualPictureDrawingProperties = nvpdp; 

        DocumentFormat.OpenXml.Drawing.Stretch stretch = new DocumentFormat.OpenXml.Drawing.Stretch(); 
        stretch.FillRectangle = new DocumentFormat.OpenXml.Drawing.FillRectangle();      

        BlipFill blipFill = new BlipFill(); 
        DocumentFormat.OpenXml.Drawing.Blip blip = new DocumentFormat.OpenXml.Drawing.Blip(); 
        blip.Embed = dp.GetIdOfPart(imgp); 
        blip.CompressionState = DocumentFormat.OpenXml.Drawing.BlipCompressionValues.Print; 
        blipFill.Blip = blip; 
        blipFill.SourceRectangle = new DocumentFormat.OpenXml.Drawing.SourceRectangle(); 
        blipFill.Append(stretch); 

        DocumentFormat.OpenXml.Drawing.Transform2D t2d = new DocumentFormat.OpenXml.Drawing.Transform2D(); 
        DocumentFormat.OpenXml.Drawing.Offset offset = new DocumentFormat.OpenXml.Drawing.Offset(); 
        offset.X = 1000; 
        offset.Y = 1000; 
        t2d.Offset = offset; 
        Bitmap bm = new Bitmap(sImagePath); 
        //http://en.wikipedia.org/wiki/English_Metric_Unit#DrawingML 
        //http://stackoverflow.com/questions/1341930/pixel-to-centimeter 
        //http://stackoverflow.com/questions/139655/how-to-convert-pixels-to-points-px-to-pt-in-net-c 
        DocumentFormat.OpenXml.Drawing.Extents extents = new DocumentFormat.OpenXml.Drawing.Extents(); 
        extents.Cx = (long)bm.Width * (long)((float)914400/bm.HorizontalResolution); 
        extents.Cy = (long)bm.Height * (long)((float)914400/bm.VerticalResolution); 
        bm.Dispose(); 
        t2d.Extents = extents; 
        ShapeProperties sp = new ShapeProperties(); 
        sp.BlackWhiteMode = DocumentFormat.OpenXml.Drawing.BlackWhiteModeValues.Auto; 
        sp.Transform2D = t2d; 
        DocumentFormat.OpenXml.Drawing.PresetGeometry prstGeom = new DocumentFormat.OpenXml.Drawing.PresetGeometry(); 
        prstGeom.Preset = DocumentFormat.OpenXml.Drawing.ShapeTypeValues.Rectangle; 
        prstGeom.AdjustValueList = new DocumentFormat.OpenXml.Drawing.AdjustValueList(); 
        sp.Append(prstGeom); 
        sp.Append(new DocumentFormat.OpenXml.Drawing.NoFill()); 

        DocumentFormat.OpenXml.Drawing.Spreadsheet.Picture picture = new DocumentFormat.OpenXml.Drawing.Spreadsheet.Picture(); 
        picture.NonVisualPictureProperties = nvpp; 
        picture.BlipFill = blipFill; 
        picture.ShapeProperties = sp; 

        Position pos = new Position(); 
        pos.X =(Int64) 1000; 
        pos.Y =(Int64) 1000; 
        Extent ext = new Extent(); 
        ext.Cx = extents.Cx; 
        ext.Cy = extents.Cy; 
        AbsoluteAnchor anchor = new AbsoluteAnchor(); 
        anchor.Position = pos; 
        anchor.Extent = ext; 
        anchor.Append(picture); 
        anchor.Append(new ClientData()); 
        WorksheetDrawing wsd = new WorksheetDrawing(); 
        wsd.Append(anchor); 
        Drawing drawing = new Drawing(); 
        drawing.Id = dp.GetIdOfPart(imgp); 

        wsd.Save(dp);      

        ws.Append(sd); 
        ws.Append(drawing); 
        wsp.Worksheet = ws; 
        wsp.Worksheet.Save(); 
        Sheets sheets = new Sheets(); 
        Sheet sheet = new Sheet(); 
        sheet.Name = "Sheet1"; 
        sheet.SheetId = 1; 
        sheet.Id = wbp.GetIdOfPart(wsp); 
        sheets.Append(sheet); 
        wb.Append(fv); 
        wb.Append(sheets); 

        xl.WorkbookPart.Workbook = wb; 
        xl.WorkbookPart.Workbook.Save(); 
        xl.Close(); 
       } 
      } 
      catch (Exception e) 
      { 
       Console.WriteLine(e.ToString()); 
       Console.ReadLine(); 
      } 
     } 


    } 
} 

Cette fonction code pour créer une nouvelle feuille de calcul Excel avec une image intégrée en elle. Cependant, j'ai été incapable de modifier ce code pour placer l'image où je veux sur la feuille de calcul. (Oui, j'ai essayé de changer la valeur du décalage.) Je n'ai également pas réussi à ajouter du texte ou des données numériques aux lignes et aux colonnes.

Est-ce que quelqu'un ici a eu ce travail?

+1

note: J'ai accès à l'espace de noms DocumentFormat.OpenXml, mais je n'ai aucune idée de la façon de l'utiliser et la documentation prête à confusion. –

Répondre

1

Jetez un oeil à la bibliothèque NPOI, qui est une excellente bibliothèque pour générer des documents Excel (et d'autres types Office) dans .Net.

Avec leur bibliothèque, ils ont un exemple montrant comment charger des images dans Excel, qui lit à partir d'un fichier. Comme vous pouvez avoir votre POPChart pouvez enregistrer les images en tant que flux de mémoire, vous pouvez facilement prendre leur exemple et le modifier pour lire à partir du flux de mémoire au lieu du fichier. Le reste du processus de génération Excel devrait être assez facile.

+1

Si cela vous aide à démarrer, j'ai récemment écrit un article sur l'utilisation de NPOI pour exporter de simples GridViews vers Excel. Vous pouvez le trouver ici: http://dillieodigital.wordpress.com/2010/10/19/soup-to-nuts-exporting-a-gridview-to-excel/ –

+0

Je suis désolé, je travaille dans une organisation qui a une liste de bibliothèques "approuvées" et c'est très court sur les bibliothèques CodePlex :-( –

0

Pour modifier l'emplacement de votre image, vous devez modifier rowId et columnId. Ils agissent comme des index de ligne et de colonne, donc si vous avez ColumnId cId = new ColumnId ("2"); et RowId rId = new RowId ("1"); votre image sera placée à la cellule C2. Vous devrez le faire deux fois, une fois pour les indices de départ et une fois pour les indices de fin si vous utilisez un deuxCellAnchor.