zoukankan      html  css  js  c++  java
  • asp.net 自编的Excel导入功能小例

    最近接的工作需要做Excel文件导入数据库的功能,当时未提供文件格式,于是有了后来那点事。

    思想:通过XML文件来保存EXCEL文件的格式、字段,并与数据库中字段对应。这样EXCEL变动时程序中只调整xml文件就可以实现匹配。

    整个内容分三部分:1.通过XML文件来保存EXCEL文件的格式、字段,并与数据库中字段对应,

    2.读取EXCEL文件名及页标签,

    3.执行导入。

    XML文件:

    <?xml version="1.0" encoding="utf-8" ?>
    <ExcelFiles>
      <ExcelFile SQLname="数据库中表名" fileName="EXCEL文件名" >
        <columns>
          <!--<column SQLname="数据库中字段名" fileName="EXCEL中字段名" OracleDbType="Oracle数据库中该字段类型" ></column> -->
          <column SQLname="a" fileName="表字段A" OracleDbType="VARCHAR2"></column>
          <column SQLname="b" fileName="表字段B " OracleDbType="VARCHAR2"></column>

     <!-- 注意这里用到了双结点及结点下含子节点 -->
          <columns SQLname="c,d" fileName="表字段C,表字段D " OracleDbType="VARCHAR2">

        <column SQLname="e" fileName="表字段E" OracleDbType="VARCHAR2"></column>
            <column SQLname="f" fileName="表字段F " OracleDbType="VARCHAR2"></column>
      </columns>

          <column SQLname="g" fileName="G" OracleDbType="VARCHAR2"></column>

    对应EXCEL表格形式:

    A B C,D G
    E F
    数据 数据 数据 数据 数据
    数据 数据 数据 数据 数据
    数据 数据 数据 数据 数据
    数据 数据 数据 数据 数据
    数据 数据 数据 数据 数据
    数据 数据 数据 数据 数据

        /// <summary>
        /// 查询xml文件找到EXCEL文件的对应项。
        /// </summary>
        /// <param name="sqlName">对应SQL表名</param>
        /// <param name="columnlist">EXCEL文件的列名及对应SQL表字段名</param>
        /// <param name="fileName">EXCEL文件的文件名</param>
        public void getSQLName(out string sqlName, out XmlNodeList columnList, string fileName)
        {
            System.Xml.XmlDocument xmlDoc = new System.Xml.XmlDocument();
            xmlDoc.Load(Server.MapPath("XMLFile.xml"));
            XmlNodeList list = xmlDoc.SelectSingleNode("ExcelFiles").ChildNodes;
            sqlName = string.Empty;
            columnList = null;
            foreach (XmlNode node in list)
            {
                if (fileName.Contains(node.Attributes["fileName"].Value.ToString()) && node.Attributes["fileName"].Value.ToString()!=string.Empty )
                {
                    sqlName = node.Attributes["SQLname"].Value.ToString();
                    columnList = node.SelectSingleNode("columns").ChildNodes;

          //这块代码应该写成一个递归循环查看子节点下是否还有子节点,我这里没改,要用多层循环的自己改下咯。
                }
            }
            if (sqlName == string.Empty)
            {
                ScriptManager.RegisterClientScriptBlock(this, this.GetType(), "", "alert('没有找到同类型的EXCEL文件模板,请检查上传的文件名是否符号要求!');", true);
                return;
            }
        }

    2.

        /// <summary>
        /// 获得Excel中的第一个下标:sheetname。方法是先返回Excel的架构信息,再从架构中读取下标。
        /// </summary>
        /// <param name="filepath">服务器中的文件的物理路径</param>
        /// <returns></returns>
        public void ExcelSheetName( out string sheetname,string filepath )
        {
            sheetname = string.Empty;
            string strConn;
            strConn = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + filepath + ";Extended Properties=Excel 8.0;";
            OleDbConnection conn = new OleDbConnection(strConn);
            conn.Open();
            DataTable sheetNames = conn.GetOleDbSchemaTable
            (System.Data.OleDb.OleDbSchemaGuid.Tables, new object[] { null, null, null, "TABLE" });
            conn.Close();
            foreach (DataRow dr in sheetNames.Rows)
            {
                sheetname = dr[2].ToString();
            }
        }

    3.

    /// <summary>
        /// 将上传excel写入数据库相应表中
        /// </summary>
        public void SqlBulkUpload()//问题还未解决:1.绝对物理路径path。
        {
            try
            {
                string filename = FileUpload1.FileName;//.PostedFile.FileName.Substring(FileUpload1.PostedFile.FileName.LastIndexOf("\\"));
                string sqlName = string.Empty;
                XmlNodeList xmlList = null;
                //在上传文件前先确定上传文件名称格式是否正确。如果有误,直接退出;如正确则获取对应sql表及字段名。
                getSQLName(out sqlName, out xmlList, filename);

                //上传文件到服务器指定文件夹。(用重名会覆盖,看后期是否再修改。)
                string serverPath = Server.MapPath("uploadFiles\\") + filename;
                FileUpload1.PostedFile.SaveAs(serverPath);

                //获取EXCEL中第1个页标签。
                string sheetname = string.Empty;
                ExcelSheetName(out sheetname, serverPath);

                //读取服务器中的此文件到datatable中。并在datatable中加入一列,用于生成id。
                string connstr = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source="
                    + serverPath
                    + ";Extended Properties=Excel 8.0";
                OleDbConnection conn = new OleDbConnection(connstr);
                string cmdText = "SELECT * FROM [" + sheetname + "]";
                OleDbCommand cmd = new OleDbCommand(cmdText, conn);
                conn.Open();
                OleDbDataAdapter adapter = new OleDbDataAdapter(cmd);
                DataTable dt = new DataTable();
                adapter.Fill(dt);
                //这个地方来判断表的结构

                conn.Close();

             

                // 获取服务器连接数据库
                string ConnectionString = System.Configuration.ConfigurationManager.ConnectionStrings["ORACLEConnectionStrings"].ConnectionString;
                string ProviderName = System.Configuration.ConfigurationManager.ConnectionStrings["ORACLEConnectionStrings"].ProviderName.ToString();
                //针对SQL数据库
                if (ProviderName.Contains("SqlClient"))
                {
                    for (int i = 0; i < dt.Rows.Count; i++)
                    {
                        dt.Rows[i]["id"] = Guid.NewGuid();
                    }
                    //以xml中的对应字段为格式模板,拷贝datatable中的数据到数据库。
                    using (SqlBulkCopy bulkCopy = new SqlBulkCopy(ConnectionString))
                    {
                        foreach (XmlNode nod in xmlList)
                        {
                            bulkCopy.ColumnMappings.Add(nod.Attributes["fileName"].Value.ToString(), nod.Attributes["SQLname"].Value.ToString());
                        }
                        bulkCopy.DestinationTableName = sqlName;

                        bulkCopy.WriteToServer(dt);
                    }
                }
                //针对Oracle数据库
                else if (ProviderName.Contains("OracleClient"))
                {
                    //这里因为客户端的版本10.2g无法支持OracleBulkCopy方法最终被放弃,必须11g及以上版本才能支持。
                    //可以用 bulk insert 的方法来处理。原理和.net提供的OracleBulkCopy方法原理相同,但因为是oracle自带函数,不需要版本支持。
                    //OracleBulkCopy bulkCopy = new OracleBulkCopy(ConnectionString);
                    //foreach (XmlNode nod in xmlList)
                    //{
                    //    bulkCopy.ColumnMappings.Add(nod.Attributes["fileName"].Value.ToString(), nod.Attributes["SQLname"].Value.ToString());
                    //}
                    //bulkCopy.DestinationTableName = sqlName;
                    //bulkCopy.WriteToServer(dt);
                    System.Data.OracleClient.OracleConnection oracleConn = new System.Data.OracleClient.OracleConnection(ConnectionString);
                   
                    Hashtable htable = new Hashtable();
                    oracleConn.Open();
                    string cmdTxt =  "insert into " + sqlName + " (";
                    foreach (XmlNode nod in xmlList)
                    {
                        cmdTxt += nod.Attributes["SQLname"].Value.ToString() + ",";
                    }
                    cmdTxt = cmdTxt.Remove(cmdTxt.LastIndexOf(",")) + ")";
                   
                    for (int i = 0; i < dt.Rows.Count; i++)
                    {
                        System.Data.OracleClient.OracleCommand oracleCmd = new System.Data.OracleClient.OracleCommand();
                        oracleCmd.Connection = oracleConn;
                        oracleCmd.CommandText = cmdTxt;

                        oracleCmd.CommandText += " values(";
                        for( int j=0;j<dt.Columns.Count;j++ )
                        {
                                if (xmlList[j].Attributes["OracleDbType"].Value == "VARCHAR2" )
                                {
                                    oracleCmd.CommandText += "'";
                                    oracleCmd.CommandText += dt.Rows[i][j].ToString() + "',";
                                }
                                else if (xmlList[j].Attributes["OracleDbType"].Value == "DATE")
                                {
                                    oracleCmd.CommandText += "to_date('" + dt.Rows[i][j].ToString() + "','yyyy-mm-dd hh24:mi:ss'),";
                                }
                                else
                                {
                                    oracleCmd.CommandText += dt.Rows[i][j].ToString() + ",";
                                }
                        }
                        oracleCmd.CommandText=oracleCmd.CommandText.Substring(0, oracleCmd.CommandText.Length - 1);
                        oracleCmd.CommandText += ")";
                        int mark = oracleCmd.ExecuteNonQuery();
                        oracleCmd.Dispose();
                        if (mark <= 0)//记录导入Oracle失败的行。
                        {
                            htable.Add((i+1).ToString(), dt.Rows[i][0]);
                        }
                    }
                    oracleConn.Close();

                    if (htable.Count > 0)
                    {
                        string errorRow = string.Empty;
                        foreach ( System.Collections.DictionaryEntry objEntry in htable)
                        {
                            errorRow += "第 " + objEntry.Key.ToString() +" 行数据故障,第一列数据为:" + objEntry.Value.ToString()+";";
                        }
                        errorRow += "请检查相应EXCEL文件进行修改。";
                        ScriptManager.RegisterClientScriptBlock(this, this.GetType(), "", "alert('"+errorRow+"');", true);
                    }
                }
                else
                {
                    ScriptManager.RegisterClientScriptBlock(this, this.GetType(), "", "alert('选择的数据库不是SQL或ORACLE数据库!~');", true);
                    return;
                }
                ScriptManager.RegisterClientScriptBlock(this, this.GetType(), "", "alert('文件上传成功!~');", true);
            }
            catch(Exception ex)
            {
                ScriptManager.RegisterClientScriptBlock(this, this.GetType(), "", "alert('"+ex.ToString()+"!');", true);//文件上传失败
                return;
            }

        }

  • 相关阅读:
    Visual Studio技巧之打造拥有自己标识的代码模板
    arcgis 10.1 错误(TCP_NODELAY NOT enabled)
    中秋节快乐
    调Windows 7的图片浏览器查看图片
    NetCFSvcUtil.exe and Windows 7
    win7下IIS错误:"无法访问请求的页面,因为该页的相关配置数据无效"的解决方法(转)
    卫星地图下载软件WebImageDowns
    出差陕西镇安
    打印完税证明
    c#定义全局条件编译符号
  • 原文地址:https://www.cnblogs.com/parse/p/2155391.html
Copyright © 2011-2022 走看看