最近应要求写了一段代码,读取excel数据。excel读取方法有两个,两个各有自己的优势,同时也有各自的缺点。
方法一:采用sqlCommand命令读取方法。
具体实现代码如:
//FilePath是路径
string conn = @"Provider=Microsoft.Jet.OLEDB.4.0;Data Source='" + FilePath + ";Extended Properties =Excel 8.0;";
//Sheet1 是表名
string sql = "select * from [Sheet1$] where [Rows]=" + 5;
OleDbCommand cmd = new OleDbCommand(sql, new OleDbConnection(conn));
OleDbDataAdapter ad = new OleDbDataAdapter(cmd);
DataSet ds = new DataSet();
ad.Fill(ds);
dt = ds.Tables[0];
dataGridView1.DataSource = ds.Tables[0];
这个方法的最大优点就是像操作数据库一样,能快速地读取数据,将数据保存到列表中。但是正因为跟数据库相似,所以excel数据的格式要统一,不能有标题什么的。因为我做的过程中所读的表固定前五行固定是标题,所以一直报错:在第33行格式不符,气死我了…………。
第二种方式是最传统的excel操作方式:
1,在引用部分添加引用:在com组建部分添加Microsoft Office12.0 object library 和Microsoft Excel 12.0 object library 两个库。
在文件标头添加
using Microsoft.Office.Core;
using Excel;
然后读取的代码是:
Excel.ApplicationClass app = new ApplicationClass();
Excel.Application excel = null;
Excel.Workbooks wbs = null;
Excel.Workbook wb = null;
Excel.Worksheet ws = null;
Excel.Range rang1 = null;
object Nothing = System.Reflection.Missing.Value;
excel = new Excel.Application();
try
{
FilePath是路径
//string conn = @"Provider=Microsoft.Jet.OLEDB.4.0;Data Source='" + FilePath + ";Extended Properties =Excel 8.0;";
Sheet1 是表名
//string sql = "select * from [Sheet1$] where [Rows]=" + 5;
//OleDbCommand cmd = new OleDbCommand(sql, new OleDbConnection(conn));
//OleDbDataAdapter ad = new OleDbDataAdapter(cmd);
//DataSet ds = new DataSet();
//ad.Fill(ds);
//dt = ds.Tables[0];
//dataGridView1.DataSource = ds.Tables[0];
excel.UserControl = true;
excel.DisplayAlerts = false;
excel.Application.Workbooks.Open(FilePath, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing);
wbs = excel.Workbooks;
wb = wbs[1];
ws = (Excel.Worksheet)wb.Worksheets["Sheet1"];
int rowCount = ws.UsedRange.Rows.Count;
if (rowCount <= 5)
{
DataCount = 0;
return;
}
else
{
DataCount = rowCount - 5;
for (int i = 5; i <= rowCount; i++)
{
DataRow row1 = dt.NewRow();
rang1 = ws.get_Range(ws.Cells[i, 1], ws.Cells[i, 1]);
row1[0] = rang1.Value2;
row1[0] = app.WorksheetFunction.Text(rang1.Value2, "yyyy-mm-dd hh:mm:ss");
for (int j = 2; j <= 11; j++)
{
rang1 = ws.get_Range(ws.Cells[i, j], ws.Cells[i, j]);
row1[j - 1] = rang1.Value2;
//ReadStatus = (i-5)/DataCount ;
//SetMyGBar(ReadStatus);
}
dt.Rows.Add(row1);
}
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
return;
}
finally
{
if (excel != null)
{
if (wbs != null)
{
if (wb != null)
{
if (ws != null) ;
{
if (rang1 != null)
{
System.Runtime.InteropServices.Marshal.ReleaseComObject(rang1);
rang1 = null;
}
System.Runtime.InteropServices.Marshal.ReleaseComObject(ws);
ws = null;
}
wb.Close(false, Nothing, Nothing);
System.Runtime.InteropServices.Marshal.ReleaseComObject(wb);
wb = null;
}
wbs.Close();
System.Runtime.InteropServices.Marshal.ReleaseComObject(wbs);
wbs = null;
}
excel.Application.Workbooks.Close();
excel.Quit();
System.Runtime.InteropServices.Marshal.ReleaseComObject(excel);
GC.Collect();
Read = true;
}
}
这个方法是逐行读取,好的地方就在于excel读取方式灵活,不想sqlcommand那么死板,可是最大的痛苦就是一个文件它要消化好久才能全部读取,花费的时间太大,还好我所做的时间可以久点,不知道你们有什么更好的方法,方便的话说出来给我参考参考。
在第二种方法中:我读取的数据中有日期时间,读取出来是39000.00000什么的,试过了很多种C#转换,依然无法如愿,最后考虑到这个事excel的函数,excel那么多函数,那么我们就从excel类中入手。
Excel.ApplicationClass app = new ApplicationClass();//初始化excel函数类。
row1[0] = app.WorksheetFunction.Text(rang1.Value2, "yyyy-mm-dd hh:mm:ss");//将那个数据转换为1990-1-1 12:30:12 ,呵呵……最后就读取excel的数据就ok了。看来简简单单的几句话,再加上zedgraph图像的X显示为事件数据,整整花了我两天的时间。至于zedgraph的内容,稍后更新。这是我第一篇技术文章。请各位博友给我一点点支持,谢谢……