Ich weiß, dass es verschiedene Möglichkeiten gibt, eine Excel-Datei zu lesen:
Iterop
Oledb
Open Xml SDK
Kompatibilität ist keine Frage, da das Programm in einer kontrollierten Umgebung ausgeführt wird.
Meine Anforderung:
Lesen Sie eine Datei in a DataTable
/ CUstom Entitie
s (Ich weiß nicht, wie dynamische Eigenschaften / Felder für ein Objekt erstellt werden sollen [Spaltennamen variieren in einer Excel-Datei])
Verwenden Sie DataTable/Custom Entities
diese Option , um einige Vorgänge mithilfe der Daten auszuführen.
Aktualisieren Sie DataTable
mit den Ergebnissen der Operationen
Schreiben Sie es zurück an excel file
.
Welches wäre einfacher.
Wenn möglich, beraten Sie mich auch zu benutzerdefinierten Entitäten (dynamisches Hinzufügen von Eigenschaften / Feldern zu einem Objekt)
quelle
DataTable
zu Blatt und Export Blatt zuDataTable
.Antworten:
Schauen Sie sich Linq-to-Excel an . Es ist ziemlich ordentlich.
var book = new LinqToExcel.ExcelQueryFactory(@"File.xlsx"); var query = from row in book.Worksheet("Stock Entry") let item = new { Code = row["Code"].Cast<string>(), Supplier = row["Supplier"].Cast<string>(), Ref = row["Ref"].Cast<string>(), } where item.Supplier == "Walmart" select item;
Es ermöglicht auch einen stark typisierten Zeilenzugriff.
quelle
Mit OLE Query ist es ganz einfach (zB sheetName ist Sheet1):
DataTable LoadWorksheetInDataTable(string fileName, string sheetName) { DataTable sheetData = new DataTable(); using (OleDbConnection conn = this.returnConnection(fileName)) { conn.Open(); // retrieve the data using data adapter OleDbDataAdapter sheetAdapter = new OleDbDataAdapter("select * from [" + sheetName + "$]", conn); sheetAdapter.Fill(sheetData); conn.Close(); } return sheetData; } private OleDbConnection returnConnection(string fileName) { return new OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + fileName + "; Jet OLEDB:Engine Type=5;Extended Properties=\"Excel 8.0;\""); }
Für neuere Excel-Versionen:
return new OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + fileName + ";Extended Properties=Excel 12.0;");
Sie können Excel Data Reader auch als Open Source-Projekt in CodePlex verwenden. Es funktioniert sehr gut, um Daten aus Excel-Tabellen zu exportieren.
Der auf dem angegebenen Link angegebene Beispielcode:
FileStream stream = File.Open(filePath, FileMode.Open, FileAccess.Read); //1. Reading from a binary Excel file ('97-2003 format; *.xls) IExcelDataReader excelReader = ExcelReaderFactory.CreateBinaryReader(stream); //... //2. Reading from a OpenXml Excel file (2007 format; *.xlsx) IExcelDataReader excelReader = ExcelReaderFactory.CreateOpenXmlReader(stream); //... //3. DataSet - The result of each spreadsheet will be created in the result.Tables DataSet result = excelReader.AsDataSet(); //... //4. DataSet - Create column names from first row excelReader.IsFirstRowAsColumnNames = true; DataSet result = excelReader.AsDataSet(); //5. Data Reader methods while (excelReader.Read()) { //excelReader.GetInt32(0); } //6. Free resources (IExcelDataReader is IDisposable) excelReader.Close();
Referenz: Wie importiere ich mit Microsoft.Office.Interop.Excel aus Excel in ein DataSet?
quelle
this.returnConnection(fileName)
?OleDb
nicht mehr, da es nicht verfügbar ist (da es nicht plattformübergreifend ist).Mir ist klar, dass diese Frage vor fast 7 Jahren gestellt wurde, aber es ist immer noch ein Top-Google-Suchergebnis für bestimmte Keywords beim Importieren von Excel-Daten mit C #. Daher wollte ich eine Alternative anbieten, die auf einigen aktuellen technischen Entwicklungen basiert.
Das Importieren von Excel-Daten ist zu einer so häufigen Aufgabe geworden, dass ich den Prozess optimiert und die Methode in meinem Blog dokumentiert habe: Der beste Weg, um Excel-Dateien in c # zu lesen .
Ich verwende NPOI, weil es Excel-Dateien ohne installiertes Microsoft Office lesen / schreiben kann und weder COM + noch Interops verwendet. Das heißt, es kann in der Cloud funktionieren!
Die wahre Magie liegt jedoch in der Zusammenarbeit mit NPOI Mapper von Donny Tian, da ich die Excel-Spalten Eigenschaften in meinen C # -Klassen zuordnen kann, ohne Code schreiben zu müssen. Es ist wunderschön.
Hier ist die Grundidee:
Ich erstelle eine .net-Klasse, die den Excel-Spalten entspricht, die mich interessieren:
class CustomExcelFormat { [Column("District")] public int District { get; set; } [Column("DM")] public string FullName { get; set; } [Column("Email Address")] public string EmailAddress { get; set; } [Column("Username")] public string Username { get; set; } public string FirstName { get { return Username.Split('.')[0]; } } public string LastName { get { return Username.Split('.')[1]; } } }
Beachten Sie, dass ich basierend auf dem Spaltennamen eine Zuordnung vornehmen kann, wenn ich möchte!
Wenn ich dann die Excel-Datei verarbeite, muss ich nur noch Folgendes tun:
public void Execute(string localPath, int sheetIndex) { IWorkbook workbook; using (FileStream file = new FileStream(localPath, FileMode.Open, FileAccess.Read)) { workbook = WorkbookFactory.Create(file); } var importer = new Mapper(workbook); var items = importer.Take<CustomExcelFormat>(sheetIndex); foreach(var item in items) { var row = item.Value; if (string.IsNullOrEmpty(row.EmailAddress)) continue; UpdateUser(row); } DataContext.SaveChanges(); }
Zugegeben, mein Code ändert die Excel-Datei selbst nicht. Ich speichere stattdessen die Daten mit Entity Framework in einer Datenbank (deshalb sehen Sie in meinem Beispiel "UpdateUser" und "SaveChanges"). Es gibt jedoch bereits eine gute Diskussion über SO, wie eine Datei mit NPOI gespeichert / geändert werden kann .
quelle
dynamic
Funktion. Ich denke, das ist es, wonach du suchst.mapper.Take<dynamic>(0).ToList();
Versuchen Sie, diesen kostenlosen Weg zu https://freenetexcel.codeplex.com zu verwenden
Workbook workbook = new Workbook(); workbook.LoadFromFile(@"..\..\parts.xls",ExcelVersion.Version97to2003); //Initialize worksheet Worksheet sheet = workbook.Worksheets[0]; DataTable dataTable = sheet.ExportDataTable();
quelle
Wenn Sie es auf nur (Open Office XML-Format) * .xlsx-Dateien beschränken können, ist EPPLus wahrscheinlich die beliebteste Bibliothek .
Bonus ist, es gibt keine anderen Abhängigkeiten. Einfach mit nuget installieren:
quelle
Versuchen Sie, die Aspose.cells-Bibliothek zu verwenden (nicht kostenlos, aber die Testversion reicht zum Lesen aus). Sie ist ziemlich gut
Install-package Aspose.cells
Es gibt Beispielcode:
using Aspose.Cells; using System; namespace ExcelReader { class Program { static void Main(string[] args) { // Replace path for your file readXLS(@"C:\MyExcelFile.xls"); // or "*.xlsx" Console.ReadKey(); } public static void readXLS(string PathToMyExcel) { //Open your template file. Workbook wb = new Workbook(PathToMyExcel); //Get the first worksheet. Worksheet worksheet = wb.Worksheets[0]; //Get cells Cells cells = worksheet.Cells; // Get row and column count int rowCount = cells.MaxDataRow; int columnCount = cells.MaxDataColumn; // Current cell value string strCell = ""; Console.WriteLine(String.Format("rowCount={0}, columnCount={1}", rowCount, columnCount)); for (int row = 0; row <= rowCount; row++) // Numeration starts from 0 to MaxDataRow { for (int column = 0; column <= columnCount; column++) // Numeration starts from 0 to MaxDataColumn { strCell = ""; strCell = Convert.ToString(cells[row, column].Value); if (String.IsNullOrEmpty(strCell)) { continue; } else { // Do your staff here Console.WriteLine(strCell); } } } } } }
quelle
Lesen Sie aus Excel, ändern Sie und schreiben Sie zurück
/// <summary> /// /Reads an excel file and converts it into dataset with each sheet as each table of the dataset /// </summary> /// <param name="filename"></param> /// <param name="headers">If set to true the first row will be considered as headers</param> /// <returns></returns> public DataSet Import(string filename, bool headers = true) { var _xl = new Excel.Application(); var wb = _xl.Workbooks.Open(filename); var sheets = wb.Sheets; DataSet dataSet = null; if (sheets != null && sheets.Count != 0) { dataSet = new DataSet(); foreach (var item in sheets) { var sheet = (Excel.Worksheet)item; DataTable dt = null; if (sheet != null) { dt = new DataTable(); var ColumnCount = ((Excel.Range)sheet.UsedRange.Rows[1, Type.Missing]).Columns.Count; var rowCount = ((Excel.Range)sheet.UsedRange.Columns[1, Type.Missing]).Rows.Count; for (int j = 0; j < ColumnCount; j++) { var cell = (Excel.Range)sheet.Cells[1, j + 1]; var column = new DataColumn(headers ? cell.Value : string.Empty); dt.Columns.Add(column); } for (int i = 0; i < rowCount; i++) { var r = dt.NewRow(); for (int j = 0; j < ColumnCount; j++) { var cell = (Excel.Range)sheet.Cells[i + 1 + (headers ? 1 : 0), j + 1]; r[j] = cell.Value; } dt.Rows.Add(r); } } dataSet.Tables.Add(dt); } } _xl.Quit(); return dataSet; } public string Export(DataTable dt, bool headers = false) { var wb = _xl.Workbooks.Add(); var sheet = (Excel.Worksheet)wb.ActiveSheet; //process columns for (int i = 0; i < dt.Columns.Count; i++) { var col = dt.Columns[i]; //added columns to the top of sheet var currentCell = (Excel.Range)sheet.Cells[1, i + 1]; currentCell.Value = col.ToString(); currentCell.Font.Bold = true; //process rows for (int j = 0; j < dt.Rows.Count; j++) { var row = dt.Rows[j]; //added rows to sheet var cell = (Excel.Range)sheet.Cells[j + 1 + 1, i + 1]; cell.Value = row[i]; } currentCell.EntireColumn.AutoFit(); } var fileName="{somepath/somefile.xlsx}"; wb.SaveCopyAs(fileName); _xl.Quit(); return fileName; }
quelle