红色部分为2013.1.19日修改的内容。

  最近做项目,项目经理让我把一个600多行的Excel文件录入数据库。本来不是什么难事,因为很多数据库管理工具都提供Excel表格导入功能,像Navicat for MySQL,Sql Server Management等都自带导入Excel表格功能。但接过Excel文件打开一看傻眼了,这个Excel文件里面的数据格式类似tree,每个根节点下面好多子节点,额,表达能力不好,我还是直接上图给大家看吧。

  先拆分了一下单元格,结果留下了无数的空白单元格需要我手动填满,不是拖一下鼠标就能解决的,坑爹啊!让我动手填满?没门,累死老子都不干这种缺心眼的事!作为一个程序猿,思考了一下决定写个C#桌面程序吧,写asp.net的话拿到别的电脑上用还得用IIS才行。

  先放上做完之后的效果图:

  

  需要完成的功能:

  1、正常连接数据库(SqlServer,MySQL,Oracle)

  2、能解析Excel文件(Excel2003及以下版本的.xls以及2007及以上版本的.xlsx)

  3、Excel文件中空白单元格能自动填充。

  4、可以从数据库中将数据导出为Excel文件。

 

  大概说说编码的过程。

  一、首先就是连接数据库。针对三种不同的数据库,连接方法也不相同。MySQL引用了外部组件MySql.Data.dll,版本6.5.4.0。下面是数据库连接字符串:

protected string ConString()
        {
            string CnnString = "";
            switch (cbSelDB.SelectedIndex)
            {
                case 0://Sql Server数据库连接字符串
                    CnnString = "Provider=SQLOLEDB;server=" + txtHost.Text + ";database=" + txtDBname.Text + ";uid=" + txtUser.Text + ";pwd=" + txtPwd.Text;
                    break;
                case 2://Oracle数据库连接字符串
                    CnnString = "Provider=OraOLEDB.Oracle;Data Source=" + txtDBname.Text + ";User id=" + txtUser.Text + ";Password=" + txtPwd.Text;
                    break;
                case 1://MySQL数据库连接字符串
                    CnnString = "server=" + txtHost.Text + ";Database=" + txtDBname.Text + ";User Id=" + txtUser.Text + ";Password=" + txtPwd.Text;
                    break;
                default:
                    break;
            }
            return CnnString;
        }

  二、解析.xls和.xlsx。C#中提供了Microsoft.Jet.OLEDB.4.0组件可以操作Excel2003及以下版本,但Excel2007及以上版本则不提供支持。没办法,上网搜,终于搜到了AccessDatabaseEngine提供的Microsoft.ACE.OLEDB.12.0组件,可以操作Excel2007。下载地址如下,下载完成后安装即可直接使用。

http://download.microsoft.com/download/7/0/3/703ffbcb-dc0c-4e19-b0da-1463960fdcdb/AccessDatabaseEngine.exe

  3楼提出的问题确实存在,对代码进行了修改。

  

  修改后依然存在一些小问题,这种方法,默认对于该列的前8条数据必须为混合型,该列才会作为混合型数据处理,否则只取前8条对于的数据类型。

  解决方案:修改注册表,将默认值8修改为你需要的数值:

Jet 4.0: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Jet\4.0\Engines\Excel\TypeGuessRows
ACE 12.0: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Office\12.0\Access Connectivity Engine\Engines\Excel\TypeGuessRows

 

private string CheckExcelVer()//Excel连接字符串
        {
            string strConn = "";
            if (txtPath.Text.EndsWith(".xlsx"))//判断当选择的文件后缀名是.xlsx时,调用Microsoft.ACE.OLEDB.12.0
            {
                strConn = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + txtPath.Text + ";Extended Properties=‘Excel 12.0;IMEX=1;'";
            }
            else
            {
                strConn = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + txtPath.Text + ";Extended Properties='Excel 8.0;IMEX=1;'";

            }
            return strConn;
        }

 

  三、读取Excel中分页并绑定至下拉菜单。

private void Excel_Changed(object sender, EventArgs e)
        {

            ArrayList al = new ArrayList();

            string strConn = CheckExcelVer();//检查是.xlsx还是.xls文件
            OleDbConnection conn = new OleDbConnection(strConn);
            conn.Open();
            System.Data.DataTable sheetNames = conn.GetOleDbSchemaTable
            (System.Data.OleDb.OleDbSchemaGuid.Tables, new object[] { null, null, null, "TABLE" });
            conn.Close();
            comboBox1.DataSource = null;
            comboBox1.Items.Clear();
            foreach (DataRow dr in sheetNames.Rows)
            {
                al.Add(dr[2]);
                comboBox1.Items.Add(dr[2].ToString());

            }
            comboBox1.DataSource = comboBox1.Items;
        }

  四、读取Excel分页中数据。

protected void ReadSheet()
        {
            string strConn = CheckExcelVer();
            OleDbConnection cnnxls = new OleDbConnection(strConn);
            string sheet = comboBox1.SelectedValue.ToString();
            OleDbDataAdapter myDa = new OleDbDataAdapter("select * from [" + sheet + "]", cnnxls);//sheet是下拉菜单中选中的分页
            DataSet myDs = new DataSet();
            myDa.Fill(myDs);
            string[] sqls=readExcel(myDs);
        }

  五、构建写入数据库字符串。

protected string[] readExcel(DataSet myDs)//传过来的是包含Excel表格中数据的DateSet
        {
            string[] Sqls = new string[myDs.Tables[0].Rows.Count];
            if (myDs.Tables[0].Rows.Count > 0)
            {

                string strSql = "";

                string[,] t = new string[myDs.Tables[0].Rows.Count, myDs.Tables[0].Columns.Count];
                string item = "";
                for (int i = 0; i < myDs.Tables[0].Columns.Count; i++)
                {
                    if (i > 0)
                    {
                        item += "," + myDs.Tables[0].Columns[i].ColumnName;
                    }
                    else
                    {
                        item += myDs.Tables[0].Columns[i].ColumnName;

                    }

                }
                for (int i = 0; i < myDs.Tables[0].Rows.Count; i++)
                {
                    strSql = "insert into " + txtTable.Text + " (" + item + ") values ('";
                    for (int h = 0; h < myDs.Tables[0].Columns.Count; h++)
                    {
                        t[i, h] = myDs.Tables[0].Rows[i].ItemArray[h].ToString();
                        if (radioButton1.Checked == true && comboBox2.SelectedIndex == 0)//选择了纵向填充。
                        {
                            if (t[i, h] == "")
                            {
                                t[i, h] = t[i - 1, h];
                            }
                        }
                        if (radioButton1.Checked == true && comboBox2.SelectedIndex == 1)//选择了横向填充
                        {
                            if (t[i, h] == "")
                            {
                                t[i, h] = t[i, h - 1];
                            }
                        }
                        if (h > 0)
                        {
                            strSql += "','" + t[i, h];
                        }
                        else
                        {
                            strSql += t[i, h];
                        }


                    }

                    strSql += "')";
                    Sqls[i] = strSql;
                    Step(i, myDs.Tables[0].Rows.Count);

                }


            }
            return Sqls;
        }

  剩下的就是写入数据库了,就不赘述了。数据库导出Excel功能相信接触过的人都会做,很简单,不知道的百度一下。

  最后附上成品,界面简单的设计了一下,写了个使用说明,希望对你有帮助!不知道院子里怎么传附件,我传到网盘里吧。

  新生成的修复了一个小Bug,我改成了V2.1,已经重新传了。

  源代码也已经共享咯,和软件一起放到了网盘里,需要的朋友自己下载看吧!喜欢的话请点一下推荐,你的支持才是我的动力!

http://dl.vmall.com/c0n9b3ljv4

 

 

posted on 2013-01-18 15:41  站住小子  阅读(5303)  评论(24编辑  收藏  举报