Excel表格导入数据库Demo小结
(1) 在没有写之前,我先说下的我总体的思路。
第一步:首先我们要能读出Excel表格里面的数据
第二步:把Excel表格的数据显示在控件上,我选择的是dataGridView
第三步:把显示在控件的上的数据插入到数据库中
这三步是必须要有的过程…
(2) 就是具体的代码实现过程了,我简述下我在做的过程遇到的一些问题,怎么解决的,我是怎么想的。
第一步:首先就要想到操作Excel表格的类是哪个?
→网上查了下用OleDbConnection这个可以用来操作Access数据库的,和连接SqlServer数据库的连接操作十分相似,提一点的就是连接字符串的不同 如下:
//备注: "HDR=yes;"是说Excel文件的第一行是列名而不是数据,"HDR=No;"正好与前面的相反。"IMEX=1 "如果列中的数据类型不一致,使用"IMEX=1"可必免数据类型冲突。
stringstrConn="Provider=Microsoft.Jet.OleDb.4.0;data source="+fileName+";Extended Properties='Excel 8.0; HDR=Yes"+"; IMEX=1'";
这个是用来操作2003的,至于具体的含义代码注释里有。
第二步:如何分辨用户给的是2003和2007的?
→Ok,这个问题呢?很容易想到用后缀名加以区别的。嗯,的确这样的一毫不错。就是通过截取文件名后缀名实现的
第三步:连接字符串有了,还差什么呢?
→OK,还有个不要忘了,就是查询语句喽 ,和Sql相似度90以上,请看“select * from sheetname”,sheetname是什么玩意呢?嗯,这个呢就是Excel表格的页面名称,就是在最左边下面的通常就是sheet1$, sheet2$, sheet3$。现在就可以吧数据绑定在dataGridView上了。
第四部;(重点来了……)现在数据有了,就是把数据插入到Sqlserver中。这个有点小麻烦,容我细细说……
(1) 说下总体思路:动态的得到dataGridView中的列名→并得到列名下面对应的值→通过字符串拼接→进行sql语句的拼接→插入数据库中
(2) Ok,我仔细说说 看下面的这段代码:
string[]Colume_Name=newstring[dataGridView1.ColumnCount];
for (inti=0; i
{
Colume_Name[i]=dataGridView1.Columns[i].Name;
}
这样呢,就动态的得到了列名
再看下面的代码:
//用列名下对应下的值字符串的拼接
StringBuilder sb=newStringBuilder();
for(intj=0;j
{
value_Name[j] =dr[Colume_Name[j]].ToString();
//得到的值用sb.Append串接,并把最后一个的逗号掉
sb.Append("'"+value_Name[j]+"'"+",");
}
通过循环,就可以动态的得到每个列名下面对应的数值。这里面呢,我是通过字符串拼接的方式保留每次循环列名下面的对应的值,最后呢通过字符串截取的方式,把最后一次拼接之后的多余一个逗号要扔掉,在这里呢字符串截取的时候我是通过MessageBox.Show(),报出字符串是否截取符合要求。当然还有sql语句我就没有贴出来了,具体的再看代码。
第五步:我知道Excel中可能有很多个页面,下面呢我就拿到所有的页面名称,看代码实现(这次贴个完整的)
//(strConn就是上面说的连接字符串)
OleDbConnectionmyConn = new OleDbConnection(strConn);
OleDbDataAdapter da = newOleDbDataAdapter("select * from [" + sheetname + "]",strConn);
//sheetname是我事先写死的“sheet1$”
DataSet ds=new DataSet();
try
{
myConn.Open();
da.Fill(ds);
dtgobal = ds.Tables[0];
this.dataGridView1.DataSource =dtgobal;
}
catch (Exception ex)
{
MessageBox.Show("Excel文档打开失败,请检查Office套件是否是2003或者2007!\r\n" + Convert.ToString(ex.Message),"打开Excel文档提示信息", MessageBoxButtons.OK,MessageBoxIcon.Error);
return;
}
DataTable dt =myConn.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, new object[] { null, null,null, "TABLE" });
//将列名添加到下拉列表中
string SheetName = "";
cboSheetName.Items.Clear();
foreach (DataRow dr in dt.Rows)
{
SheetName =dr["TABLE_NAME"].ToString();
if(SheetName.Contains("\'"))
SheetName =SheetName.Substring(0, SheetName.Length - 2);
cboSheetName.Items.Add(SheetName);
}
// return;
myConn.Close();
第六步:就是函数调用了,传递参数,插入库中具体的看代码实现
string strconn =string.Format(@"server=.\sqlexpress;database={0};IntegratedSecurity=True", SqlName);//用户选择的库名
conn = new SqlConnection(strconn);
conn.Open();
if (dataGridView1.Rows.Count >0)
{
DataRow dr = null;
for (int i = 0; i
{
dr = dtgobal.Rows[i];
InsertToSql(dr,SqlTable_Name);//Sql_Table就是用户自己选择的要进行插入的表名
}
conn.Close();
MessageBox.Show("导入成功!");
}
else
{
MessageBox.Show("没有数据");
conn.Close();
}
—————————————华丽的分割线————————————
剩下的这几步呢就是把功能强化些了……
第七步:连接数据库,把所有的数据库文件显示在ComboBox中,在通过全局变量来记录点击ComboBox控件记录数据库文件名字,此时在传递出去:
//得到数据库中的表名→利用全局变量记录值
private voidcb_SqlTabel_Name_SelectedIndexChanged(object sender, EventArgs e)
{
SqlTable_Name =cb_SqlTabel_Name.SelectedItem.ToString();
}
第八步:有了数据库就要想到数据库下面的表名:
stringconstr = string.Format("server=.\\sqlexpress;database={0};integratedsecurity=true", SqlName);
////查询表名
string sqltext =string.Format("select * from sysobjects where xtype = 'U'");
DataTable dt = new DataTable();
using (SqlConnection conn = newSqlConnection(constr))
{
conn.Open();
using (SqlCommand cmd =conn.CreateCommand())
{
cmd.CommandText = sqltext;
SqlDataAdapter adapter =new SqlDataAdapter(cmd);
adapter.Fill(dt);
}
}
foreach (DataRow row in dt.Rows)
{
cb_SqlTabel_Name.Items.Add(row["name"].ToString());
}
把表名添加到ComboBox中,此时在利用全局变量记录表名,再传递出去。
第九步:通过这两步,用户就可以选择哪个数据库文件下的那个表名了,
最后呢:这个Demo工具很大的缺陷,我一直都没有做好的,就是Excel表格第一行必须是列名,而不能是其他的,什么意思呢!上图看看
这样的标头很简单的就能导入数据库中 但是下面的
这样的表格我就不会处理了,这是个硬伤。
总结问题:
(1) 连接Excel表格的字符串
(2) 判断用户输入的Excel版本
(3) 读取数据显示在控件上
(4) 动态的得到控件上的列名以及对应下的值,并用StringBuilder拼接插入字符串
(5) 得到Excel表格的页面
(6) 得到数据库中的数据文件,以及是哪个表
(7) 在插入选择的表
(8) 先还要在数据库中建好表格,表格的列名数目一定要Excel表格的数目相同的,否则插入失败,同时注意字段的类型问题。