Von einem unserer Kunden wurde ich beauftragt einen Ansatz zu konzipieren, wie seine komplexen Statistik-Dokumente (Excel) aus einer .Net-Webanwendung heraus generiert und bereitgestellt werden können.

Die Excel-Dokumente sollen sich dynamisch gemäß einer vorgelagerten Konfiguration aufbauen. Die Inhalte werden dabei aus einer Datenbank geladen und auf einzelne Arbeitsblätter in der Arbeitsmappe verteilt.

Open XML API:

Mein erster Ansatz bestand darin, die Excel-Dokumente  über die Open XML API programmatisch generieren zu lassen. Laut Microsoft ist das die präferierte Technologie.  Für Word Dokumente kann man die Open XML API auch wirklich sehr gut nutzen, wie ich bereits durch diverse Projekte bestätigen kann.

Für Excel kann ich diese API allerdings nicht empfehlen. Alle Versuche mein Dokument zu generieren schlugen fehl, da Excel immer irgendetwas zu beanstanden hatte und Reparaturen ankündigte. Dabei aber nicht mal explizit ausgab, was repariert wird. 

Nach einigen erfolglosen Versuchen habe ich dann über das Open XML Productivity Tool ein bereits vorhandenes Statistik-Excel Dokument – eine Vorlage vom Kunden – in .Net-Code umgewandelt. Insgesamt 14722 Lines of Code waren das erstaunliche Resultat!!! (Und das XLSX-Dokument war nicht mal sehr umfangreich!)

Danach habe ich diesen Ansatz dann verworfen. Für meine simplen Anforderungen war mir das einfach viel zu viel Overhead. Zumal der Kunde den Code anschließend selbst warten will und auf  fast 15000 Zeilen mit Sicherheit verzichten möchte.

XML-basierter Aufbau:

Um diesen ganzen Overhead zu vermeiden, habe ich dann geprüft, ob die Dokumente nicht ganz pragmatisch XML-basiert zusammenbaut werden können. Und genau dieser Ansatz funktioniert fantastisch!!!

Im ersten Schritt habe ich eine XML-Vorlage der Excel-Arbeitsmappe ohne Arbeitsblätter mit drei definierten Styles angefertigt. Diese wird von der Programmlogik geladen und programmatisch ergänzt.

 
  1. <?xmlversion=“1.0”encoding=“utf-8”?>
  2. <?mso-applicationprogid=“Excel.Sheet”?>
  3. <Workbook xmlns:o=“urn:schemas-microsoft-com:office:office” xmlns:x=“urn:schemas-microsoft-com:office:excel” xmlns:ss=“urn:schemas-microsoft-com:office:spreadsheet” xmlns:html=“http://www.w3.org/TR/REC-html40”xmlns=“urn:schemas-microsoft-com:office:spreadsheet”>
  4. <DocumentPropertiesxmlns=“urn:schemas-microsoft-com:office:office”>
  5. <Author>Andreas Witt</Author>
  6. </DocumentProperties>
  7. <Styles>
  8. <Style ss:ID=“Default”>
  9. <Font ss:FontName=“Tahoma” ss:Color=“#000000”/>
  10. <Alignment ss:Vertical=“Bottom”/>
  11. </Style>
  12. <Style ss:ID=“s16”>
  13. <Font ss:FontName=“Arial” x:Family=“Swiss” ss:Size=“12” ss:Color=“#000000”
  14. ss:Bold=“1”/>
  15. </Style>
  16. <Style ss:ID=“s17”>
  17. <Font ss:FontName=“Calibri” x:Family=“Swiss” ss:Size=“11” ss:Color=“#000000”
  18. ss:Bold=“1”/>
  19. </Style>
  20. <Style ss:ID=“s18”>
  21. <NumberFormat ss:Format=“Percent”/>
  22. </Style>
  23. </Styles>
  24. <!—Hier kommen die Worksheet-Tags –>
  25. </Workbook>

Nachfolgender Quelltext aus meinem Proof of Concept zeigt das programmatische Erstellen des Dokumentes mit Hilfe der .Net-Klasse XmlDocument. Das generierte XML-Dokument wird anschließend über eine ASPX MVC Anwendung zum Download bereitgestellt.. Dafür habe ich meinem “ExcelController” eine Aktion “DownloadStatistik” gegeben.

 
  1. ”’ <summary>  
  2.        ”’ Erstellt das Excel-Dokument und bietet es zum Download an  
  3.        ”’ </summary>  
  4.        ”’ <param name=”model”></param>  
  5.        ”’ <remarks></remarks>  
  6.        <HttpGet()>  
  7.        Public Sub DownloadExcel(ByVal model As StatistikKonfigurationModel)  
  8.  
  9.            Response.ClearHeaders()  
  10.            Response.ClearContent()  
  11.            Response.Clear()  
  12.            Response.Buffer = True 
  13.            Response.ContentType = “application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml”  
  14.            Response.AddHeader(“content-disposition”, “attachment; filename=Statistik.xml”)  
  15.            Response.Charset = “” 
  16.            ‘Me.EnableViewState = False  
  17.  
  18.            Dim ms As New MemoryStream  
  19.            CreateStatistikByXmL(ms)  
  20.  
  21.            ms.WriteTo(Response.OutputStream)  
  22.            Response.Flush()  
  23.  
  24.        End Sub 

Das Erstellen des Excel-Dokumentes habe ich auf vier Methoden aufgeteilt. Die erste Methode “CreateStatistkByXml” steuert den Aufbau des Dokumentes (Bspw. welche Arbeitsblätter erstellt werden sollen.).

Die zweite Methode “CreateWorksheet” fügt dem Dokument ein neues, leeres Arbeitsblatt hinzu. Dieses kann dann – wie nachfolgend beispielhaft mit der dritten Methode “CreateSheetContent” demonstriert – gefüllt werden. Dazu wird die letzte der vier Methoden “AppendLine” verwendet.

 
  1. #Region “XML”  
  2.         ”’ <summary>  
  3.         ”’ Erstellt das Statistik-Excel-Dokument  
  4.         ”’ </summary>  
  5.         ”’ <param name=”ms”>Der Memory Stream, der die Arbeitsmappe beinhaltet</param>  
  6.         ”’ <remarks></remarks>  
  7.         Private Sub CreateStatistikByXmL(ByVal ms As MemoryStream)  
  8.  
  9.             Dim xlsxDoc As XmlDocument = New XmlDocument()  
  10.             xlsxDoc.Load(HttpRuntime.AppDomainAppPath + “templateworkbook.xml”)  
  11.             Dim suffix As String = String.Empty  
  12.             ‘ suffix= DateTime.Now().ToShortDateString().Replace(“.”, “-“)  
  13.  
  14.             Dim worksheet1 As XmlNode = CreateWorksheet(xlsxDoc, String.Format(“Arbeitsblatt 1 {0}”, suffix))  
  15.             CreateSheetContent(xlsxDoc, worksheet1)  
  16.  
  17.             Dim worksheet2 As XmlNode = CreateWorksheet(xlsxDoc, String.Format(“Arbeitsblatt 2 {0}”, suffix))    
  18.             ‘Create Content of second worksheet here  
  19.  
  20.             Dim worksheet3 As XmlNode = CreateWorksheet(xlsxDoc, String.Format(“Arbeitsblatt 3 {0}”, suffix))    
  21.             ‘Create Content of third worksheet here  
  22.  
  23.             xlsxDoc.Save(ms)  
  24.         End Sub 
  25.  
  26.         ”’ <summary>  
  27.         ”’ Erstellt einen beispielhaften Inhalt für ein Arbeitsblatt  
  28.         ”’ </summary>  
  29.         ”’ <param name=”xlsxDoc”>Die übergeordnete Arbeistmappe</param>  
  30.         ”’ <param name=”worksheet”>Das Worksheet zum betanken</param>  
  31.         ”’ <remarks></remarks>  
  32.         Private Sub CreateSheetContent(ByVal xlsxDoc As XmlDocument, ByVal worksheet As XmlNode)  
  33.  
  34.             AppendLine(xlsxDoc, worksheet, New Dictionary(Of Integer, String) From {{0, “Mein Statistikbereich 1”}}, CellStyle.Title)  
  35.             ‘add blank  
  36.             AppendLine(xlsxDoc, worksheet, Nothing, Nothing)  
  37.             AppendLine(xlsxDoc, worksheet, New Dictionary(Of Integer, String) From {{0, “Gefundene Datensätze:”}}, CellStyle.Caption)  
  38.             AppendLine(xlsxDoc, worksheet, New Dictionary(Of Integer, String) From {{0, “Gesamt”}, {1, “640”}, {2, “100%”}}, Nothing)  
  39.             AppendLine(xlsxDoc, worksheet, New Dictionary(Of Integer, String) From {{0, “davon männlich”}, {1, “320”}, {2, “50%”}}, Nothing)  
  40.             AppendLine(xlsxDoc, worksheet, New Dictionary(Of Integer, String) From {{0, “davon weiblich”}, {1, “320”}, {2, “50%”}}, Nothing)  
  41.  
  42.         End Sub 
  43.  
  44.         ”’ <summary>  
  45.         ”’ Erstellt ein neues Arbeitsblatt  
  46.         ”’ </summary>  
  47.         ”’ <param name=”xlsxDoc”>Die übergeordnete Arbeitsmappe</param>  
  48.         ”’ <param name=”name”>Name des neuen Arbeitsblattes</param>  
  49.         ”’ <returns>Das neu erstellte Arbeitsblatt</returns>  
  50.         ”’ <remarks></remarks>  
  51.         Private Function CreateWorksheet(ByVal xlsxDoc As XmlDocument, ByVal name As String) As XmlNode  
  52.             ‘ Create a new element node.   
  53.             Dim worksheet As XmlNode = xlsxDoc.CreateElement(“Worksheet”, xlsxDoc.DocumentElement.NamespaceURI)  
  54.             Dim attribute As XmlAttribute = xlsxDoc.CreateAttribute(“ss”, “Name”, “urn:schemas-microsoft-com:office:spreadsheet”)  
  55.             attribute.Value = name  
  56.             worksheet.Attributes.Append(attribute)  
  57.  
  58.             Dim table As XmlNode = xlsxDoc.CreateElement(“Table”, xlsxDoc.DocumentElement.NamespaceURI)  
  59.             Dim fcAttribute As XmlAttribute = xlsxDoc.CreateAttribute(“ss”, “FullColumns”, “urn:schemas-microsoft-com:office:spreadsheet”)  
  60.             fcAttribute.Value = “1” 
  61.             table.Attributes.Append(fcAttribute)  
  62.  
  63.             Dim frAttribute As XmlAttribute = xlsxDoc.CreateAttribute(“ss”, “FullRows”, “urn:schemas-microsoft-com:office:spreadsheet”)  
  64.             frAttribute.Value = “1” 
  65.             table.Attributes.Append(frAttribute)  
  66.  
  67.             Dim eccAttribute As XmlAttribute = xlsxDoc.CreateAttribute(“ss”, “ExpandedColumnCount”, “urn:schemas-microsoft-com:office:spreadsheet”)  
  68.             eccAttribute.Value = “4” 
  69.             table.Attributes.Append(eccAttribute)  
  70.  
  71.             Dim column As XmlNode = xlsxDoc.CreateElement(“Column”, xlsxDoc.DocumentElement.NamespaceURI)  
  72.             Dim afwAttribute As XmlAttribute = xlsxDoc.CreateAttribute(“ss”, “AutoFitWidth”, “urn:schemas-microsoft-com:office:spreadsheet”)  
  73.             afwAttribute.Value = “0” 
  74.             column.Attributes.Append(afwAttribute)  
  75.             Dim wAttribute As XmlAttribute = xlsxDoc.CreateAttribute(“ss”, “Width”, “urn:schemas-microsoft-com:office:spreadsheet”)  
  76.             wAttribute.Value = “266.25” 
  77.             column.Attributes.Append(wAttribute)  
  78.  
  79.             table.AppendChild(column)  
  80.  
  81.             ‘ leere Tabelle vorerst  
  82.             ‘ hier kämen sonst Rows und Cells  
  83.  
  84.             worksheet.AppendChild(table)  
  85.  
  86.             ‘Ab hier werden die Eigenschaften der des Arbeitsblattes gesetzt  
  87.             Dim options As XmlNode = xlsxDoc.CreateNode(XmlNodeType.Element, “WorksheetOptions”, “urn:schemas-microsoft-com:office:excel”)  
  88.             Dim pageSetup = xlsxDoc.CreateElement(“PageSetup”, “urn:schemas-microsoft-com:office:excel”)  
  89.  
  90.             Dim header = xlsxDoc.CreateElement(“Header”, “urn:schemas-microsoft-com:office:excel”)  
  91.             Dim marginAttr As XmlAttribute = xlsxDoc.CreateAttribute(“Margin”)  
  92.             marginAttr.Value = “0.3” 
  93.             header.Attributes.Append(marginAttr)  
  94.             Dim footer = xlsxDoc.CreateElement(“Footer”, “urn:schemas-microsoft-com:office:excel”)  
  95.             footer.Attributes.Append(marginAttr.Clone())  
  96.  
  97.             Dim pageMargins = xlsxDoc.CreateElement(“PageMargins”, “urn:schemas-microsoft-com:office:excel”)  
  98.             Dim bootomAttr As XmlAttribute = xlsxDoc.CreateAttribute(“Bottom”)  
  99.             bootomAttr.Value = “0.75” 
  100.             Dim leftAttr As XmlAttribute = xlsxDoc.CreateAttribute(“Left”)  
  101.             leftAttr.Value = “0.7” 
  102.             Dim rightAttr As XmlAttribute = xlsxDoc.CreateAttribute(“Right”)  
  103.             rightAttr.Value = “0.7” 
  104.             Dim topAttr As XmlAttribute = xlsxDoc.CreateAttribute(“Top”)  
  105.             topAttr.Value = “0.75” 
  106.  
  107.             pageMargins.Attributes.Append(bootomAttr)  
  108.             pageMargins.Attributes.Append(leftAttr)  
  109.             pageMargins.Attributes.Append(rightAttr)  
  110.             pageMargins.Attributes.Append(topAttr)  
  111.  
  112.             pageSetup.AppendChild(header)  
  113.             pageSetup.AppendChild(footer)  
  114.             pageSetup.AppendChild(pageMargins)  
  115.  
  116.             options.AppendChild(pageSetup)  
  117.  
  118.             Dim print = xlsxDoc.CreateElement(“Print”, “urn:schemas-microsoft-com:office:excel”)  
  119.             print.AppendChild(xlsxDoc.CreateElement(“ValidPrinterInfo”, “urn:schemas-microsoft-com:office:excel”))  
  120.             Dim fitHeight = xlsxDoc.CreateElement(“FitHeight”, “urn:schemas-microsoft-com:office:excel”)  
  121.             fitHeight.InnerText = “1” 
  122.             print.AppendChild(fitHeight)  
  123.             Dim fitWidth = xlsxDoc.CreateElement(“FitWidth”, “urn:schemas-microsoft-com:office:excel”)  
  124.             fitWidth.InnerText = “1” 
  125.             print.AppendChild(fitWidth)  
  126.  
  127.             Dim scale = xlsxDoc.CreateElement(“Scale”, “urn:schemas-microsoft-com:office:excel”)  
  128.             scale.InnerText = “100” 
  129.             print.AppendChild(scale)  
  130.  
  131.             options.AppendChild(print)  
  132.             options.AppendChild(xlsxDoc.CreateElement(“Selected”, “urn:schemas-microsoft-com:office:excel”))  
  133.  
  134.             worksheet.AppendChild(options)  
  135.             xlsxDoc.DocumentElement.AppendChild(worksheet)  
  136.             Return worksheet  
  137.         End Function 
  138.  
  139.         ”’ <summary>  
  140.         ”’ Fügt eine neue Zeile zum Arbeitsplatt hinzu  
  141.         ”’ </summary>  
  142.         ”’ <param name=”xlsxDoc”>Die übergeordnete Arbeitsmappe </param>  
  143.         ”’ <param name=”worksheet”>Das Arbeitsblatt, dem einen neue Zeile hinzugefügt werden soll</param>  
  144.         ”’ <param name=”columnValuelist”>Eine Liste aus Splaten-Index und dem dazugehörigen Text-Wert</param>  
  145.         ”’ <param name=”style”>Einen der bestehenden Styles für die Darstellung</param>  
  146.         ”’ <remarks></remarks>  
  147.         Private Sub AppendLine(ByVal xlsxDoc As XmlDocument, ByVal worksheet As XmlNode, ByVal columnValuelist As Dictionary(Of Integer, String), ByVal style As CellStyle)  
  148.             Dim newRow As XmlElement = xlsxDoc.CreateElement(“Row”, xlsxDoc.DocumentElement.NamespaceURI)  
  149.             If Not IsNothing(columnValuelist) Then 
  150.                 Dim max As Integer = columnValuelist.Keys.ToList().Max()  
  151.  
  152.                 For i = 0 To max  
  153.                     Dim newCell As XmlElement = xlsxDoc.CreateElement(“Cell”, xlsxDoc.DocumentElement.NamespaceURI)  
  154.                     Dim newData As XmlNode = xlsxDoc.CreateElement(“Data”, xlsxDoc.DocumentElement.NamespaceURI)  
  155.                     Dim typAttribute As XmlAttribute = xlsxDoc.CreateAttribute(“ss”, “Type”, “urn:schemas-microsoft-com:office:spreadsheet”)  
  156.                     typAttribute.Value = “String” 
  157.                     newData.Attributes.Append(typAttribute)  
  158.  
  159.                     If columnValuelist.ContainsKey(i) Then 
  160.                         If Not style = 0 Then 
  161.                             Dim styleAttribute As XmlAttribute = xlsxDoc.CreateAttribute(“ss”, “StyleID”, “urn:schemas-microsoft-com:office:spreadsheet”)  
  162.                             styleAttribute.Value = “s” + DirectCast(style, Integer).ToString()  
  163.                             newCell.Attributes.Append(styleAttribute)  
  164.                         End If 
  165.                         newData.InnerText = columnValuelist(i)  
  166.                     End If 
  167.                     newCell.AppendChild(newData)  
  168.                     newRow.AppendChild(newCell)  
  169.                 Next 
  170.             End If 
  171.  
  172.             ‘worksheet.FirstChild = <Table>  
  173.             worksheet.FirstChild.AppendChild(newRow)  
  174.         End Sub 
  175.  
  176. #End Region

Das generierte Excel-Dokument in Form einer XML-Kalkulationstabelle sieht dann letztendlich wie folgt aus:

 
  1. <?xml version=“1.0” encoding=“utf-8”?> 
  2. <?mso-application progid=“Excel.Sheet”?> 
  3. <Workbook xmlns:o=“urn:schemas-microsoft-com:office:office” xmlns:x=“urn:schemas-microsoft-com:office:excel” xmlns:ss=“urn:schemas-microsoft-com:office:spreadsheet” xmlns:html=“http://www.w3.org/TR/REC-html40” xmlns=“urn:schemas-microsoft-com:office:spreadsheet”> 
  4.   <DocumentProperties xmlns=“urn:schemas-microsoft-com:office:office”> 
  5.     <Author>Andreas Witt</Author> 
  6.   </DocumentProperties> 
  7.   <Styles> 
  8.     <Style ss:ID=“Default”> 
  9.       <Font ss:FontName=“Tahoma” ss:Color=“#000000” /> 
  10.       <Alignment ss:Vertical=“Bottom” /> 
  11.     </Style> 
  12.     <Style ss:ID=“s16”> 
  13.       <Font ss:FontName=“Arial” x:Family=“Swiss” ss:Size=“12” ss:Color=“#000000” ss:Bold=“1” /> 
  14.     </Style> 
  15.     <Style ss:ID=“s17”> 
  16.       <Font ss:FontName=“Calibri” x:Family=“Swiss” ss:Size=“11” ss:Color=“#000000” ss:Bold=“1” /> 
  17.     </Style> 
  18.     <Style ss:ID=“s18”> 
  19.       <NumberFormat ss:Format=“Percent” /> 
  20.     </Style> 
  21.   </Styles> 
  22.   <Worksheet ss:Name=“Arbeitsblatt 1 “> 
  23.     <Table ss:FullColumns=“1” ss:FullRows=“1” ss:ExpandedColumnCount=“4”> 
  24.       <Column ss:AutoFitWidth=“0” ss:Width=“266.25” /> 
  25.       <Row> 
  26.         <Cell ss:StyleID=“s16”> 
  27.           <Data ss:Type=“String”>Mein Statistikbereich 1</Data> 
  28.         </Cell> 
  29.       </Row> 
  30.       <Row /> 
  31.       <Row> 
  32.         <Cell ss:StyleID=“s17”> 
  33.           <Data ss:Type=“String”>Gefundene Datensätze:</Data> 
  34.         </Cell> 
  35.       </Row> 
  36.       <Row> 
  37.         <Cell> 
  38.           <Data ss:Type=“String”>Gesamt</Data> 
  39.         </Cell> 
  40.         <Cell> 
  41.           <Data ss:Type=“String”>640</Data> 
  42.         </Cell> 
  43.         <Cell> 
  44.           <Data ss:Type=“String”>100%</Data> 
  45.         </Cell> 
  46.       </Row> 
  47.       <Row> 
  48.         <Cell> 
  49.           <Data ss:Type=“String”>davon männlich</Data> 
  50.         </Cell> 
  51.         <Cell> 
  52.           <Data ss:Type=“String”>320</Data> 
  53.         </Cell> 
  54.         <Cell> 
  55.           <Data ss:Type=“String”>50%</Data> 
  56.         </Cell> 
  57.       </Row> 
  58.       <Row> 
  59.         <Cell> 
  60.           <Data ss:Type=“String”>davon weiblich</Data> 
  61.         </Cell> 
  62.         <Cell> 
  63.           <Data ss:Type=“String”>320</Data> 
  64.         </Cell> 
  65.         <Cell> 
  66.           <Data ss:Type=“String”>50%</Data> 
  67.         </Cell> 
  68.       </Row> 
  69.     </Table> 
  70.     <WorksheetOptions xmlns=“urn:schemas-microsoft-com:office:excel”> 
  71.       <PageSetup> 
  72.         <Header Margin=“0.3” /> 
  73.         <Footer Margin=“0.3” /> 
  74.         <PageMargins Bottom=“0.75” Left=“0.7” Right=“0.7” Top=“0.75” /> 
  75.       </PageSetup> 
  76.       <Print> 
  77.         <ValidPrinterInfo /> 
  78.         <FitHeight>1</FitHeight> 
  79.         <FitWidth>1</FitWidth> 
  80.         <Scale>100</Scale> 
  81.       </Print> 
  82.       <Selected /> 
  83.     </WorksheetOptions> 
  84.   </Worksheet> 
  85.   <Worksheet ss:Name=“Arbeitsblatt 2 “> 
  86.     <Table ss:FullColumns=“1” ss:FullRows=“1” ss:ExpandedColumnCount=“4”> 
  87.       <Column ss:AutoFitWidth=“0” ss:Width=“266.25” /> 
  88.     </Table> 
  89.     <WorksheetOptions xmlns=“urn:schemas-microsoft-com:office:excel”> 
  90.       <PageSetup> 
  91.         <Header Margin=“0.3” /> 
  92.         <Footer Margin=“0.3” /> 
  93.         <PageMargins Bottom=“0.75” Left=“0.7” Right=“0.7” Top=“0.75” /> 
  94.       </PageSetup> 
  95.       <Print> 
  96.         <ValidPrinterInfo /> 
  97.         <FitHeight>1</FitHeight> 
  98.         <FitWidth>1</FitWidth> 
  99.         <Scale>100</Scale> 
  100.       </Print> 
  101.       <Selected /> 
  102.     </WorksheetOptions> 
  103.   </Worksheet> 
  104.   <Worksheet ss:Name=“Arbeitsblatt 3 “> 
  105.     <Table ss:FullColumns=“1” ss:FullRows=“1” ss:ExpandedColumnCount=“4”> 
  106.       <Column ss:AutoFitWidth=“0” ss:Width=“266.25” /> 
  107.     </Table> 
  108.     <WorksheetOptions xmlns=“urn:schemas-microsoft-com:office:excel”> 
  109.       <PageSetup> 
  110.         <Header Margin=“0.3” /> 
  111.         <Footer Margin=“0.3” /> 
  112.         <PageMargins Bottom=“0.75” Left=“0.7” Right=“0.7” Top=“0.75” /> 
  113.       </PageSetup> 
  114.       <Print> 
  115.         <ValidPrinterInfo /> 
  116.         <FitHeight>1</FitHeight> 
  117.         <FitWidth>1</FitWidth> 
  118.         <Scale>100</Scale> 
  119.       </Print> 
  120.       <Selected /> 
  121.     </WorksheetOptions> 
  122.   </Worksheet> 
  123. </Workbook> 

Durch die Direktive “<?mso-applicationprogid=“Excel.Sheet”?>“ öffnet sich die Datei direkt in Excel.

image

Dieser pragmatische Ansatz ist exakt auf die Anforderungen des Kunden zugeschnitten und in Punkto Wartung und Weiterentwicklung optimiert. Warum also umständlich und teuer, wenn es auch einfach und zielführend geht!!!

P.S.: Nur für die, die sich jetzt wundern: VB.Net war eine Vorgabe vom Kunden! Ehrlich!!!

2 Comments

  1. Pingback: Aus der Praxis: Excel-Dokumente generieren (the simple way) - SharePoint Blogs in German - Bamboo Nation

  2. avatar
    Antworten

    Der pragmatische Weg über eine Xml-Datei ist eine sehr gute Entscheidung in solchen Fällen!

    Nur ein Tipp: Hinsichtlich der Wartbarkeit im Zusammenhang mit Xml stellt VB.NET gegenüber C# sogar einen nicht zu unterschätzenden Vorteil dar, da die Sprache sog. Xml Literals unterstützt. Der umständliche Weg, Xml über Methoden und Parameter “zu Fuß” zu generieren bleibt einem somit erspart und die direkte Einbettung von Xml im Code führt zu einem sofortigen Verständnis.

    Einen schönen Überblick dazu gibt es z.B. auf CodeProject und ansonsten natürlich auch wie gewohnt im MSDN.

    http://www.codeproject.com/Articles/71954/XML-Literals

Leave a comment

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.

Time limit is exhausted. Please reload the CAPTCHA.