写了一个关于简单的Excel表格导入sqlserver

                                          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<dataGridView1.ColumnCount;i++)

            {

                Colume_Name[i]=dataGridView1.Columns[i].Name;

            }

这样呢,就动态的得到了列名

再看下面的代码:

               //用列名下对应下的值字符串的拼接

            StringBuilder sb=newStringBuilder();

       for(intj=0;j<dataGridView1.ColumnCount;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 <dtgobal.Rows.Count; 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表格的数目相同的,否则插入失败,同时注意字段的类型问题。

你可能感兴趣的:(Excel,Office,sqlserver)