Lesen von Excel-Dateien aus C #


233

Gibt es eine kostenlose oder Open Source-Bibliothek zum Lesen von Excel-Dateien (.xls) direkt aus einem C # -Programm?

Es muss nicht zu ausgefallen sein, nur ein Arbeitsblatt auszuwählen und die Daten als Zeichenfolgen zu lesen. Bisher habe ich Export in Unicode-Text-Funktion von Excel unter Verwendung von, und Analysieren der resultierenden (Tabulator getrennt) Datei, aber ich möchte das Handbuch Schritt beseitigen.

Antworten:


153
var fileName = string.Format("{0}\\fileNameHere", Directory.GetCurrentDirectory());
var connectionString = string.Format("Provider=Microsoft.Jet.OLEDB.4.0; data source={0}; Extended Properties=Excel 8.0;", fileName);

var adapter = new OleDbDataAdapter("SELECT * FROM [workSheetNameHere$]", connectionString);
var ds = new DataSet();

adapter.Fill(ds, "anyNameHere");

DataTable data = ds.Tables["anyNameHere"];

Das benutze ich normalerweise. Es ist etwas anders, weil ich normalerweise ein AsEnumerable () bei der Bearbeitung der Tabellen stecke:

var data = ds.Tables["anyNameHere"].AsEnumerable();

Auf diese Weise kann ich mit LINQ Strukturen aus den Feldern suchen und erstellen.

var query = data.Where(x => x.Field<string>("phoneNumber") != string.Empty).Select(x =>
                new MyContact
                    {
                        firstName= x.Field<string>("First Name"),
                        lastName = x.Field<string>("Last Name"),
                        phoneNumber =x.Field<string>("Phone Number"),
                    });

Wenn es so aussieht, als würde Select in diesem Ansatz versuchen, den Datentyp der Spalte zu erraten und diesen erratenen Datentyp zu erzwingen. Wenn Sie beispielsweise eine Spalte mit meist doppelten Werten haben, möchten Sie x.Field <string> nicht übergeben, erwarten jedoch x.Field <double>. Ist das wahr?
Kevin Le - Khnle

1
Habe es gerade auf MSDN nachgeschlagen. Es sieht so aus, als würde <T> nur verwendet, um zu versuchen, den Inhalt der Spalte in einen Typ umzuwandeln. In diesem Beispiel werden die Daten in den Spalten nur in Zeichenfolgen umgewandelt. Wenn Sie ein Double möchten, müssen Sie double.Parse (x.Field <string> ("Cost") oder ähnliches aufrufen. Field ist eine Erweiterungsmethode für DataRow und es gibt anscheinend keine nicht generischen Versionen.
Robin Robinson

Verlangsamt das Hinzufügen eines double.Parse zur Linq-Abfrage dies erheblich?
Anonymer Typ

23
Beachten Sie, dass Sie beim Lesen xlsxstattdessen diese Verbindungszeichenfolge verwenden müssen:string.Format("Provider=Microsoft.ACE.OLEDB.12.0;Data Source={0}; Extended Properties=Excel 12.0;", fileName)
Andreas Grech

7
Leider ist der Jet.OLEDB-Treiber nicht 64-Bit-kompatibel. Sie müssen zu Ziel-x86 und nicht zu einer beliebigen CPU wechseln (wenn Sie diese Methode weiterhin ausführen möchten). Alternativ können Sie den 64-Bit-ACE-Treiber installieren und die Verbindungszeichenfolge ändern, um diesen Treiber zu verwenden (wie von Andreas angegeben). microsoft.com/en-us/download/…
Duncan

83

Wenn es sich nur um einfache Daten handelt, die in der Excel-Datei enthalten sind, können Sie die Daten über ADO.NET lesen. Siehe die hier aufgeführten Verbindungszeichenfolgen:

http://www.connectionstrings.com/?carrier=excel2007 oder http://www.connectionstrings.com/?carrier=excel

-Ryan

Update: Dann können Sie das Arbeitsblatt einfach über so etwas wie lesen select * from [Sheet1$]


1
Dieser Weg ist bei weitem der schnellste.
StingyJack

17
Das stimmt natürlich nicht, Stingy. Sie müssen alle Daten sichten und beschissenen DB-Code schreiben (Handarbeit Ihrer Modelle, Zuordnung von Spalten zu Eigenschaften, yadda yadda). Der schnellste Weg ist, dies von einem anderen armen SOB für Sie tun zu lassen . Deshalb verwenden die Leute Frameworks, anstatt alles von unten nach oben zu schreiben.

12
Wertlose Methode! Schneidet Textspalten beim Lesen auf 255 Zeichen ab. In acht nehmen! Siehe: stackoverflow.com/questions/1519288/… ACE-Engine macht dasselbe!
Triynko

5
Beachten Sie, dass für die Verwendung von ADO.NET zum Lesen von Daten aus Exel Microsoft Access oder Microsoft Access Database Engine Redistributable installiert sein muss.
Zihotki

3
Der Treiber errät auch die Spaltentypen basierend auf den ersten Zeilen. Wenn Sie eine Spalte mit Ganzzahlen in den ersten Zeilen haben, wird ein Fehler auftreten, wenn Sie eine Nicht-Ganzzahl (z. B. ein Float, eine Zeichenfolge) treffen
Brian Low

27

Der ADO.NET-Ansatz ist schnell und einfach, weist jedoch einige Besonderheiten auf, die Sie beachten sollten, insbesondere hinsichtlich des Umgangs mit DataTypes.

Dieser hervorragende Artikel hilft Ihnen dabei, einige häufige Fallstricke zu vermeiden: http://blog.lab49.com/archives/196


Sie haben meine Frage beantwortet (in Form eines Kommentars oben).
Kevin Le - Khnle

22

Folgendes habe ich für Excel 2003 verwendet:

Dictionary<string, string> props = new Dictionary<string, string>();
props["Provider"] = "Microsoft.Jet.OLEDB.4.0";
props["Data Source"] = repFile;
props["Extended Properties"] = "Excel 8.0";

StringBuilder sb = new StringBuilder();
foreach (KeyValuePair<string, string> prop in props)
{
    sb.Append(prop.Key);
    sb.Append('=');
    sb.Append(prop.Value);
    sb.Append(';');
}
string properties = sb.ToString();

using (OleDbConnection conn = new OleDbConnection(properties))
{
    conn.Open();
    DataSet ds = new DataSet();
    string columns = String.Join(",", columnNames.ToArray());
    using (OleDbDataAdapter da = new OleDbDataAdapter(
        "SELECT " + columns + " FROM [" + worksheet + "$]", conn))
    {
        DataTable dt = new DataTable(tableName);
        da.Fill(dt);
        ds.Tables.Add(dt);
    }
}

2
Arbeitsblatt ist nicht definiert ... scheint mir etwas seltsam, nachdem ich alles andere klar definiert habe.
Jeremy Holovacs

21

Wie wäre es mit Excel Data Reader?

http://exceldatareader.codeplex.com/

Ich habe in einer Produktionsumgebung Wut verwendet, um große Datenmengen aus einer Vielzahl von Excel-Dateien in SQL Server Compact zu ziehen. Es funktioniert sehr gut und ist ziemlich robust.


2
Ich werde den zweiten Excel Data Reader verwenden. Es hat auch zu der unglaublich nützlichen Excel Data Driven Tests-Bibliothek geführt, die das TestCaseSource-Attribut von NUnit 2.5 verwendet, um datengesteuerte Tests mit Excel-Tabellen lächerlich einfach zu machen. Beachten Sie jedoch, dass Resharper TestCaseSource noch nicht unterstützt. Sie müssen daher den NUnit-Runner verwenden.
David Keaveny

Leider gibt es einige Probleme mit dieser Bibliothek, auf die wir gerade gestoßen sind. Erstens haben wir einige Währungsfelder als Datumsangaben veröffentlicht. Zweitens stürzt es ab, wenn die Arbeitsmappe leere Blätter enthält. Obwohl die Integration sehr einfach war, prüfen wir jetzt neu, ob diese Bibliothek weiterhin verwendet werden soll. Es scheint nicht aktiv entwickelt zu werden.
Ian1971

Es wird auch davon ausgegangen, dass einige optionale Elemente in der xlsx-Datei vorhanden sind, die dazu führen, dass die Daten nicht gelesen werden können, wenn sie nicht vorhanden sind.
RichieHindle

Wir haben Probleme mit Excel-Dateien, die von SQL Server Reporting Services stammen. Sie funktionieren einfach nicht, es sei denn, Sie öffnen sie und speichern sie (auch unbearbeitet). @RichieHindle: Über welche optionalen Elemente sprechen Sie (in der Hoffnung, dass dies mir bei meinen SSRS-Excel-Dateien helfen könnte)?
Peter

@Peter: Ich denke, es war ein fehlendes <dimension>Element in dem <worksheet>, das mir Probleme bereitete.
RichieHindle

16

Hier ist ein Code, den ich vor einigen Jahren mit .NET 1.1 in C # geschrieben habe. Ich bin mir nicht sicher, ob dies genau das ist, was du brauchst (und möglicherweise nicht mein bester Code :)).

using System;
using System.Data;
using System.Data.OleDb;

namespace ExportExcelToAccess
{
    /// <summary>
    /// Summary description for ExcelHelper.
    /// </summary>
    public sealed class ExcelHelper
    {
        private const string CONNECTION_STRING = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=<FILENAME>;Extended Properties=\"Excel 8.0;HDR=Yes;\";";

        public static DataTable GetDataTableFromExcelFile(string fullFileName, ref string sheetName)
        {
            OleDbConnection objConnection = new OleDbConnection();
            objConnection = new OleDbConnection(CONNECTION_STRING.Replace("<FILENAME>", fullFileName));
            DataSet dsImport = new DataSet();

            try
            {
                objConnection.Open();

                DataTable dtSchema = objConnection.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, null);

                if( (null == dtSchema) || ( dtSchema.Rows.Count <= 0 ) )
                {
                    //raise exception if needed
                }

                if( (null != sheetName) && (0 != sheetName.Length))
                {
                    if( !CheckIfSheetNameExists(sheetName, dtSchema) )
                    {
                        //raise exception if needed
                    }
                }
                else
                {
                    //Reading the first sheet name from the Excel file.
                    sheetName = dtSchema.Rows[0]["TABLE_NAME"].ToString();
                }

                new OleDbDataAdapter("SELECT * FROM [" + sheetName + "]", objConnection ).Fill(dsImport);
            }
            catch (Exception)
            {
                //raise exception if needed
            }
            finally
            {
                // Clean up.
                if(objConnection != null)
                {
                    objConnection.Close();
                    objConnection.Dispose();
                }
            }


            return dsImport.Tables[0];
            #region Commented code for importing data from CSV file.
            //              string strConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;" +"Data Source=" + System.IO.Path.GetDirectoryName(fullFileName) +";" +"Extended Properties=\"Text;HDR=YES;FMT=Delimited\"";
            //
            //              System.Data.OleDb.OleDbConnection conText = new System.Data.OleDb.OleDbConnection(strConnectionString);
            //              new System.Data.OleDb.OleDbDataAdapter("SELECT * FROM " + System.IO.Path.GetFileName(fullFileName).Replace(".", "#"), conText).Fill(dsImport);
            //              return dsImport.Tables[0];

            #endregion
        }

        /// <summary>
        /// This method checks if the user entered sheetName exists in the Schema Table
        /// </summary>
        /// <param name="sheetName">Sheet name to be verified</param>
        /// <param name="dtSchema">schema table </param>
        private static bool CheckIfSheetNameExists(string sheetName, DataTable dtSchema)
        {
            foreach(DataRow dataRow in dtSchema.Rows)
            {
                if( sheetName == dataRow["TABLE_NAME"].ToString() )
                {
                    return true;
                }   
            }
            return false;
        }
    }
}

Konnte nicht mehr Cherian zustimmen. Dieser Code ist viele Jahre alt ... bevor ich überhaupt mit Resharper vertraut war :)
hitec

2
Der Code ist hässlich, aber er zeigt, wie man die Blattnamen bekommt, großartig!
Sam



8

Ich habe vor einiger Zeit viel aus Excel-Dateien in C # gelesen, und wir haben zwei Ansätze verwendet:

  • Die COM-API, über die Sie direkt auf Excel-Objekte zugreifen und diese über Methoden und Eigenschaften bearbeiten können
  • Der ODBC-Treiber, mit dem Excel wie eine Datenbank verwendet werden kann.

Letzterer Ansatz war viel schneller: Das Lesen einer großen Tabelle mit 20 Spalten und 200 Zeilen würde über COM 30 Sekunden und über ODBC eine halbe Sekunde dauern. Daher würde ich den Datenbankansatz empfehlen, wenn Sie nur die Daten benötigen.

Prost,

Carl



6

Ich möchte eine einfache Methode zum Lesen der xls / xlsx-Datei mit .NET zeigen. Ich hoffe, dass das Folgende für Sie hilfreich sein wird.

 private DataTable ReadExcelToTable (Zeichenfolgenpfad)    
 {

     // Verbindungszeichenfolge

     string connstring = "Provider = Microsoft.ACE.OLEDB.12.0; Datenquelle =" + Pfad + "; Erweiterte Eigenschaften = 'Excel 8.0; HDR = NO; IMEX = 1';";  
     //der selbe Name 
     // string connstring = Provider = Microsoft.JET.OLEDB.4.0; Datenquelle = "+ Pfad + //"; Erweiterte Eigenschaften = 'Excel 8.0; HDR = NO; IMEX = 1'; "; 

     using (OleDbConnection conn = new OleDbConnection (connstring))
     {
        conn.Open ();
        // Alle Blattnamen abrufen
        DataTable sheetName = conn.GetOleDbSchemaTable (OleDbSchemaGuid.Tables, neues Objekt [] {null, null, null, "Tabelle"});  

        // Den ersten Blattnamen abrufen
        Zeichenfolge firstSheetName = sheetName.Rows [0] [2] .ToString (); 

        // Abfragezeichenfolge 
        string sql = string.Format ("SELECT * FROM [{0}]", firstSheetName); 
        OleDbDataAdapter ada = neuer OleDbDataAdapter (SQL, Connstring);
        DataSet set = new DataSet ();
        ada.Fill (set);
        return set.Tables [0];   
   }}
 }}

Der Code stammt aus dem Artikel: http://www.c-sharpcorner.com/uploadfile/d2dcfc/read-excel-file-with-net/ . Sie können mehr Details davon erhalten.


2
Es war hilfreich, insbesondere der Teil über das Lesen der Blattnamen.
Martinstoeckli

4

Nicht kostenlos, aber mit dem neuesten Office gibt es eine sehr schöne Automatisierungs-.NET-API. (Es gibt schon lange eine API, die aber unangenehm war.) Sie können alles tun, was Sie im Code wollen / brauchen, während die Office-App ein versteckter Hintergrundprozess bleibt.


3
@ Anonymous-type Ich habe die Frage gelesen und bot eine hilfreiche Alternative zu einer gewünschten OSS-Implementierung an ... weil ich mir ziemlich sicher war, dass nichts verfügbar war. Nach der akzeptierten Antwort zu urteilen, ist die Anforderung, Office installiert zu haben, kein Problem.
Xanadont

3

Verzeihen Sie mir, wenn ich hier außerhalb der Basis bin, aber sind die Office-PIAs nicht dafür gedacht ?


5
Ja, aber dazu müsste eine Excel.Application-Instanz erstellt, die XLS-Datei geladen usw. werden. Wenn nur einige Daten aus der Datei gelesen werden sollen, ist die Verwendung einer der beschriebenen ADO.NET-Methoden viel einfacher und weitaus einfacher in den anderen Antworten.
Adam Ralph

Zu langsam, mit Office PIA als Basis, ist alles andere schneller - selbst wenn nur ein Objektarray verwendet wird, das von der .Value2-Eigenschaft übergeben wird. Welches verwendet noch die PIA.
Anonymer Typ

3

In letzter Zeit teilweise, um LINQ besser zu machen ... Ich habe die Automatisierungs-API von Excel verwendet, um die Datei als XML-Tabelle zu speichern und diese Datei dann mit LINQ zu XML zu verarbeiten.


Ich würde vermuten, dass Sie es vor Excel schützen können, aber nicht vor Leuten mit Compiler ... wie alles andere ... es sind nur Bytes.
Kenny

@gsvirdi, poste eine separate Frage zur Sicherheit von Excel-Dateien. Diese Frage bezieht sich auf die Leistung.
Anonymer Typ


3

SmartXLS ist eine weitere Excel-Tabellenkomponente, die die meisten Funktionen von Excel-Diagrammen und Formeln unterstützt und das openxml-Format von excel2007 lesen / schreiben kann.



2

Ich empfehle die FileHelpers Library, eine kostenlose und einfach zu verwendende .NET-Bibliothek zum Importieren / Exportieren von Daten aus EXCEL, festen oder begrenzten Datensätzen in Dateien, Zeichenfolgen oder Streams + More.

Der Abschnitt zur Dokumentation von Excel-Datenverbindungen http://filehelpers.sourceforge.net/example_exceldatalink.html


1
Ich werde Sie nicht im Stich lassen, aber ich habe kürzlich angefangen, FileHelpers zu verwenden, und war schockiert darüber, wie ... beschissen es ist. Zum Beispiel besteht die einzige Möglichkeit, Spalten in einer CSV Eigenschaften zuzuordnen ... entschuldigen Sie, FELDER, eines Modells darin, die Felder in der Reihenfolge der Spalten zu erstellen . Ich weiß nichts über Sie, aber ich würde mich bei einer der zentralsten Designüberlegungen meines f8king-Frameworks nicht auf eine Eigenart des Compilers verlassen.


2

SpreadsheetGear ist großartig. Ja, es ist eine Ausgabe, aber im Vergleich zu diesen anderen Lösungen ist es die Kosten wert. Es ist schnell, zuverlässig, sehr umfassend und ich muss sagen, nachdem ich dieses Produkt über anderthalb Jahre in meinem Vollzeit-Software-Job verwendet habe, ist die Kundenbetreuung fantastisch!


Schwer zu rechtfertigen, wenn es so viele einfache und effektive Möglichkeiten gibt (kostenlos), aus Excel zu lesen und in Excel zu schreiben.
Anonymer Typ

2

Die Lösung, die wir verwendeten, musste:

  • Lesen / Schreiben zulassen von in Excel erstellten Dateien
  • Seien Sie schnell in der Leistung (nicht wie mit COMs)
  • Seien Sie MS Office- unabhängig (muss verwendet werden können, ohne dass Clients MS Office installiert haben)
  • Sei frei oder Open Source (aber aktiv entwickelt)

Es gibt mehrere Möglichkeiten, aber wir haben festgestellt, dass NPoi (.NET-Port von Javas seit langem bestehendem Poi- Open-Source-Projekt) die beste ist: http://npoi.codeplex.com/

Es ermöglicht auch das Arbeiten mit den Dateiformaten .doc und .ppt


2

Wenn es nur tabellarische Daten sind. Ich würde Dateidaten-Helfer von Marcos Melli empfehlen, die hier heruntergeladen werden können .



1

Sie könnten eine Excel-Tabelle schreiben, die eine bestimmte Excel-Tabelle lädt und als CSV speichert (anstatt sie manuell auszuführen).

dann könnten Sie das von c # aus automatisieren.

und sobald es in csv ist, kann das c # -Programm das verstehen.

(Wenn Sie jemand bittet, in Excel zu programmieren, tun Sie am besten so, als wüssten Sie nicht, wie)

(edit: ah ja, rob und ryan haben beide recht)


1

Ich weiß, dass Leute zu diesem Zweck eine Excel- "Erweiterung" erstellt haben.
Sie erstellen in Excel mehr oder weniger eine Schaltfläche mit der Aufschrift "In Programm X exportieren" und exportieren und senden die Daten dann in einem Format, das das Programm lesen kann.

http://msdn.microsoft.com/en-us/library/ms186213.aspx sollte ein guter Anfang sein.

Viel Glück


1

Ich habe gerade ein schnelles Demo-Projekt durchgeführt, bei dem einige Excel-Dateien verwaltet werden mussten. Die .NET-Komponente der GemBox-Software war für meine Anforderungen ausreichend. Es gibt eine kostenlose Version mit einigen Einschränkungen.

http://www.gemboxsoftware.com/GBSpreadsheet.htm


Zu Ihrer Information: Ich habe es versucht und es entsprach nicht meinem Bedürfnis, eine verschlüsselte Datei lesen zu können.
Tschad

1

Excel Package ist eine Open Source-Komponente (GPL) zum Lesen / Schreiben von Excel 2007-Dateien. Ich habe es für ein kleines Projekt verwendet und die API ist unkompliziert. Funktioniert nur mit XLSX (Excel 200 &), nicht mit XLS.

Der Quellcode scheint auch gut organisiert und leicht zu umgehen zu sein (wenn Sie die Funktionalität erweitern oder kleinere Probleme beheben müssen, wie ich es getan habe).

Zuerst habe ich den ADO.Net-Ansatz (Excel-Verbindungszeichenfolge) ausprobiert, aber er war mit bösen Hacks behaftet. Wenn beispielsweise die zweite Zeile eine Zahl enthält, werden Ints für alle Felder in der folgenden Spalte zurückgegeben und alle Daten werden leise gelöscht das passt nicht


1

Wir gebrauchen ClosedXML in ziemlich großen Systemen.

  • Frei
  • Einfach zu installieren
  • Einfache Codierung
  • Sehr reaktionsschnelle Unterstützung
  • Das Entwicklerteam ist äußerst offen für neue Vorschläge. Oft werden neue Funktionen und Fehlerbehebungen innerhalb derselben Woche implementiert

1

Take.ioSpreadsheet erledigt diese Arbeit für Sie und kostenlos. Werfen Sie einen Blick auf diese .


Dies ist eine wirklich tolle kleine Bibliothek. Es konvertiert einfach alles in Listen von Listen von Zeichenfolgen, was für die Art von Arbeit, für die ich es brauchte, in Ordnung ist.
Drewmate

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.