如何使用C#读取Excel文件的数据?

如何使用C#读取Excel文件? 我打开Excel文件进​​行阅读并将其复制到剪贴板以search电子邮件格式,但是我不知道该如何做。

FileInfo finfo; Excel.ApplicationClass ExcelObj = new Excel.ApplicationClass(); ExcelObj.Visible = false; Excel.Workbook theWorkbook; Excel.Worksheet worksheet; if (listView1.Items.Count > 0) { foreach (ListViewItem s in listView1.Items) { finfo = new FileInfo(s.Text); if (finfo.Extension == ".xls" || finfo.Extension == ".xlsx" || finfo.Extension == ".xlt" || finfo.Extension == ".xlsm" || finfo.Extension == ".csv") { theWorkbook = ExcelObj.Workbooks.Open(s.Text, 0, true, 5, "", "", true, Excel.XlPlatform.xlWindows, "\t", false, false, 0, true, false, false); for (int count = 1; count <= theWorkbook.Sheets.Count; count++) { worksheet = (Excel.Worksheet)theWorkbook.Worksheets.get_Item(count); worksheet.Activate(); worksheet.Visible = false; worksheet.UsedRange.Cells.Select(); } } } } 

好,

Excel VSTO编程所掌握的一个更为困难的概念是,您不会像数组那样引用单元格, Worksheet[0][0]不会给您单元格A1,它将会出错。 即使在Excel打开时键入A1,实际上也会将数据input到范围A1中。 因此,您将单元格称为命名范围。 这是一个例子:

 Excel.Worksheet sheet = workbook.Sheets["Sheet1"] as Excel.Worksheet; Excel.Range range = sheet.get_Range("A1", Missing.Value) 

你现在可以从字面上input:

 range.Text // this will give you the text the user sees range.Value2 // this will give you the actual value stored by Excel (without rounding) 

如果你想做这样的事情:

 Excel.Range range = sheet.get_Range("A1:A5", Missing.Value) if (range1 != null) foreach (Excel.Range r in range1) { string user = r.Text string value = r.Value2 } 

可能有更好的办法,但是这对我有效。

您需要使用Value2而不是Value的原因是因为Value属性是参数化的,而C#不支持它们。

至于清理代码,我会在明天开始工作的时候发布,我没有代码,但是这是非常好的样板。 您只需以与创build它们相反的顺序closures并释放对象。 您不能使用Using()块,因为Excel.Application或Excel.Workbook没有实现IDisposable ,并且如果不清除,将会在内存中留下悬挂的Excel对象。

注意:

  • 如果你没有设置Visibility属性,Excel不会显示,这可能会让你的用户感到不安,但是如果你只想把数据撕掉,那可能是足够好的了
  • 你可以OleDb,也可以工作。

我希望你能开始,让我知道如果你需要进一步澄清。 我会发布一个完整的

这里是一个完整的示例:

 using System; using System.IO; using System.Reflection; using NUnit.Framework; using ExcelTools = Ms.Office; using Excel = Microsoft.Office.Interop.Excel; namespace Tests { [TestFixture] public class ExcelSingle { [Test] public void ProcessWorkbook() { string file = @"C:\Users\Chris\Desktop\TestSheet.xls"; Console.WriteLine(file); Excel.Application excel = null; Excel.Workbook wkb = null; try { excel = new Excel.Application(); wkb = ExcelTools.OfficeUtil.OpenBook(excel, file); Excel.Worksheet sheet = wkb.Sheets["Data"] as Excel.Worksheet; Excel.Range range = null; if (sheet != null) range = sheet.get_Range("A1", Missing.Value); string A1 = String.Empty; if( range != null ) A1 = range.Text.ToString(); Console.WriteLine("A1 value: {0}", A1); } catch(Exception ex) { //if you need to handle stuff Console.WriteLine(ex.Message); } finally { if (wkb != null) ExcelTools.OfficeUtil.ReleaseRCM(wkb); if (excel != null) ExcelTools.OfficeUtil.ReleaseRCM(excel); } } } } 

我明天将从ExcelTools发布函数,但是我也没有这个代码。

编辑:如所承诺的,这里是你可能需要的ExcelTools的函数。

 public static Excel.Workbook OpenBook(Excel.Application excelInstance, string fileName, bool readOnly, bool editable, bool updateLinks) { Excel.Workbook book = excelInstance.Workbooks.Open( fileName, updateLinks, readOnly, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, editable, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing); return book; } public static void ReleaseRCM(object o) { try { System.Runtime.InteropServices.Marshal.ReleaseComObject(o); } catch { } finally { o = null; } } 

坦率地说,如果你使用VB.NET,这个东西要容易得多。 它是用C#编写的,因为我没有写它。 VB.NET做的选项参数很好,C#没有,因此Type.Missing。 一旦你连续inputType.Missing两次,你就从房间里尖叫起来!

至于你的问题,你可以尝试以下方法:

http://msdn.microsoft.com/en-us/library/microsoft.office.interop.excel.range.find(VS.80).aspx

当我从我的会议回来时,我会举一个例子…欢呼

编辑:这是一个例子

 range = sheet.Cells.Find("Value to Find", Type.Missing, Type.Missing, Type.Missing, Type.Missing, Excel.XlSearchDirection.xlNext, Type.Missing, Type.Missing, Type.Missing); range.Text; //give you the value found 

这里是另外一个由这个网站启发的例子:

  range = sheet.Cells.Find("Value to find", Type.Missing, Type.Missing,Excel.XlLookAt.xlWhole,Excel.XlSearchOrder.xlByColumns,Excel.XlSearchDirection.xlNext,false, false, Type.Missing); 

这有助于了解参数。

PS我是那些喜欢学习COM自动化的奇怪人士之一。 所有这些代码都是从我为工作而写的工具中蒸发出来的,每个星期一都要求我在实验室中处理超过1000个以上的电子表格。

您可以使用Microsoft.Office.Interop.Excel程序集来处理Excel文件。

  1. 右键单击您的项目,然后转到Add reference 。 添加Microsoft.Office.Interop.Excel程序集。
  2. 包括using Microsoft.Office.Interop.Excel; 利用组装。

这里是示例代码:

  using Microsoft.Office.Interop.Excel; //create the Application object we can use in the member functions. Microsoft.Office.Interop.Excel.Application _excelApp = new Microsoft.Office.Interop.Excel.Application(); _excelApp.Visible = true; string fileName = "C:\\sampleExcelFile.xlsx"; //open the workbook Workbook workbook = _excelApp.Workbooks.Open(fileName, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing); //select the first sheet Worksheet worksheet = (Worksheet)workbook.Worksheets[1]; //find the used range in worksheet Range excelRange = worksheet.UsedRange; //get an object array of all of the cells in the worksheet (their values) object[,] valueArray = (object[,])excelRange.get_Value( XlRangeValueDataType.xlRangeValueDefault); //access the cells for (int row = 1; row <= worksheet.UsedRange.Rows.Count; ++row) { for (int col = 1; col <= worksheet.UsedRange.Columns.Count; ++col) { //access each cell Debug.Print(valueArray[row, col].ToString()); } } //clean up stuffs workbook.Close(false, Type.Missing, Type.Missing); Marshal.ReleaseComObject(workbook); _excelApp.Quit(); Marshal.FinalReleaseComObject(_excelApp); 

你为什么不创buildOleDbConnection? 互联网上有很多可用的资源。 这是一个例子

 OleDbConnection con = new OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source="+filename+";Extended Properties=Excel 8.0"); con.Open(); try { //Create Dataset and fill with imformation from the Excel Spreadsheet for easier reference DataSet myDataSet = new DataSet(); OleDbDataAdapter myCommand = new OleDbDataAdapter(" SELECT * FROM ["+listname+"$]" , con); myCommand.Fill(myDataSet); con.Close(); richTextBox1.AppendText("\nDataSet Filled"); //Travers through each row in the dataset foreach (DataRow myDataRow in myDataSet.Tables[0].Rows) { //Stores info in Datarow into an array Object[] cells = myDataRow.ItemArray; //Traverse through each array and put into object cellContent as type Object //Using Object as for some reason the Dataset reads some blank value which //causes a hissy fit when trying to read. By using object I can convert to //String at a later point. foreach (object cellContent in cells) { //Convert object cellContect into String to read whilst replacing Line Breaks with a defined character string cellText = cellContent.ToString(); cellText = cellText.Replace("\n", "|"); //Read the string and put into Array of characters chars richTextBox1.AppendText("\n"+cellText); } } //Thread.Sleep(15000); } catch (Exception ex) { MessageBox.Show(ex.ToString()); //Thread.Sleep(15000); } finally { con.Close(); } 

首先,通过“打开Excel文件进​​行阅读并将其复制到剪贴板”来了解您的意思,这一点很重要。

这是非常重要的,因为有很多方法可以做到这一点,取决于你打算做什么。 让我解释:

  1. 如果你想读取一组数据并将其复制到剪贴板中,并知道数据格式(例如列名),我build议你使用OleDbConnection打开文件,这样你可以把xls文件的内容当作数据库表,所以你可以用SQL指令读取数据,并按照你的意愿处理数据。

  2. 如果您想用Excel对象模型对数据进行操作,请按照您开始的方式打开它。

  3. 有时候可以将xls文件当作一种csv文件来处理,还有一些工具,比如File Helper ,它允许你通过在任意对象上映射一个结构来以简单的方式处理和打开一个xls文件。

另一个重要的点是文件的Excel版本。

不幸的是,我说,尽pipe在应用自动化,数据pipe理和插件这些概念中有界限,并且通常我build议只使用Excel自动化或Office自动化,读取数据; 只要没有更好的方法来完成这个任务。

在自动化方面的工作可能会在资源成本方面performance沉重,可能会涉及到其他相关问题,例如涉及到安全性等问题,最后但不是至less,与COM互操作,它不是那么“自由”。所以我的build议在您的需求中思考和分析情况,然后采取更好的方式。

 try { DataTable sheet1 = new DataTable("Excel Sheet"); OleDbConnectionStringBuilder csbuilder = new OleDbConnectionStringBuilder(); csbuilder.Provider = "Microsoft.ACE.OLEDB.12.0"; csbuilder.DataSource = fileLocation; csbuilder.Add("Extended Properties", "Excel 12.0 Xml;HDR=YES"); string selectSql = @"SELECT * FROM [Sheet1$]"; using (OleDbConnection connection = new OleDbConnection(csbuilder.ConnectionString)) using (OleDbDataAdapter adapter = new OleDbDataAdapter(selectSql, connection)) { connection.Open(); adapter.Fill(sheet1); } } catch (Exception e) { Console.WriteLine(e.Message); } 

这对我有效。 请尝试一下,让我知道的查询。

使用OLEDB连接与excel文件进​​行通信。 它会给出更好的结果

 using System.Data.OleDb; string physicalPath = "Your Excel file physical path"; OleDbCommand cmd = new OleDbCommand(); OleDbDataAdapter da = new OleDbDataAdapter(); DataSet ds = new DataSet(); String strNewPath = physicalPath; String connString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + strNewPath + ";Extended Properties=\"Excel 12.0;HDR=Yes;IMEX=2\""; String query = "SELECT * FROM [Sheet1$]"; // You can use any different queries to get the data from the excel sheet OleDbConnection conn = new OleDbConnection(connString); if (conn.State == ConnectionState.Closed) conn.Open(); try { cmd = new OleDbCommand(query, conn); da = new OleDbDataAdapter(cmd); da.Fill(ds); } catch { // Exception Msg } finally { da.Dispose(); conn.Close(); } 

输出数据将存储在数据集中,使用数据集对象可以轻松访问数据。 希望这可能有帮助

没有Excel的Excel文件阅读器和作家在u'r系统

  • 下载并添加NPOI u'r项目的DLL。
  • 使用这个代码来读取一个excel文件。

      using (FileStream file = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) { XSSFWorkbook XSSFWorkbook = new XSSFWorkbook(file); } ISheet objxlWorkSheet = XSSFWorkbook.GetSheetAt(0); int intRowCount = 1; int intColumnCount = 0; for (; ; ) { IRow Row = objxlWorkSheet.GetRow(intRowCount); if (Row != null) { ICell Cell = Row.GetCell(0); ICell objCell = objxlWorkSheet.GetRow(intRowCount).GetCell(intColumnCount); }} 

使用Open XML 。

以下是一些代码,用于处理具有特定选项卡或表单名称的电子表格,并将其转储为类似CSV的内容。 (我select了一个pipe道而不是逗号)。

我希望从单元中获得价值更容易,但我认为这是我们所坚持的。 你可以看到,我参考了MSDN文档,我得到了大部分的代码。 这是微软推荐的。

  /// <summary> /// Got code from: https://msdn.microsoft.com/en-us/library/office/gg575571.aspx /// </summary> [Test] public void WriteOutExcelFile() { var fileName = "ExcelFiles\\File_With_Many_Tabs.xlsx"; var sheetName = "Submission Form"; // Existing tab name. using (var document = SpreadsheetDocument.Open(fileName, isEditable: false)) { var workbookPart = document.WorkbookPart; var sheet = workbookPart.Workbook.Descendants<Sheet>().FirstOrDefault(s => s.Name == sheetName); var worksheetPart = (WorksheetPart)(workbookPart.GetPartById(sheet.Id)); var sheetData = worksheetPart.Worksheet.Elements<SheetData>().First(); foreach (var row in sheetData.Elements<Row>()) { foreach (var cell in row.Elements<Cell>()) { Console.Write("|" + GetCellValue(cell, workbookPart)); } Console.Write("\n"); } } } /// <summary> /// Got code from: https://msdn.microsoft.com/en-us/library/office/hh298534.aspx /// </summary> /// <param name="cell"></param> /// <param name="workbookPart"></param> /// <returns></returns> private string GetCellValue(Cell cell, WorkbookPart workbookPart) { if (cell == null) { return null; } var value = cell.CellFormula != null ? cell.CellValue.InnerText : cell.InnerText.Trim(); // If the cell represents an integer number, you are done. // For dates, this code returns the serialized value that // represents the date. The code handles strings and // Booleans individually. For shared strings, the code // looks up the corresponding value in the shared string // table. For Booleans, the code converts the value into // the words TRUE or FALSE. if (cell.DataType == null) { return value; } switch (cell.DataType.Value) { case CellValues.SharedString: // For shared strings, look up the value in the // shared strings table. var stringTable = workbookPart.GetPartsOfType<SharedStringTablePart>() .FirstOrDefault(); // If the shared string table is missing, something // is wrong. Return the index that is in // the cell. Otherwise, look up the correct text in // the table. if (stringTable != null) { value = stringTable.SharedStringTable .ElementAt(int.Parse(value)).InnerText; } break; case CellValues.Boolean: switch (value) { case "0": value = "FALSE"; break; default: value = "TRUE"; break; } break; } return value; } 
 public void excelRead(string sheetName) { Excel.Application appExl = new Excel.Application(); Excel.Workbook workbook = null; try { string methodName = ""; Excel.Worksheet NwSheet; Excel.Range ShtRange; //Opening Excel file(myData.xlsx) appExl = new Excel.Application(); workbook = appExl.Workbooks.Open(sheetName, Missing.Value, ReadOnly: false); NwSheet = (Excel.Worksheet)workbook.Sheets.get_Item(1); ShtRange = NwSheet.UsedRange; //gives the used cells in sheet int rCnt1 = 0; int cCnt1 = 0; for (rCnt1 = 1; rCnt1 <= ShtRange.Rows.Count; rCnt1++) { for (cCnt1 = 1; cCnt1 <= ShtRange.Columns.Count; cCnt1++) { if (Convert.ToString(NwSheet.Cells[rCnt1, cCnt1].Value2) == "Y") { methodName = NwSheet.Cells[rCnt1, cCnt1 - 2].Value2; Type metdType = this.GetType(); MethodInfo mthInfo = metdType.GetMethod(methodName); if (Convert.ToString(NwSheet.Cells[rCnt1, cCnt1 - 2].Value2) == "fn_AddNum" || Convert.ToString(NwSheet.Cells[rCnt1, cCnt1 - 2].Value2) == "fn_SubNum") { StaticVariable.intParam1 = Convert.ToInt32(NwSheet.Cells[rCnt1, cCnt1 + 3].Value2); StaticVariable.intParam2 = Convert.ToInt32(NwSheet.Cells[rCnt1, cCnt1 + 4].Value2); object[] mParam1 = new object[] { StaticVariable.intParam1, StaticVariable.intParam2 }; object result = mthInfo.Invoke(this, mParam1); StaticVariable.intOutParam1 = Convert.ToInt32(result); NwSheet.Cells[rCnt1, cCnt1 + 5].Value2 = Convert.ToString(StaticVariable.intOutParam1) != "" ? Convert.ToString(StaticVariable.intOutParam1) : String.Empty; } else { object[] mParam = new object[] { }; mthInfo.Invoke(this, mParam); NwSheet.Cells[rCnt1, cCnt1 + 5].Value2 = StaticVariable.outParam1 != "" ? StaticVariable.outParam1 : String.Empty; NwSheet.Cells[rCnt1, cCnt1 + 6].Value2 = StaticVariable.outParam2 != "" ? StaticVariable.outParam2 : String.Empty; } NwSheet.Cells[rCnt1, cCnt1 + 1].Value2 = StaticVariable.resultOut; NwSheet.Cells[rCnt1, cCnt1 + 2].Value2 = StaticVariable.resultDescription; } else if (Convert.ToString(NwSheet.Cells[rCnt1, cCnt1].Value2) == "N") { MessageBox.Show("Result is No"); } else if (Convert.ToString(NwSheet.Cells[rCnt1, cCnt1].Value2) == "EOF") { MessageBox.Show("End of File"); } } } workbook.Save(); workbook.Close(true, Missing.Value, Missing.Value); appExl.Quit(); System.Runtime.InteropServices.Marshal.FinalReleaseComObject(ShtRange); System.Runtime.InteropServices.Marshal.FinalReleaseComObject(NwSheet); System.Runtime.InteropServices.Marshal.FinalReleaseComObject(workbook); System.Runtime.InteropServices.Marshal.FinalReleaseComObject(appExl); } catch (Exception) { workbook.Close(true, Missing.Value, Missing.Value); } finally { GC.Collect(); GC.WaitForPendingFinalizers(); System.Runtime.InteropServices.Marshal.CleanupUnusedObjectsInCurrentContext(); } } //code for reading excel data in datatable public void testExcel(string sheetName) { try { MessageBox.Show(sheetName); foreach(Process p in Process.GetProcessesByName("EXCEL")) { p.Kill(); } //string fileName = "E:\\inputSheet"; Excel.Application oXL; Workbook oWB; Worksheet oSheet; Range oRng; // creat a Application object oXL = new Excel.Application(); // get WorkBook object oWB = oXL.Workbooks.Open(sheetName); // get WorkSheet object oSheet = (Microsoft.Office.Interop.Excel.Worksheet)oWB.Sheets[1]; System.Data.DataTable dt = new System.Data.DataTable(); //DataSet ds = new DataSet(); //ds.Tables.Add(dt); DataRow dr; StringBuilder sb = new StringBuilder(); int jValue = oSheet.UsedRange.Cells.Columns.Count; int iValue = oSheet.UsedRange.Cells.Rows.Count; // get data columns for (int j = 1; j <= jValue; j++) { oRng = (Microsoft.Office.Interop.Excel.Range)oSheet.Cells[1, j]; string strValue = oRng.Text.ToString(); dt.Columns.Add(strValue, System.Type.GetType("System.String")); } //string colString = sb.ToString().Trim(); //string[] colArray = colString.Split(':'); // get data in cell for (int i = 2; i <= iValue; i++) { dr = dt.NewRow(); for (int j = 1; j <= jValue; j++) { oRng = (Microsoft.Office.Interop.Excel.Range)oSheet.Cells[i, j]; string strValue = oRng.Text.ToString(); dr[j - 1] = strValue; } dt.Rows.Add(dr); } if(StaticVariable.dtExcel != null) { StaticVariable.dtExcel.Clear(); StaticVariable.dtExcel = dt.Copy(); } else StaticVariable.dtExcel = dt.Copy(); oWB.Close(true, Missing.Value, Missing.Value); oXL.Quit(); MessageBox.Show(sheetName); } catch (Exception ex) { MessageBox.Show(ex.Message); } finally { } } //code for class initialize public static void startTesting(TestContext context) { Playback.Initialize(); ReadExcel myClassObj = new ReadExcel(); string sheetName=""; StreamReader sr = new StreamReader(@"E:\SaveSheetName.txt"); sheetName = sr.ReadLine(); sr.Close(); myClassObj.excelRead(sheetName); myClassObj.testExcel(sheetName); } //code for test initalize public void runValidatonTest() { DataTable dtFinal = StaticVariable.dtExcel.Copy(); for (int i = 0; i < dtFinal.Rows.Count; i++) { if (TestContext.TestName == dtFinal.Rows[i][2].ToString() && dtFinal.Rows[i][3].ToString() == "Y" && dtFinal.Rows[i][4].ToString() == "TRUE") { MessageBox.Show(TestContext.TestName); MessageBox.Show(dtFinal.Rows[i][2].ToString()); StaticVariable.runValidateResult = "true"; break; } } //StaticVariable.dtExcel = dtFinal.Copy(); } 

我build议你使用Bytescout电子表格。

https://bytescout.com/products/developer/spreadsheetsdk/bytescoutspreadsheetsdk.html

我在Unity3D中使用Monodevelop进行了尝试,而且非常简单。 检查这个示例代码,看看这个库是如何工作的:

https://bytescout.com/products/developer/spreadsheetsdk/read-write-excel.html