Generieren einer Excel-Datei in ASP.NET [geschlossen]

99

Ich bin dabei, einer ASP.NET-App (VB.NET-Codebehind) einen Abschnitt hinzuzufügen, der es einem Benutzer ermöglicht, Daten als Excel-Datei an ihn zurückzugeben, die ich basierend auf Datenbankdaten generieren werde. Es gibt verschiedene Möglichkeiten, dies zu tun, aber jede hat ihre eigenen Nachteile. Wie würden Sie die Daten zurückgeben? Ich suche etwas, das so sauber und unkompliziert wie möglich ist.

Dan Coates
quelle

Antworten:

131

CSV

Vorteile:

  • Einfach

Nachteile:

  • Es funktioniert möglicherweise nicht in anderen Gebietsschemas oder in anderen Excel-Konfigurationen (z. B. Listentrennzeichen).
  • Formatierungen, Formeln usw. Können nicht angewendet werden

HTML

Vorteile:

  • Immer noch ziemlich einfach
  • Unterstützt einfache Formatierungen und Formeln

Nachteile:

  • Sie müssen die Datei als xls benennen, und Excel warnt Sie möglicherweise vor dem Öffnen einer nicht nativen Excel-Datei
  • Ein Arbeitsblatt pro Arbeitsmappe

OpenXML (Office 2007 .XLSX)

Vorteile:

  • Natives Excel-Format
  • Unterstützt alle Excel-Funktionen
  • Sie nicht benötigen eine installieren Kopie von Excel
  • Kann Pivot-Tabellen generieren
  • Kann mit dem Open Source Projekt EPPlus generiert werden

Nachteile:

  • Eingeschränkte Kompatibilität außerhalb von Excel 2007 (sollte heutzutage kein Problem sein)
  • Kompliziert, es sei denn, Sie verwenden eine Komponente eines Drittanbieters

SpreadSheetML (offenes Format XML)

Vorteile:

  • Einfach im Vergleich zu nativen Excel-Formaten
  • Unterstützt die meisten Excel-Funktionen: Formatieren, Stile, Formeln, mehrere Blätter pro Arbeitsmappe
  • Excel muss nicht installiert sein, um es zu verwenden
  • Es werden keine Bibliotheken von Drittanbietern benötigt - schreiben Sie einfach Ihre XML aus
  • Dokumente können mit Excel XP / 2003/2007 geöffnet werden

Nachteile:

  • Mangel an guter Dokumentation
  • Wird in älteren Excel-Versionen (vor 2000) nicht unterstützt.
  • Nur Schreiben, sobald Sie es geöffnet und Änderungen in Excel vorgenommen haben, wird es in natives Excel konvertiert.

XLS (generiert von einer Drittanbieter-Komponente)

Vorteile:

  • Generieren Sie eine native Excel-Datei mit allen Formatierungen, Formeln usw.

Nachteile:

  • Kostet Geld
  • Abhängigkeiten hinzufügen

COM Interop

Vorteile:

  • Verwendet native Microsoft-Bibliotheken
  • Lesen Sie die Unterstützung für native Dokumente

Nachteile:

  • Sehr langsam
  • Probleme mit der Abhängigkeit / Versionsübereinstimmung
  • Probleme mit der Parallelität / Datenintegrität für die Webnutzung beim Lesen
  • Sehr langsam
  • Skalierungsprobleme für die Webnutzung (anders als bei der Parallelität): Es müssen viele Instanzen einer schweren Excel-App auf dem Server erstellt werden
  • Benötigt Windows
  • Habe ich erwähnt, dass es langsam ist?
Eduardo Molteni
quelle
1
Die für SpreadsheetML erwähnte Einschränkung "Nur Schreiben" ist kein vollständiges Problem, da Sie eine Excel-Datei auf Wunsch als SpreadsheetML speichern können.
Brian
1
SpreadsheetML kann Excel 2003 zum Absturz bringen, wenn Sie damit große Dateien erstellen. Traue es nicht: /
Brian
2
Sie können in Office 2002 und 2003 problemlos in einer SpreadsheetML-Datei speichern. Kein Speichern unter erforderlich. SpreadsheetML kann keine Makros, Diagramme, Grafiken und einige andere Kleinigkeiten speichern, einschließlich der neuen Funktionen von Office 2007 (z. B. mehr als 3 bedingte Formate). Da XML ausführlich ist, funktioniert das Zippen von SpreadsheetML vor dem Senden vom Server (die Verwendung von SharpZipLib ist eine Option) hervorragend, um die Downloadzeiten zu verkürzen. Eigentlich sollte erwähnt werden, dass OpenXML ohnehin in einem ZIP-Container gespeichert ist. @Brian: Ich verwende täglich komplexe SpreadsheetML im Bereich von 50 bis 100 MB, ohne dass Probleme auftreten.
richardtallent
Wenn die Möglichkeit besteht, dass Sie große Datenmengen exportieren müssen, sollten Sie diese als CSV exportieren. Abgesehen von SpreadsheetML ist es schwieriger, mit einem der anderen Formate eine performante Lösung zu finden. HTML kann effizient geschrieben und gelesen werden, benötigt jedoch weitere Spezifikationen, um nützlich zu sein. Sowohl HTML als auch SpreadsheetML haben andere Probleme mit großen Dateien, wie Brian in seinem Kommentar erwähnt. Wenn Sie also nur einen einfachen Datenexport benötigen, bleiben Sie bei CSV.
JohannesH
2
@pomarc: Es mag einfach sein, aber es ist nicht sauber. Der Benutzer möchte eine Excel-Datei und Sie geben ihm eine HTML-Datei mit einer gefälschten Erweiterung.
Heinzi
38

Sie können die Daten als HTML-Tabellenzellen ausgeben, eine .xlsoder eine .xlsxErweiterung darauf kleben , und Excel öffnet sie, als wäre es ein natives Dokument. Auf diese Weise können Sie sogar einige eingeschränkte Formatierungs- und Formelberechnungen durchführen, sodass es viel leistungsfähiger als CSV ist. Außerdem sollte die Ausgabe einer HTML-Tabelle von einer Webplattform wie ASP.Net aus ziemlich einfach sein;)

Wenn Sie mehrere Arbeitsblätter oder benannte Arbeitsblätter in Ihrer Excel-Arbeitsmappe benötigen, können Sie etwas Ähnliches über ein XML-Schema namens ausführen SpreadSheetML. Dies ist nicht das neue Format, das mit Office 2007 ausgeliefert wurde, sondern etwas völlig anderes, das bereits in Excel 2000 funktioniert. Der einfachste Weg, die Funktionsweise zu erklären, ist ein Beispiel:

<?xml version="1.0"?>
<?mso-application progid="Excel.Sheet"?> 
<Workbook xmlns="urn:schemas-microsoft-com:office:spreadsheet"
        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">
<DocumentProperties xmlns="urn:schemas-microsoft-com:office:office">
      <Author>Your_name_here</Author>
      <LastAuthor>Your_name_here</LastAuthor>
      <Created>20080625</Created>
      <Company>ABC Inc</Company>
      <Version>10.2625</Version>
</DocumentProperties>
<ExcelWorkbook xmlns="urn:schemas-microsoft-com:office:excel">
        <WindowHeight>6135</WindowHeight>
        <WindowWidth>8445</WindowWidth>
        <WindowTopX>240</WindowTopX>
        <WindowTopY>120</WindowTopY>
        <ProtectStructure>False</ProtectStructure>
        <ProtectWindows>False</ProtectWindows>
</ExcelWorkbook>

<Styles>
      <Style ss:ID="Default" ss:Name="Normal">
            <Alignment ss:Vertical="Bottom" />
            <Borders />
            <Font />
            <Interior />
            <NumberFormat />
            <Protection />
      </Style>
</Styles>

<Worksheet ss:Name="Sample Sheet 1">
<Table ss:ExpandedColumnCount="2" x:FullColumns="1" x:FullRows="1" ID="Table1">
<Column ss:Width="150" />
<Column ss:Width="200" />
<Row>
      <Cell><Data ss:Type="Number">1</Data></Cell>
      <Cell><Data ss:Type="Number">2</Data></Cell>
</Row>
<Row>
      <Cell><Data ss:Type="Number">3</Data></Cell>
      <Cell><Data ss:Type="Number">4</Data></Cell>
</Row>
<Row>
      <Cell><Data ss:Type="Number">5</Data></Cell>
      <Cell><Data ss:Type="Number">6</Data></Cell>
</Row>
<Row>
      <Cell><Data ss:Type="Number">7</Data></Cell>
      <Cell><Data ss:Type="Number">8</Data></Cell>
</Row>
</Table>
</Worksheet>

<Worksheet ss:Name="Sample Sheet 2">
<Table ss:ExpandedColumnCount="2" x:FullColumns="1" x:FullRows="1" ID="Table2">
<Column ss:Width="150" />
<Column ss:Width="200" />
<Row>
      <Cell><Data ss:Type="String">A</Data></Cell>
      <Cell><Data ss:Type="String">B</Data></Cell>
</Row>
<Row>
      <Cell><Data ss:Type="String">C</Data></Cell>
      <Cell><Data ss:Type="String">D</Data></Cell>
</Row>
<Row>
      <Cell><Data ss:Type="String">E</Data></Cell>
      <Cell><Data ss:Type="String">F</Data></Cell>
</Row>
<Row>
      <Cell><Data ss:Type="String">G</Data></Cell>
      <Cell><Data ss:Type="String">H</Data></Cell>
</Row>
</Table>
</Worksheet>
</Workbook> 
Joel Coehoorn
quelle
12
Sie können die Datei mit einer XML-Erweiterung umbenennen und Folgendes hinzufügen: <? mso-application progid = "Excel.Sheet"?> direkt nach der <? xml version = "1.0"?> auf diese Weise erkennen Windows, dass die Datei eine ist Excel-Datei, gibt ihr das richtige Symbol, öffnet Excel, wenn Sie auf die Datei klicken, und Excel beschwert sich nicht, dass das Dateiformat und der Inhalt nicht übereinstimmen. Tschüss.
Pomarc
1
@pomarc Der Nachteil dabei ist, dass andere Programme, die Excel-Dateien importieren, dies nicht erkennen. Aber dann würden sie die XML wahrscheinlich sowieso nicht analysieren.
Joel Coehoorn
1
Ich habe diese Technik ziemlich erfolgreich angewendet. Dies wäre meine Empfehlung - schmutzig einfach und sehr effektiv.
NealB
Zwei potenzielle Probleme (YMMV) mit HTML-Tabellendaten, die als XLS-Datei maskiert sind: (1) Microsoft Excel schneidet führende Leerzeichen und Nullen automatisch ab. und (2) Microsoft Excel 2010 warnt den Benutzer beim Öffnen einer XLS-Datei mit HTML-Tabellendaten. Die Lösung für # 1 scheint creativyst.com/Doc/Articles/CSV/CSV01.htm#CSVAndExcel zu sein (wenn führende Leerzeichen / Nullen signifikant sind und beibehalten werden müssen).
Iokevins
Nur zur Verdeutlichung, obwohl ich HTML-Tabellen erwähnt habe, ist der Hauptpunkt dieser Antwort SpreadsheetML, das mehr als nur HTML-Tabellendaten sind. Excel sieht es als nativ an.
Joel Coehoorn
16

Wenn Sie von einer Datentabelle kommen :

public static void DataTabletoXLS(DataTable DT, string fileName)
{
    HttpContext.Current.Response.Clear();
    HttpContext.Current.Response.Charset = "utf-16";
    HttpContext.Current.Response.ContentEncoding = System.Text.Encoding.GetEncoding("windows-1250");
    HttpContext.Current.Response.AddHeader("content-disposition", string.Format("attachment; filename={0}.xls", fileName));
    HttpContext.Current.Response.ContentType = "application/ms-excel";

    string tab = "";
    foreach (DataColumn dc in DT.Columns)
    {
        HttpContext.Current.Response.Write(tab + dc.ColumnName.Replace("\n", "").Replace("\t", ""));
        tab = "\t";
    }
    HttpContext.Current.Response.Write("\n");

    int i;
    foreach (DataRow dr in DT.Rows)
    {
        tab = "";
        for (i = 0; i < DT.Columns.Count; i++)
        {
            HttpContext.Current.Response.Write(tab + dr[i].ToString().Replace("\n", "").Replace("\t", ""));
            tab = "\t";
        }
        HttpContext.Current.Response.Write("\n");
    }
    HttpContext.Current.Response.End();
}

Aus einer Rasteransicht :

public static void GridviewtoXLS(GridView gv, string fileName)
{
    int DirtyBit = 0;
    int PageSize = 0;
    if (gv.AllowPaging == true)
    {
        DirtyBit = 1;
        PageSize = gv.PageSize;
        gv.AllowPaging = false;
        gv.DataBind();
    }

    HttpContext.Current.Response.Clear();
    HttpContext.Current.Response.Charset = "utf-8";
    HttpContext.Current.Response.ContentEncoding = System.Text.Encoding.GetEncoding("windows-1250");
    HttpContext.Current.Response.AddHeader(
        "content-disposition", string.Format("attachment; filename={0}.xls", fileName));
    HttpContext.Current.Response.ContentType = "application/ms-excel";

    using (StringWriter sw = new StringWriter())
    using (HtmlTextWriter htw = new HtmlTextWriter(sw))
    {
        //  Create a table to contain the grid
        Table table = new Table();

        //  include the gridline settings
        table.GridLines = gv.GridLines;

        //  add the header row to the table
        if (gv.HeaderRow != null)
        {
            Utilities.Export.PrepareControlForExport(gv.HeaderRow);
            table.Rows.Add(gv.HeaderRow);
        }

        //  add each of the data rows to the table
        foreach (GridViewRow row in gv.Rows)
        {
            Utilities.Export.PrepareControlForExport(row);
            table.Rows.Add(row);
        }

        //  add the footer row to the table
        if (gv.FooterRow != null)
        {
            Utilities.Export.PrepareControlForExport(gv.FooterRow);
            table.Rows.Add(gv.FooterRow);
        }

        //  render the table into the htmlwriter
        table.RenderControl(htw);

        //  render the htmlwriter into the response
        HttpContext.Current.Response.Write(sw.ToString().Replace("£", ""));
        HttpContext.Current.Response.End();
    }

    if (DirtyBit == 1)
    {
        gv.PageSize = PageSize;
        gv.AllowPaging = true;
        gv.DataBind();
    }
}

private static void PrepareControlForExport(Control control)
{
    for (int i = 0; i < control.Controls.Count; i++)
    {
        Control current = control.Controls[i];
        if (current is LinkButton)
        {
            control.Controls.Remove(current);
            control.Controls.AddAt(i, new LiteralControl((current as LinkButton).Text));
        }
        else if (current is ImageButton)
        {
            control.Controls.Remove(current);
            control.Controls.AddAt(i, new LiteralControl((current as ImageButton).AlternateText));
        }
        else if (current is HyperLink)
        {
            control.Controls.Remove(current);
            control.Controls.AddAt(i, new LiteralControl((current as HyperLink).Text));
        }
        else if (current is DropDownList)
        {
            control.Controls.Remove(current);
            control.Controls.AddAt(i, new LiteralControl((current as DropDownList).SelectedItem.Text));
        }
        else if (current is CheckBox)
        {
            control.Controls.Remove(current);
            control.Controls.AddAt(i, new LiteralControl((current as CheckBox).Checked ? "True" : "False"));
        }

        if (current.HasControls())
        {
            Utilities.Export.PrepareControlForExport(current);
        }
    }
}
SpoiledTechie.com
quelle
1
Nur der Code, den ich brauchte, danke. :)
Kjensen
Scott, was ist mit dem Pfundzeichen ("£")? Was ist, wenn ich es brauche? Irgendwelche anderen Charaktere, die gefährlich sind?
Piotr Owsiak
PERFEKT. Genau das, was ich brauchte.
Brad Bruce
Das £ -Zeichen ist eigentlich nur etwas, was ich für einen meiner Kunden brauchte. Sie können es herausnehmen.
SpoiledTechie.com
Zwei potenzielle Probleme (YMMV) mit HTML-Tabellendaten, die als XLS-Datei maskiert sind: (1) Microsoft Excel schneidet führende Leerzeichen und Nullen automatisch ab. und (2) Microsoft Excel 2010 warnt den Benutzer beim Öffnen einer XLS-Datei mit HTML-Tabellendaten. Die Lösung für # 1 scheint creativyst.com/Doc/Articles/CSV/CSV01.htm#CSVAndExcel zu sein (wenn führende Leerzeichen / Nullen signifikant sind und beibehalten werden müssen). CSV-Datendateien leiden auch unter # 1, wenn sie in Microsoft Excel geöffnet werden.
Iokevins
7

Dies ist ein kostenloser Wrapper für SpreadML - er funktioniert hervorragend.

http://www.carlosag.net/Tools/ExcelXmlWriter/

rp.
quelle
Ich habe das auch benutzt - es ist großartig.
Paul Suart
Diese Bibliothek ermöglicht auch das Lesen von xls?
Alex
5

Basierend auf den gegebenen Antworten und der Konsultation mit Kollegen scheint es die beste Lösung zu sein, entweder eine XML-Datei oder HTML-Tabellen zu generieren und sie als Anhang nach unten zu verschieben. Die einzige von meinen Mitarbeitern empfohlene Änderung besteht darin, dass die Daten (dh die HTML-Tabellen) direkt in das Response-Objekt geschrieben werden können, sodass keine Datei mehr geschrieben werden muss, was aufgrund von Berechtigungsproblemen, E / A, problematisch sein kann Streit und Sicherstellen, dass eine geplante Bereinigung erfolgt.

Hier ist ein Ausschnitt des Codes ... Ich habe dies noch nicht überprüft und nicht den gesamten aufgerufenen Code angegeben, aber ich denke, er repräsentiert die Idee gut.

    Dim uiTable As HtmlTable = GetUiTable(groupedSumData)

    Response.Clear()

    Response.ContentType = "application/vnd.ms-excel"
    Response.AddHeader("Content-Disposition", String.Format("inline; filename=OSSummery{0:ddmmssf}.xls", DateTime.Now))

    Dim writer As New System.IO.StringWriter()
    Dim htmlWriter As New HtmlTextWriter(writer)
    uiTable.RenderControl(htmlWriter)
    Response.Write(writer.ToString)

    Response.End()
Dan Coates
quelle
2
Dan, du bist auf dem richtigen Weg. Und ich empfehle SpreadsheetML definitiv über HTML - Raum für die Zukunft, da die HTML-Unterstützung frustrierend begrenzt ist. Bei HTML, SpreadsheetML und OpenXML können die Dateigrößen jedoch recht groß sein und werden vom Server nicht komprimiert. OpenXML erfordert einen ZIP-Container mit mehreren Dateien, und SpreadsheetML und HTML lassen sich viel schneller herunterladen, wenn Sie sie zuerst komprimieren und die Zip-Datei als Anhang senden. Verwenden Sie SharpZipLib und streamen Sie dorthin und nicht direkt zu Response.
richardtallent
4

Da Excel HTML versteht, können Sie die Daten einfach als HTML-Tabelle in eine temporäre Datei mit der Erweiterung .xls schreiben, die FileInfo für die Datei abrufen und sie mit zurückblasen

Response.Clear();
Response.AddHeader("Content-Disposition", "attachment; filename=" + fi.Name);
Response.AddHeader("Content-Length", fi.Length.ToString());
Response.ContentType = "application/octet-stream";
Response.WriteFile(fi.FullName);
Response.End();

Wenn Sie die temporäre Datei vermeiden möchten, können Sie in einen speicherinternen Stream schreiben und die Bytes zurückschreiben, anstatt WriteFile zu verwenden

Wenn der Header für die Inhaltslänge weggelassen wird, können Sie den HTML-Code einfach direkt zurückschreiben. Dies funktioniert jedoch möglicherweise nicht immer in allen Browsern

Steven A. Lowe
quelle
2
Zwei potenzielle Probleme (YMMV) mit HTML-Tabellendaten, die als XLS-Datei maskiert sind: (1) Microsoft Excel schneidet führende Leerzeichen und Nullen automatisch ab. und (2) Microsoft Excel 2010 warnt den Benutzer beim Öffnen einer XLS-Datei mit HTML-Tabellendaten. Die Lösung für # 1 scheint creativyst.com/Doc/Articles/CSV/CSV01.htm#CSVAndExcel zu sein (wenn führende Leerzeichen / Nullen signifikant sind und beibehalten werden müssen).
Iokevins
3

Ich persönlich bevorzuge die XML-Methode. Ich werde die Daten aus der Datenbank in einem Dataset zurückgeben, sie in XMl speichern, dann eine xslt-Datei erstellen, die eine Transformationsregel enthält, die ein ordnungsgemäßes Dokument formatiert, und eine einfache XML-Transformation beendet den Job. Das Beste daran ist, dass Sie Zellen formatieren, bedingte Formatierungen vornehmen, Kopf- und Fußzeilen einrichten und sogar Druckbereiche festlegen können.

Mitchel Sellers
quelle
2

Ich habe dies einige Male getan und jedes Mal war es am einfachsten, einfach eine CSV-Datei (Comma Separated Value) zurückzugeben. Excel importiert es perfekt und es ist relativ schnell zu tun.

Mark Allen
quelle
Ein potenzielles Problem (YMMV) mit CSV-Daten: Microsoft Excel schneidet führende Leerzeichen und Nullen automatisch ab
iokevins
2

Wir exportieren Daten aus einem Datagrid, um sie jederzeit zu übertreffen. Konvertieren Sie es in HTML und schreiben Sie es in eine Excel-Datei

Response.ContentType = "application/vnd.ms-excel"
    Response.Charset = ""
    Response.AddHeader("content-disposition", "fileattachment;filename=YOURFILENAME.xls")
    Me.EnableViewState = False
    Dim sw As System.IO.StringWriter = New System.IO.StringWriter
    Dim hw As HtmlTextWriter = New HtmlTextWriter(sw)
    ClearControls(grid)
    grid.RenderControl(hw)
    Response.Write(sw.ToString())
    Response.End()

Das einzige Problem bei dieser Methode war, dass viele unserer Gitter Schaltflächen oder Links enthielten, sodass Sie dies auch benötigen:

'needed to export grid to excel to remove link button control and represent as text
Private Sub ClearControls(ByVal control As Control)
    Dim i As Integer
    For i = control.Controls.Count - 1 To 0 Step -1
        ClearControls(control.Controls(i))
    Next i

    If TypeOf control Is System.Web.UI.WebControls.Image Then
        control.Parent.Controls.Remove(control)
    End If

    If (Not TypeOf control Is TableCell) Then
        If Not (control.GetType().GetProperty("SelectedItem") Is Nothing) Then
            Dim literal As New LiteralControl
            control.Parent.Controls.Add(literal)
            Try
                literal.Text = CStr(control.GetType().GetProperty("SelectedItem").GetValue(control, Nothing))
            Catch
            End Try
            control.Parent.Controls.Remove(control)
        Else
            If Not (control.GetType().GetProperty("Text") Is Nothing) Then
                Dim literal As New LiteralControl
                control.Parent.Controls.Add(literal)
                literal.Text = CStr(control.GetType().GetProperty("Text").GetValue(control, Nothing))
                control.Parent.Controls.Remove(control)
            End If
        End If
    End If
    Return
End Sub

Ich habe festgestellt, dass es irgendwo gut funktioniert.

WACM161
quelle
2
Zwei potenzielle Probleme (YMMV) mit HTML-Tabellendaten, die als XLS-Datei maskiert sind: (1) Microsoft Excel schneidet führende Leerzeichen und Nullen automatisch ab. und (2) Microsoft Excel 2010 warnt den Benutzer beim Öffnen einer XLS-Datei mit HTML-Tabellendaten. Die Lösung für # 1 scheint creativyst.com/Doc/Articles/CSV/CSV01.htm#CSVAndExcel zu sein (wenn führende Leerzeichen / Nullen signifikant sind und beibehalten werden müssen).
Iokevins
2

Hier ist ein Bericht, der aus einer gespeicherten Prozedur abgerufen wird. Die Ergebnisse werden nach Excel exportiert. Es verwendet ADO anstelle von ADO.NET und der Grund dafür ist diese Zeile

oSheet.Cells(2, 1).copyfromrecordset(rst1)

Es erledigt den größten Teil der Arbeit und ist in ado.net nicht verfügbar.

‘Calls stored proc in SQL Server 2000 and puts data in Excel and ‘formats it

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

        Dim cnn As ADODB.Connection
        cnn = New ADODB.Connection
        cnn.Open("Provider=SQLOLEDB;data source=xxxxxxx;" & _
          "database=xxxxxxxx;Trusted_Connection=yes;")

        Dim cmd As New ADODB.Command


        cmd.ActiveConnection = cnn


        cmd.CommandText = "[sp_TomTepley]"
        cmd.CommandType = ADODB.CommandTypeEnum.adCmdStoredProc
        cmd.CommandTimeout = 0
        cmd.Parameters.Refresh()


        Dim rst1 As ADODB.Recordset
        rst1 = New ADODB.Recordset
        rst1.Open(cmd)

        Dim oXL As New Excel.Application
        Dim oWB As Excel.Workbook
        Dim oSheet As Excel.Worksheet

        'oXL = CreateObject("excel.application")
        oXL.Visible = True
        oWB = oXL.Workbooks.Add
        oSheet = oWB.ActiveSheet

        Dim Column As Integer
        Column = 1

        Dim fld As ADODB.Field
        For Each fld In rst1.Fields

            oXL.Workbooks(1).Worksheets(1).Cells(1, Column).Value = fld.Name
            oXL.Workbooks(1).Worksheets(1).cells(1, Column).Interior.ColorIndex = 15
            Column = Column + 1

        Next fld

        oXL.Workbooks(1).Worksheets(1).name = "Tom Tepley Report"
        oSheet.Cells(2, 1).copyfromrecordset(rst1)
        oXL.Workbooks(1).Worksheets(1).Cells.EntireColumn.AutoFit()


        oXL.Visible = True
        oXL.UserControl = True

        rst1 = Nothing

        cnn.Close()
        Beep()

    End Sub
Siddharth Rout
quelle
1

Wenn Sie eine GridView mit Daten füllen, können Sie diese Funktion verwenden, um die HTML-formatierten Daten abzurufen. Der Browser zeigt jedoch an, dass es sich um eine Excel-Datei handelt.

 Public Sub ExportToExcel(ByVal fileName As String, ByVal gv As GridView)

        HttpContext.Current.Response.Clear()
        HttpContext.Current.Response.AddHeader("content-disposition", String.Format("attachment; filename={0}", fileName))
        HttpContext.Current.Response.ContentType = "application/ms-excel"

        Dim sw As StringWriter = New StringWriter
        Dim htw As HtmlTextWriter = New HtmlTextWriter(sw)
        Dim table As Table = New Table

        table.GridLines = gv.GridLines

        If (Not (gv.HeaderRow) Is Nothing) Then
            PrepareControlForExport(gv.HeaderRow)
            table.Rows.Add(gv.HeaderRow)
        End If

        For Each row As GridViewRow In gv.Rows
            PrepareControlForExport(row)
            table.Rows.Add(row)
        Next

        If (Not (gv.FooterRow) Is Nothing) Then
            PrepareControlForExport(gv.FooterRow)
            table.Rows.Add(gv.FooterRow)
        End If

        table.RenderControl(htw)

        HttpContext.Current.Response.Write(sw.ToString)
        HttpContext.Current.Response.End()

    End Sub


    Private Sub PrepareControlForExport(ByVal control As Control)

        Dim i As Integer = 0

        Do While (i < control.Controls.Count)

            Dim current As Control = control.Controls(i)

            If (TypeOf current Is LinkButton) Then
                control.Controls.Remove(current)
                control.Controls.AddAt(i, New LiteralControl(CType(current, LinkButton).Text))

            ElseIf (TypeOf current Is ImageButton) Then
                control.Controls.Remove(current)
                control.Controls.AddAt(i, New LiteralControl(CType(current, ImageButton).AlternateText))

            ElseIf (TypeOf current Is HyperLink) Then
                control.Controls.Remove(current)
                control.Controls.AddAt(i, New LiteralControl(CType(current, HyperLink).Text))

            ElseIf (TypeOf current Is DropDownList) Then
                control.Controls.Remove(current)
                control.Controls.AddAt(i, New LiteralControl(CType(current, DropDownList).SelectedItem.Text))

            ElseIf (TypeOf current Is CheckBox) Then
                control.Controls.Remove(current)
                control.Controls.AddAt(i, New LiteralControl(CType(current, CheckBox).Checked))

            End If

            If current.HasControls Then
                PrepareControlForExport(current)
            End If

            i = i + 1

        Loop

    End Sub
Eduardo Campañó
quelle
Zwei potenzielle Probleme (YMMV) mit HTML-Tabellendaten, die als XLS-Datei maskiert sind: (1) Microsoft Excel schneidet führende Leerzeichen und Nullen automatisch ab. und (2) Microsoft Excel 2010 warnt den Benutzer beim Öffnen einer XLS-Datei mit HTML-Tabellendaten. Die Lösung für # 1 scheint creativyst.com/Doc/Articles/CSV/CSV01.htm#CSVAndExcel zu sein (wenn führende Leerzeichen / Nullen signifikant sind und beibehalten werden müssen).
Iokevins
1

Vermeiden Sie einfach COM Interop über den Microsoft.Office.Interop-Namespace. Es ist so verdammt langsam und unzuverlässig und nicht skalierbar. Gilt nicht für Masochisten.

Andrei Rînea
quelle
1

Mit dieser Bibliothek können Sie ganz einfach gut formatierte Excel-Dateien erstellen: http://officehelper.codeplex.com/documentation .

Microsoft Office muss nicht auf dem Webserver installiert sein!

user698116
quelle
0

Ich gehe entweder die CSV-Route (wie oben beschrieben) oder verwende heutzutage häufiger Infragistics NetAdvantage, um die Datei zu generieren. (In den meisten Fällen, in denen Infragistics im Spiel ist, exportieren wir nur ein vorhandenes UltraWebGrid, bei dem es sich im Wesentlichen um eine Ein-LOC-Lösung handelt, sofern keine zusätzlichen Formatierungsänderungen erforderlich sind. Wir könnten auch manuell eine Excel / BIFF-Datei generieren. aber es gibt selten eine Notwendigkeit.)

John Rudy
quelle
0

Mann, in .net könnte man eine Komponente haben, die das kann, aber in klassischem asp habe ich es bereits getan, eine HTML-Tabelle zu erstellen und die MIME-Tabelle der Seite in vnd / msexcel zu ändern. Ich denke, wenn Sie eine Rasteransicht verwenden und den MIME-Typ ändern, sollte dies möglicherweise funktionieren, da die Rasteransicht eine HTML-Tabelle ist.


quelle
Zwei potenzielle Probleme (YMMV) mit HTML-Tabellendaten, die als XLS-Datei maskiert sind: (1) Microsoft Excel schneidet führende Leerzeichen und Nullen automatisch ab. und (2) Microsoft Excel 2010 warnt den Benutzer beim Öffnen einer XLS-Datei mit HTML-Tabellendaten. Die Lösung für # 1 scheint creativyst.com/Doc/Articles/CSV/CSV01.htm#CSVAndExcel zu sein (wenn führende Leerzeichen / Nullen signifikant sind und beibehalten werden müssen).
Iokevins
0

Die einzige kugelsichere Möglichkeit, die grünen Dreiecke "Es sieht so aus, als würden diese Zahlen als Text gespeichert" zu vermeiden, ist die Verwendung des Open XML-Formats. Es lohnt sich, es zu verwenden, nur um die unvermeidlichen grünen Dreiecke zu vermeiden.

hova
quelle
0

Die beste Methode, die ich für Excel-Berichte gesehen habe, besteht darin, die Daten in XML mit einer XML-Erweiterung zu schreiben und sie an Clients mit dem richtigen Inhaltstyp zu streamen. (application / xls)

Dies funktioniert für alle Berichte, für die eine grundlegende Formatierung erforderlich ist, und ermöglicht den Vergleich mit vorhandenen Tabellen mithilfe von Textvergleichstools.

Bravax
quelle
0

Angenommen, dies gilt für ein Intranet, in dem Sie Berechtigungen festlegen und den IE beauftragen können, können Sie die Arbeitsmappe clientseitig mit JScript / VBScript generieren, das Excel steuert . Auf diese Weise erhalten Sie eine native Excel-Formatierung, ohne mühsam versuchen zu müssen, Excel auf dem Server zu automatisieren.

Ich bin mir nicht sicher, ob ich diesen Ansatz wirklich empfehlen würde, außer in ziemlich Nischenszenarien, aber er war während der klassischen ASP-Blütezeit ziemlich häufig.

Mark Brackett
quelle
0

Sie können sich natürlich jederzeit für Komponenten von Drittanbietern entscheiden. Persönlich habe ich gute Erfahrungen mit Spire.XLS http://www.e-iceblue.com/xls/xlsintro.htm gemacht

Die Komponente ist in Ihrer Anwendung recht einfach zu verwenden:

        Workbook workbook = new Workbook();

        //Load workbook from disk.
        workbook.LoadFromFile(@"Data\EditSheetSample.xls");
        //Initailize worksheet
        Worksheet sheet = workbook.Worksheets[0];

        //Writes string
        sheet.Range["B1"].Text = "Hello,World!";
        //Writes number
        sheet.Range["B2"].NumberValue = 1234.5678;
        //Writes date
        sheet.Range["B3"].DateTimeValue = System.DateTime.Now;
        //Writes formula
        sheet.Range["B4"].Formula = "=1111*11111";

        workbook.SaveToFile("Sample.xls");
Nasir
quelle
0

Eines der Probleme, auf das ich mit einer der oben vorgeschlagenen Lösungen gestoßen bin, die dieser Antwort ähnlich sind besteht darin, dass Sie den Inhalt als Anhang herausschieben (was ich als die sauberste Lösung für Nicht-MS-Browser empfunden habe). Öffnen Sie es dann in Excel 2000-2003. Der Typ ist eine "Excel-Webseite" und kein natives Excel-Dokument.

Anschließend müssen Sie den Benutzern erklären, wie Sie "In Dateityp speichern" in Excel verwenden, um es in ein Excel-Dokument zu konvertieren. Dies ist ein Problem, wenn Benutzer dieses Dokument bearbeiten und dann erneut auf Ihre Website hochladen müssen.

Meine Empfehlung ist die Verwendung von CSV. Es ist einfach und wenn Benutzer es in Excel öffnen, fordert Excel sie zumindest auf, es in seinem nativen Format zu speichern.

Chad Braun-Duin
quelle
Sie müssen mit CSV vorsichtig sein, wenn Ihre Benutzer auf der ganzen Welt verstreut sind. Hier in Deutschland wird das Komma als Dezimaltrennzeichen und damit das Semikolon als Werttrennzeichen verwendet. Macht es schwierig, eine Datei zu erstellen, die in allen verschiedenen Kulturen lesbar ist. Daher würde ich für eines der XML-Formate stimmen.
Paul
0

Ich würde nur eine CSV-Datei basierend auf den Daten erstellen, da ich dies als die sauberste betrachte und Excel eine gute Unterstützung dafür hat. Wenn Sie jedoch ein flexibleres Format benötigen, gibt es sicher einige Tools von Drittanbietern zum Generieren von echten Excel-Dateien.

Alex Fort
quelle
0

Hier ist eine Lösung, die die Daten als CSV überträgt. Schnell, sauber und einfach und verarbeitet Kommas in der Eingabe.

public static void ExportToExcel(DataTable data, HttpResponse response, string fileName)
{
    response.Charset = "utf-8";
    response.ContentEncoding = System.Text.Encoding.GetEncoding("windows-1250");
    response.Cache.SetCacheability(HttpCacheability.NoCache);
    response.ContentType = "text/csv";
    response.AddHeader("Content-Disposition", "attachment; filename=" + fileName);

    for (int i = 0; i < data.Columns.Count; i++)
    {
       response.Write(data.Columns[i].ColumnName);
       response.Write(i == data.Columns.Count - 1 ? "\n" : ",");
    }        
    foreach (DataRow row in data.Rows)
    {
        for (int i = 0; i < data.Columns.Count; i++)
        {
            response.Write(String.Format("\"{0}\"", row[i].ToString()));
            response.Write(i == data.Columns.Count - 1 ? "\n" : ",");
        }
    }

    response.End();
}
Justin R.
quelle
-1

Ich habe gerade eine Funktion zum Exportieren aus einem Webformular C # erstellt, um zu hoffen, dass sie anderen hilft

    public void ExportFileFromSPData(string filename, DataTable dt)
    {
        HttpResponse response = HttpContext.Current.Response;

        //clean up the response.object
        response.Clear();
        response.Buffer = true;
        response.Charset = "";

        // set the response mime type for html so you can see what are you printing 
        //response.ContentType = "text/html";
        //response.AddHeader("Content-Disposition", "attachment;filename=test.html");

        // set the response mime type for excel
        response.ContentType = "application/vnd.ms-excel";
        response.AddHeader("Content-Disposition", "attachment;filename=\"" + filename + "\"");
        response.ContentEncoding = System.Text.Encoding.UTF8;
        response.BinaryWrite(System.Text.Encoding.UTF8.GetPreamble());

        //style to format numbers to string
        string style = @"<style> .text { mso-number-format:\@; } </style>";
        response.Write(style);

        // create a string writer
        using (StringWriter sw = new StringWriter())
        {
            using (HtmlTextWriter htw = new HtmlTextWriter(sw))
            {
                // instantiate a datagrid
                GridView dg = new GridView();
                dg.DataSource = dt;
                dg.DataBind();

                foreach (GridViewRow datarow in dg.Rows)
                {
                    //format specific cell to be text 
                    //to avoid 1.232323+E29 to get 1232312312312312124124
                    datarow.Cells[0].Attributes.Add("class", "text");
                }

                dg.RenderControl(htw);
                response.Write(sw.ToString());
                response.End();
            }
        }
     }
Steve D Sousa
quelle
-5

Wenn Sie Excel anstelle einer CSV-Datei verwenden müssen, müssen Sie die OLE-Automatisierung auf einer Excel-Instanz auf dem Server verwenden. Der einfachste Weg, dies zu tun, besteht darin, eine Vorlagendatei zu haben und diese programmgesteuert mit den Daten zu füllen. Sie speichern es in einer anderen Datei.

Tipps:

  • Mach es nicht interaktiv. Lassen Sie den Benutzer den Vorgang starten und dann eine Seite mit dem Link zur Datei veröffentlichen. Dies verringert potenzielle Leistungsprobleme, während die Tabelle generiert wird.
  • Verwenden Sie die Vorlage wie zuvor beschrieben. Es macht es einfacher, es zu ändern.
  • Stellen Sie sicher, dass Excel so eingestellt ist, dass keine Dialogfelder angezeigt werden. Auf einem Webserver hängt dies die gesamte Excel-Instanz.
  • Bewahren Sie die Excel-Instanz auf einem separaten Server auf, vorzugsweise hinter einer Firewall, damit sie nicht als potenzielle Sicherheitslücke angezeigt wird.
  • Behalten Sie die Ressourcennutzung im Auge. Das Generieren eines Spreadhseets über die OLE-Automatisierungsschnittstelle (die PIAs sind nur Shims darüber) ist ein ziemlich schwerer Prozess. Wenn Sie dies auf ein hohes Datenvolumen skalieren müssen, müssen Sie möglicherweise etwas clever mit Ihrer Architektur umgehen.

Einige der Ansätze zum Verwenden von MIME-Typen, um Excel zum Öffnen von HTML-Tabellen zu verleiten, funktionieren, wenn Sie nichts dagegen haben, dass das Format der Datei etwas grundlegend ist. Diese Ansätze befördern auch die CPU-Arbeit auf den Client. Wenn Sie das Format der Tabelle genau steuern möchten, müssen Sie wahrscheinlich Excel selbst verwenden, um die Datei wie oben beschrieben zu generieren.

ConcernedOfTunbridgeWells
quelle
Schlechte Idee, Automatisierung von einem Webserver aus durchzuführen. Die Alternativen mögen hackig erscheinen, aber sie werden wirklich viel besser funktionieren.
Joel Coehoorn
Wir verwenden serverseitiges OLE mit Excel und es ist ein großer Schmerz auf der Rückseite. Ohne das Risiko für unser Produkt ** würden wir eine andere Lösung wählen. ** Besser der Teufel, den du kennst ...
DaveE