Wie erstelle ich eine Excel-Datei (.XLS und .XLSX) in C #, ohne Microsoft Office zu installieren?


1891

Wie kann ich eine Excel-Tabelle mit C # erstellen, ohne dass Excel auf dem Computer installiert werden muss, auf dem der Code ausgeführt wird?


Das "... ohne Ms Office zu installieren?" Ein Teil der Frage klingt sehr unprofessionell. Sie können jeden Dateityp aus einem C # -Programm generieren (wobei eine xlsoder xlsx-Datei eine davon ist). Es ist nicht erforderlich, dass sich auf Ihrem Computer ein Programm befindet, das es lesen kann (z. B. binär).
Mike

30
@Mike Das Stück "ohne dass Excel installiert werden muss" hat nichts damit zu tun, professionell zu sein. Es geht um Abhängigkeiten. Der ursprüngliche Text der Frage lautete wie folgt: "Idealerweise möchte ich Open Source, damit ich meinem Code keine Abhängigkeiten von Drittanbietern hinzufügen muss, und ich möchte vermeiden, Excel direkt zum Erstellen der Datei zu verwenden (mit OLE) Automatisierung.) " Es ist bedauerlich, dass die Frage drastisch vereinfacht wurde.
Tony

5
Angenommen, Sie haben versucht, etwas ohne Bibliothek oder externen Code zu tun, kann ich nicht für XLS-Dateien sprechen, aber für XLSX-Dateien, warum nicht zunächst eine vorhandene übernehmen, sie in eine Zip-Datei umbenennen und den Inhalt untersuchen? Ein bisschen Reverse Engineering wird Ihnen einiges verraten. In den verschiedenen Ordnern und Unterordnern befinden sich verschiedene XML- und Rel-Dateien. Versuchen Sie, dies zu untersuchen, und prüfen Sie, ob Sie es replizieren können oder ob Sie Dokumentation zu den verschiedenen XML-Namespaces / -Schemas finden.
Alexander Ryan Baggett

@AlexanderRyanBaggett Das war sehr hilfreich! Ich bin auf diesen Beitrag gestoßen, als ich an der automatischen Berichterstellung und dem Durchsuchen von Dokumenten als Zip-Archiv gearbeitet habe. Er bietet einen umfassenden Einblick in die Erstellung einer Dokumentdatei.
SentientFlesh

Antworten:


1055

Sie können eine Bibliothek namens ExcelLibrary verwenden. Es ist eine kostenlose Open-Source-Bibliothek, die auf Google Code veröffentlicht wird:

ExcelLibrary

Dies scheint ein Port des oben erwähnten PHP ExcelWriter zu sein. Es wird noch nicht in das neue XLSX-Format geschrieben, aber sie arbeiten daran, diese Funktionalität hinzuzufügen.

Es ist sehr einfach, klein und einfach zu bedienen. Außerdem verfügt es über einen DataSetHelper, mit dem Sie DataSets und DataTables verwenden können, um problemlos mit Excel-Daten zu arbeiten.

ExcelLibrary scheint immer noch nur für das ältere Excel-Format (XLS-Dateien) zu funktionieren, unterstützt jedoch möglicherweise in Zukunft neuere Formate für 2007/2010.

Sie können auch EPPlus verwenden , das nur für Dateien im Excel 2007/2010-Format (XLSX-Dateien) funktioniert. Es gibt auch NPOI, die mit beiden funktioniert.

Es gibt einige bekannte Fehler in jeder Bibliothek, wie in den Kommentaren angegeben. Insgesamt scheint EPPlus im Laufe der Zeit die beste Wahl zu sein. Es scheint auch aktiver aktualisiert und dokumentiert zu werden.

Wie von @ АртёмЦарионов unten angegeben, unterstützt EPPlus Pivot-Tabellen und ExcelLibrary unterstützt möglicherweise ( Pivot-Tabellenproblem in ExcelLibrary )

Hier einige Links zur schnellen Referenz:
ExcelLibrary - GNU Lesser GPL
EPPlus - GNU Lesser General Public License (LGPL)
NPOI - Apache-Lizenz

Hier ein Beispielcode für ExcelLibrary:

Hier ist ein Beispiel, in dem Daten aus einer Datenbank entnommen und daraus eine Arbeitsmappe erstellt werden. Beachten Sie, dass der ExcelLibrary-Code die einzelne Zeile unten ist:

//Create the data set and table
DataSet ds = new DataSet("New_DataSet");
DataTable dt = new DataTable("New_DataTable");

//Set the locale for each
ds.Locale = System.Threading.Thread.CurrentThread.CurrentCulture;
dt.Locale = System.Threading.Thread.CurrentThread.CurrentCulture;

//Open a DB connection (in this example with OleDB)
OleDbConnection con = new OleDbConnection(dbConnectionString);
con.Open();

//Create a query and fill the data table with the data from the DB
string sql = "SELECT Whatever FROM MyDBTable;";
OleDbCommand cmd = new OleDbCommand(sql, con);
OleDbDataAdapter adptr = new OleDbDataAdapter();

adptr.SelectCommand = cmd;
adptr.Fill(dt);
con.Close();

//Add the table to the data set
ds.Tables.Add(dt);

//Here's the easy part. Create the Excel worksheet from the data set
ExcelLibrary.DataSetHelper.CreateWorkbook("MyExcelFile.xls", ds);

So einfach ist das Erstellen der Excel-Datei. Sie können Excel-Dateien auch manuell erstellen, aber die oben genannten Funktionen haben mich wirklich beeindruckt.


247
ExcelLibrary wurde durch das außergewöhnliche EPPlus - epplus.codeplex.com - ersetzt . Jan aktualisiert es regelmäßig. Ich habe es benutzt und es ist eines der besten Open Source-Projekte, mit denen wir gearbeitet haben.
Mark A

3
Es ist zu beachten, dass ExcelLibrary beim Umgang mit großen Datenmengen (mehr als 5000 Zeilen mit vielen Spalten) viele Leistungsprobleme aufweist. Derzeit wird die Codebasis bei der Arbeit stark modifiziert, damit wir sie in einem Projekt verwenden können.
Rossisdead

EPPlus scheint weit weniger fehlerhaft zu sein als ExcelLibrary, ABER es ist GPL und daher nur eine Lösung für Open Source-Projekte.
Seth


6
Was ist mit ClosedXML ? Ich kann mich in Ihren Projekten als nützlich erweisen.
Amadeus Sánchez

589

Wenn Sie mit dem xlsx-Format zufrieden sind, probieren Sie mein GitHub-Projekt EPPlus aus . Es begann mit der Quelle von ExcelPackage, aber heute ist es ein komplettes Umschreiben. Es unterstützt Bereiche, Zellenstil, Diagramme, Formen, Bilder, benannte Bereiche, AutoFilter und viele andere Dinge.


77
Lizenz ist jetzt LGPL, Versionshinweise
Simon D

13
Die Beispiele waren hilfreich. Ich konnte meinen Code innerhalb weniger Stunden von der Verwendung der Microsoft Interop-Bibliothek (schrecklich langsam) auf diese Bibliothek (Version 4.x) ändern. Mein Benchmark schreibt eine Datei mit zwei Registerkarten und ungefähr 750.000 Zellen. Mit MS Interop dauerte es 13 Minuten. Mit EPPlus dauerte es 10 Sekunden, was einer etwa 80-fachen Beschleunigung entspricht. Sehr glücklich!
Paul Chernoch

3
Aus Gründen der Übersichtlichkeit in diesem Thread ermöglicht die LGPL die Verknüpfung der Software, ohne dass der infektiöse Teil der GPL auftritt. Sie müssen nur Quelländerungen öffnen, die Sie an ClosedXml vornehmen, oder wenn Sie den Quellcode direkt in Ihre Anwendung einfügen (anstatt auf die ClosedXml-Assemblys zu verweisen), müssen Sie Ihre Anwendung als Open Source-Datei verwenden.
Chris Marisic

4
@ Paul Chernoch: Wir füllen große Excel-Tabellen sehr schnell mit Interop. Das Geheimnis besteht darin, ein Massenupdate durchzuführen. Erstellen Sie einen Objektblock [,], füllen Sie diesen aus und schreiben Sie diese Matrix gleichzeitig in Excel: excelWorksheet.get_Range (Bereich) .Value2 = Block;
Marc Meketon

2
Es sieht so aus, als würde die Lizenzierung von LGPL auf Polyform Noncommercial 1.0.0 umgestellt
Luke

175

Und was ist mit Open XML SDK 2.0 für Microsoft Office?

Einige Vorteile:

  • Erfordert keine Installation von Office
  • Hergestellt von Microsoft = anständige MSDN-Dokumentation
  • Nur eine .Net-DLL zur Verwendung im Projekt
  • Das SDK enthält viele Tools wie Diff, Validator usw.

Links:


3
Es ist wichtig zu beachten, dass die DLL hierfür etwas mehr als 5 MB groß und auf Office 2007-Formate beschränkt ist. Aber sicherlich die einfachste und schnellste Lösung, die für mich funktioniert.
Josh Brown

18
Nur ein Hinweis darauf, dass v2.5 herauskommt und hier heruntergeladen werden kann .
Snuffleupagus

10
Das SDK modelliert das XML in Klassen, sodass jedes XML-Tag einem Tag zugeordnet wird. Anschließend müssen Sie die Klassenhierarchie (jede Instanz verfügt über eine Sammlung untergeordneter Instanzen / Tags) korrekt erstellen. Dies bedeutet, dass Sie die XML-Struktur einer Excel-Datei kennen müssen, was sehr kompliziert ist. Es ist viel einfacher, einen Wrapper wie EPPlus zu verwenden, der die Dinge vereinfacht.
Tsahi Asher

2
Ein großartiges Beispiel für Microsoft Open XML SDK - Open XML Writer finden Sie unter polymathprogrammer.com/2012/08/06/… oder unter Stack Overflow-Lösung stackoverflow.com/questions/11370672/…
Greg

4
Ich fand den Open XML Writer des Microsoft Open XML SDK großartig. Mit den oben genannten Lösungen (insbesondere Vincent Toms Beispiel (Poly Math)) ist es einfach, einen Writer zu erstellen, der große Datenmengen durchströmt und Datensätze auf eine Weise schreibt, die der von Ihnen gewünschten ähnelt und nicht zu komplex ist CSV; aber dass du stattdessen xml schreibst. Open XML ist die Denkweise, in der Microsoft die neuen Office-Formate betrachtet. Sie können sie jederzeit von .xslx- in .zip-Dateien umbenennen, wenn Sie ihre XML-Inhalte durchsuchen möchten.
Greg

167

Ich habe mit Erfolg die folgenden Open Source-Projekte verwendet:

  • ExcelPackage für OOXML-Formate (Office 2007)

  • NPOI für das XLS-Format (Office 2003). NPOI 2.0 (Beta) unterstützt auch XLSX.

Schauen Sie sich meine Blog-Beiträge an:

Erstellen von Excel-Tabellen .XLS und .XLSX in C #

NPOI mit Excel-Tabelle und dynamischem Diagramm


6
Ein Hinweis zu NPOI - Zeilen- und Spaltenreferenzen basieren auf Null. Funktioniert gut zum Auffüllen einer vorhandenen Vorlage.
John M

108

Mit OLEDB können Sie Excel-Dateien erstellen und bearbeiten. Überprüfen Sie Folgendes : Lesen und Schreiben von Excel mit OLEDB .

Typisches Beispiel:

using (OleDbConnection conn = new OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\\temp\\test.xls;Extended Properties='Excel 8.0;HDR=Yes'"))
{
  conn.Open();
  OleDbCommand cmd = new OleDbCommand("CREATE TABLE [Sheet1] ([Column1] string, [Column2] string)", conn);
  cmd.ExecuteNonQuery();
}

EDIT - Einige weitere Links:


4
Kann jemand bestätigen, ob dies unter x64 funktioniert? Ich bin mir ziemlich sicher, dass Jet nur funktioniert, wenn Ihre App kompiliert ist oder im 32-Bit-Modus ausgeführt wird.
Lamar

2
Ich habe diese Verbindung gerade getestet und sie ist auf einem Windows Server 2008 R2 x64 RC fehlgeschlagen. Es scheint, als müsste man den 2007 Office System-Treiber installieren: Datenkonnektivitätskomponenten [ microsoft.com/downloads/…
Chris Richner

25
Seien Sie sehr vorsichtig damit - es ist ein großer hässlicher Fehler (zum Beispiel errät es manchmal einen Spaltentyp und verwirft alle Daten, die nicht passen).
dbkk

9
Bei dieser Methode sollte man sehr vorsichtig sein. Ich fand es sehr flockig für Daten, die nicht in einem perfekten Format vorliegen.
Kenny Mann

9
Als eine Person, die OleDb in einem großen Projekt verwenden musste, sage ich, bleiben Sie davon fern! Manchmal kann ein Zellenwert nicht abgerufen werden, nur weil das Format nicht verstanden werden konnte. Es gibt keinen Löschvorgang. Es funktioniert auch bei einem geringfügigen Anbieterwechsel völlig anders und unvorhersehbar. Ich würde sagen, entscheiden Sie sich für eine bewährte kommerzielle Lösung.
Caner Öncü

80

Die kommerzielle Lösung SpreadsheetGear für .NET wird dies tun.

Sie können Live - ASP.NET (C # und VB) Proben siehe hier und laden Sie eine Testversion hier .

Haftungsausschluss: Ich besitze SpreadsheetGear LLC


10
Sie haben ein großartiges Produkt, aber ich denke, viele Leute hier erwarten kostenlose Lösungen. Das könnte die Abstimmungen erklären.
Md1337

65

Einige Optionen, die ich verwendet habe:

Wenn XLSX ein Muss ist: ExcelPackage ist ein guter Anfang, aber es ist ausgestorben, als der Entwickler aufgehört hat, daran zu arbeiten. ExML nahm von dort auf und fügte einige Funktionen hinzu. ExML ist keine schlechte Option, ich verwende es immer noch auf einigen Produktionswebsites.

Für alle meine neuen Projekte verwende ich jedoch NPOI , den .NET-Port von Apache POI . NPOI 2.0 (Alpha) unterstützt auch XLSX.


Seien Sie vorsichtig mit ExcelPackage, wenn Sie XLS unterstützen müssen. Ich hatte es schwer damit und wechselte schließlich zu ExcelLibrary.
Jeremy

Definitiv wahr. ExcelPackage / ExML ist nur dann eine gute Option, wenn Sie die XLSX-Unterstützung benötigen.
Nate

5
Beachten Sie, dass ExcelPackage einen Nachfolger hat: EPPlus ( epplus.codeplex.com ), der XLSX unterstützt. Meine einzige Sorge im Vergleich zu NPOI ist zum Beispiel die Leistung, z. B. wenn es viele Spalten gibt.
Pragmateek

63

Eine extrem leichte Option kann die Verwendung von HTML-Tabellen sein. Erstellen Sie einfach Kopf-, Text- und Tabellen-Tags in einer Datei und speichern Sie sie als Datei mit der Erweiterung .xls. Es gibt Microsoft-spezifische Attribute, mit denen Sie die Ausgabe formatieren können, einschließlich Formeln.

Mir ist klar, dass Sie dies möglicherweise nicht in einer Webanwendung codieren, aber hier ist ein Beispiel für die Zusammensetzung einer Excel-Datei über eine HTML-Tabelle. Diese Technik kann verwendet werden, wenn Sie eine Konsolen-App, eine Desktop-App oder einen Dienst codieren.


6
Es ist so ad hoc, aber es funktioniert (ganz zu schweigen davon, dass Excel beim Öffnen eine Warnung ausgibt) und es ist so einfach, dass es einen Platz als Lösung verdient. Obwohl nur um zu zeigen, dass Sie eine Excel-Datei exportieren können :))
Luka Ramishvili

3
Diese Lösung hat bei mir gut funktioniert. Beachten Sie jedoch, dass Sie die Erweiterung .xlsx nicht verwenden können
Jill

Einige Mitarbeiter meiner Organisation können Excel-Dateien, die auf diese Weise in Office 2010 und höher erstellt wurden, nicht öffnen. Ich weiß nicht, was das Problem ist, aber ich musste meine eigene OpenXML-Implementierung rollen. (siehe Soggers Antwort)
Kristen Hammack

49

Wenn Sie Excel 2007/2010-Dateien erstellen, probieren Sie dieses Open Source-Projekt aus: https://github.com/closedxml/closedxml

Es bietet eine objektorientierte Möglichkeit, die Dateien (ähnlich wie VBA) zu bearbeiten, ohne die Probleme von XML-Dokumenten zu lösen. Es kann von jeder .NET-Sprache wie C # und Visual Basic (VB) verwendet werden.

Mit ClosedXML können Sie Excel 2007/2010-Dateien ohne die Excel-Anwendung erstellen. Das typische Beispiel ist das Erstellen von Excel-Berichten auf einem Webserver:

var workbook = new XLWorkbook();
var worksheet = workbook.Worksheets.Add("Sample Sheet");
worksheet.Cell("A1").Value = "Hello World!";
workbook.SaveAs("HelloWorld.xlsx");

9
Ich habe versucht, dies in einem Projekt zu verwenden, das ziemlich große Excel-Tabellen erstellt. Ausgezeichnete Bibliothek, aber extrem schlechte Leistung. Ich habe gerade einen Vergleich für das Projekt durchgeführt, an dem ich arbeite: ClosedXML (Version 0.53.3) benötigte 92.489 ms, während EPPlus (Version 2.9.03 zum Testen - wir können es nicht verwenden, weil es GPL ist) 16.500 ms benötigte.
Druide

1
@Druid die Lizenz ist LGPL, vorausgesetzt, Sie ändern den Quellcode nicht in ClosedXML. Es ist kostenlos, epplus.codeplex.com/license
Chris Marisic


47

Vielleicht möchten Sie tatsächlich die in C # verfügbaren Interop-Klassen überprüfen (z Microsoft.Office.Interop.Excel. B. Sie sagen kein OLE (was dies nicht ist), aber die Interop-Klassen sind sehr einfach zu verwenden. Lesen Sie hier die C # -Dokumentation (Interop für Excel beginnt am) Seite 1072 des C # PDF).

Sie könnten beeindruckt sein, wenn Sie sie nicht ausprobiert haben.

Bitte seien Sie vor der Haltung von Microsoft zu diesem Thema gewarnt :

Microsoft empfiehlt und unterstützt derzeit keine Automatisierung von Microsoft Office-Anwendungen aus unbeaufsichtigten, nicht interaktiven Clientanwendungen oder -komponenten (einschließlich ASP-, ASP.NET-, DCOM- und NT-Diensten), da Office möglicherweise instabiles Verhalten und / oder instabiles Verhalten aufweist oder Deadlock, wenn Office in dieser Umgebung ausgeführt wird.


6
Aber Sie müssen sicherstellen, dass Sie alles manuell entsorgen, sonst
verlieren

8
@ Ricky B: Nach meiner Erfahrung mit dem Interop wird auch Excel verwendet. Jedes Mal, wenn wir es verwendeten und Excel nicht auf dem Computer installiert war, erhielten wir COM-Ausnahmen.
MagicKat

1
Mit dem OLE geht trotz sehr sorgfältiger Entsorgung möglicherweise Speicherplatz verloren oder es stürzt ab. Dies ist für besuchte Anwendungen / Workstations wohl in Ordnung, für Server wird jedoch nicht empfohlen (MS verfügt über eine KB, die dies angibt). Für unseren Server starten wir ihn einfach jede Nacht neu. Auch das funktioniert OK.
Jennifer Zouak

11
@Geoffrey: ah OK, Sie werden mich dazu bringen, dafür zu arbeiten :) -> support.microsoft.com/kb/257757 Microsoft empfiehlt und unterstützt die Automatisierung von Microsoft Office-Anwendungen von unbeaufsichtigten, nicht unbeaufsichtigten Anwendungen derzeit nicht. interaktive Client-Anwendung ...
Jennifer Zouak

4
Ich komme zu dieser Diskussion, nachdem ich mehr als eine Woche mit Interop zu kämpfen habe, und wenn Ihre Bedürfnisse nicht sehr einfach sind, wird dies nicht funktionieren. Die Unterstützung für die Formatierung Ihrer Tabelle ist miserabel, was wohl der Grund für die Generierung einer XLS-Datei und nicht nur einer flachen CSV-Datei ist. Haben Sie beispielsweise versucht, mehr als 911 Zeichen in einer Zelle auszugeben, oder haben Sie versucht, die Breite zusammengeführter Zellen auf konsistente Weise festzulegen? Ich habe, und ich kann Ihnen nicht sagen, wie sehr ich diesen Mist jetzt hasse ... Tun Sie sich selbst einen Gefallen und gehen Sie mit einer der freien Bibliotheken, die in dieser Diskussion erwähnt wurden.
Md1337

34

Hier ist eine völlig freie C # Bibliothek, die Sie von einem exportieren können DataSet, DataTableoder List<>in eine echte Excel 2007 XLSX - Datei, die OpenXML - Bibliotheken:

http://mikesknowledgebase.com/pages/CSharp/ExportToExcel.htm

Der vollständige Quellcode wird kostenlos zusammen mit Anweisungen und einer Demo-Anwendung bereitgestellt.

Nachdem Sie diese Klasse zu Ihrer Anwendung hinzugefügt haben, können Sie Ihr DataSet in nur einer Codezeile nach Excel exportieren:

CreateExcelFile.CreateExcelDocument(myDataSet, "C:\\Sample.xlsx");

Einfacher geht es nicht ...

Und es ist nicht einmal erforderlich, dass Excel auf Ihrem Server vorhanden ist.


1
Dies scheint etwas irreführend zu sein, da Sie um eine Spende bitten, um alle Funktionen nutzen zu können.
UrbanEsc

Das stimmt teilweise: Die völlig kostenlose Version generiert eine perfekte XLSX-Datei für Sie und der gesamte Quellcode wird bereitgestellt. Wenn Sie 10 USD oder mehr an eine dieser beiden Wohltätigkeitsorganisationen spenden (von denen ich absolut nichts bekomme), erhalten Sie eine "bessere" Version, die zeigt, wie Formatierungen, Daten usw. vorgenommen werden. Angesichts der Kosten für Produkte von Drittanbietern rechne ich damit Es lohnt sich, stattdessen 10 US-Dollar für einen guten Zweck zu spenden!
Mike Gledhill


23

Vielleicht möchten Sie einen Blick auf GemBox.Spreadsheet werfen .

Sie haben eine kostenlose Version mit allen Funktionen, sind jedoch auf 150 Zeilen pro Blatt und 5 Blätter pro Arbeitsmappe beschränkt, wenn dies Ihren Anforderungen entspricht.

Ich musste es noch nicht selbst benutzen, sieht aber interessant aus.


21

Syncfusion Essential XlsIO kann dies tun. Es ist nicht von Microsoft Office abhängig und bietet spezifische Unterstützung für verschiedene Plattformen.

Codebeispiel:

//Creates a new instance for ExcelEngine.
ExcelEngine excelEngine = new ExcelEngine();
//Loads or open an existing workbook through Open method of IWorkbooks
IWorkbook workbook = excelEngine.Excel.Workbooks.Open(fileName);
//To-Do some manipulation|
//To-Do some manipulation
//Set the version of the workbook.
workbook.Version = ExcelVersion.Excel2013;
//Save the workbook in file system as xlsx format
workbook.SaveAs(outputFileName);

Die gesamte Kontrollsuite ist über das Community-Lizenzprogramm kostenlos verfügbar , wenn Sie sich qualifizieren (weniger als 1 Million USD Umsatz). Hinweis: Ich arbeite für Syncfusion.


18

Gut,

Sie können auch eine Drittanbieter-Bibliothek wie Aspose verwenden .

Diese Bibliothek hat den Vorteil, dass Excel nicht auf Ihrem Computer installiert werden muss, was in Ihrem Fall ideal wäre.


Genauer gesagt können Sie Aspose.Cells for .NET verwenden, um Excel-Dateien (XLS, XLSX) in Ihrer .NET-Anwendung zu erstellen.
Shahzad Latif

9
Ja, Sie können, wenn es Ihnen nichts ausmacht, eine Mindestlizenzgebühr von 999 US-Dollar zu zahlen. Probieren Sie die MikesKnowledgeBase-Bibliothek aus, die 999 US-Dollar billiger ist!
Mike Gledhill

17

OpenXML ist auch eine gute Alternative, um die Installation von MS Excel auf einem Server zu vermeiden. Das von Microsoft bereitgestellte Open XML SDK 2.0 vereinfacht die Bearbeitung von Open XML-Paketen und den zugrunde liegenden Open XML-Schemaelementen innerhalb eines Pakets. Die Open XML Application Programming Interface (API) enthält viele allgemeine Aufgaben, die Entwickler für Open XML-Pakete ausführen.

Schauen Sie sich OpenXML: Alternative an, um die Installation von MS Excel auf dem Server zu vermeiden


17

Die verschiedenen verfügbaren Office 2003-XML-Bibliotheken eignen sich recht gut für kleinere Excel-Dateien. Ich finde jedoch die schiere Größe einer großen Arbeitsmappe, die im XML-Format gespeichert ist, ein Problem. Eine Arbeitsmappe, mit der ich arbeite, ist beispielsweise 40 MB im neuen (und zugegebenermaßen dichter gepackten) XLSX-Format und wird zu einer 360 MB XML-Datei.

Nach meinen Recherchen gibt es zwei kommerzielle Pakete, die die Ausgabe in ältere Binärdateiformate ermöglichen. Sie sind:

Weder sind billig (500 USD bzw. 800 USD, denke ich). Beide arbeiten jedoch unabhängig von Excel.

Was mich interessieren würde, ist das Excel-Ausgabemodul für OpenOffice.org. Ich frage mich, ob sie von Java nach .Net portiert werden können.


Dieser funktioniert sowohl auf .net als auch auf Java und ist nicht teuer. SmartXLS smartxls.com
liya


15

Ich habe erst kürzlich FlexCel.NET verwendet und festgestellt, dass es sich um eine hervorragende Bibliothek handelt! Ich sage das nicht über zu viele Softwareprodukte. Es macht keinen Sinn, hier das gesamte Verkaufsgespräch zu führen. Sie können alle Funktionen auf ihrer Website lesen.

Es ist ein kommerzielles Produkt, aber Sie erhalten die vollständige Quelle, wenn Sie es kaufen. Ich nehme an, Sie könnten es in Ihre Assembly kompilieren, wenn Sie es wirklich wollten. Ansonsten ist es nur eine zusätzliche Baugruppe für xcopy - keine Konfiguration oder Installation oder ähnliches.

Ich glaube nicht, dass Sie ohne Bibliotheken von Drittanbietern einen Weg finden werden, dies zu tun, da .NET Framework offensichtlich keine Unterstützung dafür eingebaut hat und OLE Automation nur eine ganze Welt voller Schmerzen ist.


15

Ich habe einen einfachen Code zum Exportieren eines Datasets nach Excel geschrieben, ohne ein Excel-Objekt mithilfe von System.IO.StreamWriter zu verwenden.

Unten finden Sie den Code, mit dem alle Tabellen aus dem Datensatz gelesen und einzeln in die Blätter geschrieben werden. Ich habe Hilfe von diesem Artikel genommen .

public static void exportToExcel(DataSet source, string fileName)
{
        const string endExcelXML = "</Workbook>";
        const string startExcelXML = "<xml version>\r\n<Workbook " +
                 "xmlns=\"urn:schemas-microsoft-com:office:spreadsheet\"\r\n" +
                 " xmlns:o=\"urn:schemas-microsoft-com:office:office\"\r\n " +
                 "xmlns:x=\"urn:schemas-    microsoft-com:office:" +
                 "excel\"\r\n xmlns:ss=\"urn:schemas-microsoft-com:" +
                 "office:spreadsheet\">\r\n <Styles>\r\n " +
                 "<Style ss:ID=\"Default\" ss:Name=\"Normal\">\r\n " +
                 "<Alignment ss:Vertical=\"Bottom\"/>\r\n <Borders/>" +
                 "\r\n <Font/>\r\n <Interior/>\r\n <NumberFormat/>" +
                 "\r\n <Protection/>\r\n </Style>\r\n " +
                 "<Style ss:ID=\"BoldColumn\">\r\n <Font " +
                 "x:Family=\"Swiss\" ss:Bold=\"1\"/>\r\n </Style>\r\n " +
                 "<Style     ss:ID=\"StringLiteral\">\r\n <NumberFormat" +
                 " ss:Format=\"@\"/>\r\n </Style>\r\n <Style " +
                 "ss:ID=\"Decimal\">\r\n <NumberFormat " +
                 "ss:Format=\"0.0000\"/>\r\n </Style>\r\n " +
                 "<Style ss:ID=\"Integer\">\r\n <NumberFormat " +
                 "ss:Format=\"0\"/>\r\n </Style>\r\n <Style " +
                 "ss:ID=\"DateLiteral\">\r\n <NumberFormat " +
                 "ss:Format=\"mm/dd/yyyy;@\"/>\r\n </Style>\r\n " +
                 "</Styles>\r\n ";
        System.IO.StreamWriter excelDoc = null;
        excelDoc = new System.IO.StreamWriter(fileName);

        int sheetCount = 1;
        excelDoc.Write(startExcelXML);
        foreach (DataTable table in source.Tables)
        {
            int rowCount = 0;
            excelDoc.Write("<Worksheet ss:Name=\"" + table.TableName + "\">");
            excelDoc.Write("<Table>");
            excelDoc.Write("<Row>");
            for (int x = 0; x < table.Columns.Count; x++)
            {
                excelDoc.Write("<Cell ss:StyleID=\"BoldColumn\"><Data ss:Type=\"String\">");
                excelDoc.Write(table.Columns[x].ColumnName);
                excelDoc.Write("</Data></Cell>");
            }
            excelDoc.Write("</Row>");
            foreach (DataRow x in table.Rows)
            {
                rowCount++;
                //if the number of rows is > 64000 create a new page to continue output
                if (rowCount == 64000)
                {
                    rowCount = 0;
                    sheetCount++;
                    excelDoc.Write("</Table>");
                    excelDoc.Write(" </Worksheet>");
                    excelDoc.Write("<Worksheet ss:Name=\"" + table.TableName + "\">");
                    excelDoc.Write("<Table>");
                }
                excelDoc.Write("<Row>"); //ID=" + rowCount + "
                for (int y = 0; y < table.Columns.Count; y++)
                {
                    System.Type rowType;
                    rowType = x[y].GetType();
                    switch (rowType.ToString())
                    {
                        case "System.String":
                            string XMLstring = x[y].ToString();
                            XMLstring = XMLstring.Trim();
                            XMLstring = XMLstring.Replace("&", "&");
                            XMLstring = XMLstring.Replace(">", ">");
                            XMLstring = XMLstring.Replace("<", "<");
                            excelDoc.Write("<Cell ss:StyleID=\"StringLiteral\">" +
                                           "<Data ss:Type=\"String\">");
                            excelDoc.Write(XMLstring);
                            excelDoc.Write("</Data></Cell>");
                            break;
                        case "System.DateTime":
                            //Excel has a specific Date Format of YYYY-MM-DD followed by  
                            //the letter 'T' then hh:mm:sss.lll Example 2005-01-31T24:01:21.000
                            //The Following Code puts the date stored in XMLDate 
                            //to the format above
                            DateTime XMLDate = (DateTime)x[y];
                            string XMLDatetoString = ""; //Excel Converted Date
                            XMLDatetoString = XMLDate.Year.ToString() +
                                 "-" +
                                 (XMLDate.Month < 10 ? "0" +
                                 XMLDate.Month.ToString() : XMLDate.Month.ToString()) +
                                 "-" +
                                 (XMLDate.Day < 10 ? "0" +
                                 XMLDate.Day.ToString() : XMLDate.Day.ToString()) +
                                 "T" +
                                 (XMLDate.Hour < 10 ? "0" +
                                 XMLDate.Hour.ToString() : XMLDate.Hour.ToString()) +
                                 ":" +
                                 (XMLDate.Minute < 10 ? "0" +
                                 XMLDate.Minute.ToString() : XMLDate.Minute.ToString()) +
                                 ":" +
                                 (XMLDate.Second < 10 ? "0" +
                                 XMLDate.Second.ToString() : XMLDate.Second.ToString()) +
                                 ".000";
                            excelDoc.Write("<Cell ss:StyleID=\"DateLiteral\">" +
                                         "<Data ss:Type=\"DateTime\">");
                            excelDoc.Write(XMLDatetoString);
                            excelDoc.Write("</Data></Cell>");
                            break;
                        case "System.Boolean":
                            excelDoc.Write("<Cell ss:StyleID=\"StringLiteral\">" +
                                        "<Data ss:Type=\"String\">");
                            excelDoc.Write(x[y].ToString());
                            excelDoc.Write("</Data></Cell>");
                            break;
                        case "System.Int16":
                        case "System.Int32":
                        case "System.Int64":
                        case "System.Byte":
                            excelDoc.Write("<Cell ss:StyleID=\"Integer\">" +
                                    "<Data ss:Type=\"Number\">");
                            excelDoc.Write(x[y].ToString());
                            excelDoc.Write("</Data></Cell>");
                            break;
                        case "System.Decimal":
                        case "System.Double":
                            excelDoc.Write("<Cell ss:StyleID=\"Decimal\">" +
                                  "<Data ss:Type=\"Number\">");
                            excelDoc.Write(x[y].ToString());
                            excelDoc.Write("</Data></Cell>");
                            break;
                        case "System.DBNull":
                            excelDoc.Write("<Cell ss:StyleID=\"StringLiteral\">" +
                                  "<Data ss:Type=\"String\">");
                            excelDoc.Write("");
                            excelDoc.Write("</Data></Cell>");
                            break;
                        default:
                            throw (new Exception(rowType.ToString() + " not handled."));
                    }
                }
                excelDoc.Write("</Row>");
            }
            excelDoc.Write("</Table>");
            excelDoc.Write(" </Worksheet>");
            sheetCount++;
        }


        excelDoc.Write(endExcelXML);
        excelDoc.Close();
    }

1
Wie der Artikel jedoch sagt, ist dies XML, das Excel liest, anstatt tatsächlich eine XLS-Datei zu sein. Dies bedeutet, dass es möglicherweise nur in Excel funktioniert und nicht in anderen Programmen, die Tabellen lesen. Aber es ist wahrscheinlich besser als die entsprechenden HTML-Tabellenantworten hier!
Rup

Unterstützt xlsx ? OpenXML ?
Kiquenet

14

Sie möchten lediglich einen weiteren Verweis auf eine Drittanbieterlösung hinzufügen, die Ihr Problem direkt behebt: http://www.officewriter.com

(Haftungsausschluss: Ich arbeite für SoftArtisans, das Unternehmen, das OfficeWriter herstellt.)



12

Hier ist eine Möglichkeit, dies mit LINQ to XML zu tun, einschließlich Beispielcode:

Schnelles Importieren und Exportieren von Excel-Daten mit LINQ nach XML

Es ist ein wenig komplex, da Sie Namespaces usw. importieren müssen, aber Sie können damit externe Abhängigkeiten vermeiden.

(Natürlich ist es auch VB .NET, nicht C #, aber Sie können das VB .NET-Material jederzeit in einem eigenen Projekt isolieren, um XML-Literale zu verwenden, und alles andere in C # ausführen.)


12

Einige Anbieter von Komponenten von Drittanbietern wie Infragistics oder Syncfusion bieten sehr gute Excel-Exportfunktionen, für die keine Installation von Microsoft Excel erforderlich ist.

Da diese Anbieter auch erweiterte UI-Rasterkomponenten bereitstellen, sind diese Komponenten besonders praktisch, wenn Stil und Layout eines Excel-Exports den aktuellen Status eines Rasters in der Benutzeroberfläche Ihrer Anwendung nachahmen sollen.

Wenn Ihr Export serverseitig ausgeführt werden soll, wobei der Schwerpunkt auf den zu exportierenden Daten liegt und keine Verknüpfung zur Benutzeroberfläche besteht, würde ich eine der kostenlosen Open Source-Optionen (z. B. ExcelLibrary) wählen.

Ich war zuvor an Projekten beteiligt, bei denen versucht wurde, die serverseitige Automatisierung in der Microsoft Office-Suite zu verwenden. Aufgrund dieser Erfahrung würde ich diesen Ansatz dringend empfehlen.


12
public class GridViewExportUtil
{
    public static void Export(string fileName, GridView gv)
    {
        HttpContext.Current.Response.Clear();
        HttpContext.Current.Response.AddHeader(
            "content-disposition", string.Format("attachment; filename={0}", fileName));
        HttpContext.Current.Response.ContentType = "application/ms-excel";

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

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

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

                //  add the footer row to the table
                if (gv.FooterRow != null)
                {
                    GridViewExportUtil.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());
                HttpContext.Current.Response.End();
            }
        }
    }

    /// <summary>
    /// Replace any of the contained controls with literals
    /// </summary>
    /// <param name="control"></param>
    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())
            {
                GridViewExportUtil.PrepareControlForExport(current);
            }
        }
    }
}

Hallo, diese Lösung besteht darin, Ihre Rasteransicht in Ihre Excel-Datei zu exportieren. Dies könnte Ihnen helfen


7
Nein, dies generiert HTML, das als Excel-Datei und nicht als echte Excel-Datei markiert ist. Ja, Excel selbst öffnet dieses OK, aber andere Programme, die Tabellenkalkulationen verwenden - einschließlich beispielsweise des kostenlosen Excel-Viewers von Microsoft - akzeptieren es nicht. Sie sollten eine echte Excel-Datei mit einer der Bibliotheken hier erstellen.
Rup

Sie sollten auch System.Net.Mime.ContentDisposition verwenden , um den Headertext für die Inhaltsdisposition anstelle eines Zeichenfolgenanhangs zu generieren - dies wird Dateinamen, die Leerzeichen usw. enthalten, korrekt verarbeiten.
Rup

12

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

using (ExcelHelper helper = new ExcelHelper(TEMPLATE_FILE_NAME, GENERATED_FILE_NAME))
{
    helper.Direction = ExcelHelper.DirectionType.TOP_TO_DOWN;
    helper.CurrentSheetName = "Sheet1";
    helper.CurrentPosition = new CellRef("C3");

    //the template xlsx should contains the named range "header"; use the command "insert"/"name".
    helper.InsertRange("header");

    //the template xlsx should contains the named range "sample1";
    //inside this range you should have cells with these values:
    //<name> , <value> and <comment>, which will be replaced by the values from the getSample()
    CellRangeTemplate sample1 = helper.CreateCellRangeTemplate("sample1", new List<string> {"name", "value", "comment"}); 
    helper.InsertRange(sample1, getSample());

    //you could use here other named ranges to insert new cells and call InsertRange as many times you want, 
    //it will be copied one after another;
    //even you can change direction or the current cell/sheet before you insert

    //typically you put all your "template ranges" (the names) on the same sheet and then you just delete it
    helper.DeleteSheet("Sheet3");
}        

wo Probe so aussehen:

private IEnumerable<List<object>> getSample()
{
    var random = new Random();

    for (int loop = 0; loop < 3000; loop++)
    {
        yield return new List<object> {"test", DateTime.Now.AddDays(random.NextDouble()*100 - 50), loop};
    }
}

10

Der einfachste und schnellste Weg, eine Excel-Datei aus C # zu erstellen, ist die Verwendung des Open XML Productivity Tool. Das Open XML Productivity Tool wird mit der Open XML SDK-Installation geliefert. Das Tool entwickelt jede Excel-Datei in C # -Code zurück. Der C # -Code kann dann verwendet werden, um diese Datei neu zu generieren.

Ein Überblick über den Prozess ist:

  1. Installieren Sie das Open XML SDK mit dem Tool.
  2. Erstellen Sie eine Excel-Datei mit dem neuesten Excel-Client mit dem gewünschten Aussehen. Nennen Sie es DesiredLook.xlsx.
  3. Öffnen DesiredLook.xlsxSie bei geöffnetem Werkzeug die Schaltfläche Code reflektieren oben. Geben Sie hier die Bildbeschreibung ein
  4. Der C # -Code für Ihre Datei wird im rechten Bereich des Tools generiert. Fügen Sie dies Ihrer C # -Lösung hinzu und generieren Sie Dateien mit dem gewünschten Aussehen.

Als Bonus funktioniert diese Methode für alle Word- und PowerPoint-Dateien. Als C # -Entwickler nehmen Sie dann Änderungen am Code vor, die Ihren Anforderungen entsprechen.

Ich habe eine einfache WPF-App auf Github entwickelt, die zu diesem Zweck unter Windows ausgeführt wird. Es gibt eine Platzhalterklasse namens, GeneratedClassin die Sie den generierten Code einfügen können. Wenn Sie eine Version der Datei zurückgehen, wird eine Excel-Datei wie folgt generiert:

Geben Sie hier die Bildbeschreibung ein


1
Ich habe diese Open XML SDK-Lösung noch nicht ausprobiert, aber Wow, ich werde sie auf jeden Fall ausprobieren. Ich habe viele Jahre mit solchen Werkzeugen gearbeitet und wusste nichts davon. Ich habe mein eigenes einfaches FOSS zum Konvertieren von Dateien in XLSX mit .NET veröffentlicht: github.com/TonyGravagno/NebulaXConvert
TonyG


Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.