winform开发过程中有时候会涉及到批量数据导入数据库的问题,比如单位人员查体信息,医保人员缴费信息,学生信息录入等,
这个时候一般通过Excel模板录入数据,然后批量导入数据库,这里分享一段自用的C#Excel数据导入源代码
演示实例
演示程序在Form窗口上添加了一个Button按钮,一个dataGridView控件
Button按钮实现方法
private void btnExcel_Click(object sender, EventArgs e) { try { OpenFileDialog fd = new OpenFileDialog(); fd.Filter = "Excel(97-2003)文件|*.xls|所有文件|*.*"; fd.Title = "打开文件夹"; string path = ""; fd.InitialDirectory = "d:\\"; fd.FilterIndex = 1; if (fd.ShowDialog() == DialogResult.OK) { path = fd.FileName; } string tableName = GetExcelFirstTableName(path); //设置T_Sql string TSql = "SELECT * FROM [" + tableName + "]"; //读取数据 DataTable table = ExcelToDataSet(path, TSql).Tables[0]; dataGridView1.DataSource = table; } catch(Exception ex) { MessageBox.Show(ex.Message); } }
点击导入按钮弹出文件选择界面,打开需要导入的Excel文件
OpenFileDialog fd = new OpenFileDialog(); fd.Filter = "Excel(97-2003)文件|*.xls|所有文件|*.*";//文件过滤器 fd.Title = "打开文件夹";//文件选择对话框标题 string path = ""; fd.InitialDirectory = "d:\\";//默认打开文件夹路径 fd.FilterIndex = 1; if (fd.ShowDialog() == DialogResult.OK) { path = fd.FileName;//获取文件完整路径 }
选择Excel后点击对话框打开按钮,Excel第一个Sheet1中的数据就导入dataGridView中了
这里有两个核心函数,一个是动态获取Excel表名
string tableName = GetExcelFirstTableName(path);
GetExcelFirstTableName代码
/// <summary> /// 动态取Excel表名 /// </summary> /// <param name="fullPath">文件路径</param> /// <returns></returns> public static string GetExcelFirstTableName(string fullPath) { string tableName = null; if (File.Exists(fullPath)) { using (OleDbConnection conn = new OleDbConnection("Provider=Microsoft.Jet." + "OLEDB.4.0;Extended Properties=Excel 8.0;Data Source=" + fullPath)) { conn.Open(); tableName = conn.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, null).Rows[0][2].ToString().Trim(); } } return tableName; }
另一个是返回Excel数据源
DataTable table = ExcelToDataSet(path, TSql).Tables[0];
ExcelToDataSet代码
/// <summary> /// 返回Excel数据源 /// </summary> /// <param name="filename">文件路径</param> /// <param name="TSql">TSql</param> /// <returns>DataSet</returns> public static DataSet ExcelToDataSet(string filename, string TSql) { DataSet ds; string strCon = "Provider=Microsoft.Jet.OLEDB.4.0;Extended Properties=Excel 8.0;data source=" + filename; OleDbConnection myConn = new OleDbConnection(strCon); string strCom = TSql; myConn.Open(); OleDbDataAdapter myCommand = new OleDbDataAdapter(strCom, myConn); ds = new DataSet(); myCommand.Fill(ds); myConn.Close(); return ds; }
命名空间引用
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using System.IO; using System.Data.OleDb;
注意
连接字符串的问题。采用Microsoft.Jet.OleDb.4.0,可以读取excel2007以前的版本,在客户机上不需要部署office,采用Microsoft.Ace.OleDb.12.0的时候,需要安装引擎。
@"Provider=Microsoft.Ace.OleDb.12.0;" + "data source=" + excelFile + @";Extended Properties='Excel 12.0; HDR=YES; IMEX=1'"; //此连接可以操作.xls与.xlsx文件。//备注: "HDR=yes;"是说Excel文件的第一行是列名而不是数据,"HDR=No;"正好与前面的相反。 "IMEX=1 "如果列中的数据类型不一致,使用"IMEX=1"可必免数据类型冲突。
Microsoft.Ace.OleDb.12.0未安装,可以到下载2007 Office system 驱动程序AccessDatabaseEngine2007_CHS.zip:
数据连接组件安装 http://download.microsoft.com/download/7/0/3/703ffbcb-dc0c-4e19-b0da-1463960fdcdb/AccessDatabaseEngine.exe
oledb连接打开的时候出现外部表不是预期的格式,这是因为读取的表格可能是带有html的格式,需要打开该表格,另存为标准的xls格式文档即可读取
采用oledb的时候读取和读写都比较的方便快速,尤其是可以不需要安装office组件,采用sql语句进行操作通用性强,将Excel中内容看作数据表,读取操作简单可靠,适合内容规范的Excel表格的数据读取但是缺点是当Excel结构复杂,如含合并单元等时,无法正确读取,甚至出现不可预知的异常。