如何使用C#读取Excel文件的数据?
如何使用C#读取Excel文件的数据?
如何使用C#读取Excel文件?我打开一个Excel文件进行读取,并将其复制到剪贴板以搜索电子邮件格式,但我不知道如何做到这一点。\n
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(); } } } }
如何使用C#读取Excel文件的数据?
为什么不创建OleDbConnection?在互联网上有很多可用的资源。这里是一个示例:
OleDbConnection con = new OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source="+filename+";Extended Properties=Excel 8.0"); con.Open(); try { //创建数据集并从Excel电子表格中填充信息,以便更容易地引用 DataSet myDataSet = new DataSet(); OleDbDataAdapter myCommand = new OleDbDataAdapter(" SELECT * FROM ["+listname+"$]" , con); myCommand.Fill(myDataSet); con.Close(); richTextBox1.AppendText("\nDataSet Filled"); //遍历数据集中的每一行 foreach (DataRow myDataRow in myDataSet.Tables[0].Rows) { //将数据行中的信息存储到数组中 Object[] cells = myDataRow.ItemArray; //遍历数组并将其放入对象cellContent中,作为Object类型 //使用对象是因为数据集会读取一些空值,这会在尝试读取时出现问题。 //通过使用对象,我可以稍后将其转换为字符串。 foreach (object cellContent in cells) { //将对象cellContent转换为字符串,同时用指定字符替换换行符 string cellText = cellContent.ToString(); cellText = cellText.Replace("\n", "|"); //读取字符串并将其放入字符数组chars中 richTextBox1.AppendText("\n"+cellText); } } } catch (Exception ex) { MessageBox.Show(ex.ToString()); } finally { con.Close(); }
我在使用OleDbConnection(使用Oracle Data Adapter)时遇到的一个问题是,一个列既包含数字又包含文本。我得到了一个以数字格式化的DataTable,其中缺少以文本格式化的数据的单元格。我的解决方法是在使用OleDBC获取数据之前,使用interop将整个列的已使用范围转换为文本格式。
最后一个可用的存档链接在这里。只有40行...可能可以编辑帖子并添加进去。耸肩
文章题目:如何使用C#读取Excel文件的数据?
在C#中,可以使用Microsoft.Office.Interop.Excel程序集来处理Excel文件。
1. 在项目上右键点击,选择“添加引用”。添加Microsoft.Office.Interop.Excel程序集。
2. 使用"using Microsoft.Office.Interop.Excel;"引入程序集。
下面是示例代码:
using Microsoft.Office.Interop.Excel; // 创建一个可以在成员函数中使用的Application对象 Microsoft.Office.Interop.Excel.Application _excelApp = new Microsoft.Office.Interop.Excel.Application(); _excelApp.Visible = true; string fileName = "C:\\sampleExcelFile.xlsx"; // 打开工作簿 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); // 选择第一个工作表 Worksheet worksheet = (Worksheet)workbook.Worksheets[1]; // 查找工作表中使用的范围 Range excelRange = worksheet.UsedRange; // 获取工作表中所有单元格的对象数组(它们的值) object[,] valueArray = (object[,])excelRange.get_Value( XlRangeValueDataType.xlRangeValueDefault); // 访问单元格 for (int row = 1; row <= worksheet.UsedRange.Rows.Count; ++row) { for (int col = 1; col <= worksheet.UsedRange.Columns.Count; ++col) { // 访问每个单元格 Debug.Print(valueArray[row, col].ToString()); } } // 清理资源 workbook.Close(false, Type.Missing, Type.Missing); Marshal.ReleaseComObject(workbook); _excelApp.Quit(); Marshal.FinalReleaseComObject(_excelApp);
我发现在“清理资源”时,以下COM对象需要先声明,然后在“clean up stuffs”中使用ReleaseComObject()释放,否则在代码完成后会有一个僵尸Excel进程正在运行:在_excelApp.Workbooks创建的Workbooks对象,workbook.Worksheets创建的Worksheets对象,worksheet.UsedRange.Rows和worksheet.UsedRange.Columns创建的Range对象,以及excelRange对象。另外,我认为将两个worksheet.UsedRange的使用替换为excelRange变量,以防止使用现有变量创建更多的COM对象。
如何使用C#读取Excel文件的数据?
这个问题的原因是,Excel VSTO编程中比较难理解的一个概念是,你不能像访问数组一样引用单元格,即Worksheet[0][0]
不能给你A1单元格,而会报错。即使你在Excel打开时在A1单元格中输入值,实际上你是在输入Range A1的数据。因此,你需要将单元格引用为命名区域。下面是一个示例:
Excel.Worksheet sheet = workbook.Sheets["Sheet1"] as Excel.Worksheet; Excel.Range range = sheet.get_Range("A1", Missing.Value);
你现在可以直接使用以下代码:
range.Text // 这将给你用户看到的文本 range.Value2 // 这将给你Excel存储的实际值(不进行四舍五入)
如果你想要做类似于以下的操作:
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#尚不支持这种属性。
至于清理代码,我明天上班时会贴出来,我现在没有代码,但它非常模板化。你只需按照你创建它们的相反顺序关闭和释放对象。你无法使用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。一旦你连续两次输入Type.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; //给你找到的值
这是受此网站启发的另一个示例:
range = sheet.Cells.Find("Value to find", Type.Missing, Type.Missing,Excel.XlLookAt.xlWhole,Excel.XlSearchOrder.xlByColumns,Excel.XlSearchDirection.xlNext,false, false, Type.Missing);
了解这些参数会有所帮助。
P.S. 我是那些喜欢学习COM自动化的怪人之一。所有这些代码都源自我为工作编写的一个工具,需要我每个星期一处理1000多个实验室的电子表格。
我想从Listview读取Excel文件以搜索电子邮件地址...我正在尝试做这个...但我不知道Excel的编码类型,也就是数据格式...我如何读取Excel文件来搜索电子邮件地址...我不想使用数据连接
+1,非常详细的答案。我刚刚从一个恢复的硬盘丢失了400多个xls文件的名称和日期,这个答案让我在一个小时内重新回到了正轨。
为什么声明行“using ExcelTools = Ms.Office;”会显示“找不到类型或命名空间名'Ms'”?
Ms.Office命名空间没有什么特别之处。它包含一个静态方法的类,该类封装了Interop库的Open、Save、Add方法,以提供常见的重载,并隐藏了COM Interop库所需的一些Type.Missing和Missing.Value参数。如果你需要我发布代码,我可以提供。
“VB.NET很好地处理了可选参数,C#则没有,因此需要使用Type.Missing。”实际上,我认为自从C# 4之后,C#也很好地处理可选参数。更多信息请参见这里:blogs.msdn.com/b/samng/archive/2009/06/16/…
嗨Chris,你是否有你编写的Excel函数方便的代码?上面的Ms.ExcelTools?如果你能提供,对我来说将非常有帮助。