上一篇写了将规则的Excel导入到数据库中,这篇写一下将不规则的Excel导入到数据库中。
首先看一下Excel的结构:
这个Excel的结构明显要复杂的多。读取复杂的Excel结构,往往还要考虑在数据库中的存储结构,接下来从设计对应Excel结构的数据库开始。
复杂结构的Excel就是存在的一对多的现象,类似于树状图,上图就可以抽象成树状图:
有了抽象成的树状图就可以对应设计数据库存储,以方便日后根据数据库的数据生成相同结构的Excel表格。
数据库中的树状关系是通过主外键连接来实现的,根据这个结构,我们需要创建四个表,分别存储parent,child,definite和click的数据,并建立主外键连接。
数据库表之间的关系如下图:(关系并不是严格按照树状图建立的,而是以树状图为基础,方便功能实现和日后数据查找建立的)
有了数据库表,和表关系,现在让我们来读数据和插数据吧!在有规则Excel的基础上读取不规则的Excel模板,读数据都是一样的,只是添加一些逻辑判断,判断将数据插到哪?
View Code
protected void Button1_Click(object sender, EventArgs e) 2 { 3 if (FileUpload1.HasFile == false)//HasFile用来检查FileUpload是否有指定文件 4 { 5 Response.Write("<script>alert('请您选择Excel文件')</script> "); 6 return;//当无文件时,返回 7 } 8 string IsXls = System.IO.Path.GetExtension(FileUpload1.FileName).ToString().ToLower();//System.IO.Path.GetExtension获得文件的扩展名 9 if (IsXls != ".xls") 10 { 11 if(IsXls != ".xlsx") 12 { 13 Response.Write("<script>alert('只可以选择Excel文件')</script>"); 14 return;//当选择的不是Excel文件时,返回 15 } 16 } 17 string filename = FileUpload1.FileName; //获取Execle文件名 DateTime日期函数 18 string savePath = Server.MapPath(("upload\\") + filename);//Server.MapPath 获得虚拟服务器相对路径 19 FileUpload1.SaveAs(savePath); //SaveAs 将上传的文件内容保存在服务器上 20 DataSet ds = ExcelSqlConnection(savePath, filename,IsXls); //调用自定义方法 21 DataRow[] dr = ds.Tables[0].Select(); //定义一个DataRow数组 22 int rowsnum = ds.Tables[0].Rows.Count; 23 if (rowsnum == 0) 24 { 25 Response.Write("<script>alert('Excel表为空表,无数据!')</script>"); //当Excel表为空时,对用户进行提示 26 } 27 else 28 { 29 for (int i = 0; i < dr.Length/3; i++)//循环根节点,根据模板判断,根节点数等于行数/3(dr.Length/3) 30 { 31 string DocumentParentClassified = dr[i*3]["Document Parent Classified"].ToString(); 32 cD.AddparentclassifiedDate(((i * 3)+1), DocumentParentClassified);//向根节点表中插入数据 33 for (int j = i * 3; j < (i+1)*3; j++)//循环枝干节点 34 { 35 string DocumentChildClassified = dr[j]["Document Child Classified"].ToString(); 36 cD.AddchildclassifiedDate(((i * 3) + 1), j+1, DocumentChildClassified);//向枝干节点表中插入数据 37 38 string S = dr[j]["S"].ToString(); 39 string M = dr[j]["M"].ToString(); 40 string L = dr[j]["L"].ToString(); 41 cD.AddclicktimesDate(j + 1, S, M, L); 42 for (int k = 2; k <= 4; k++)//循环叶子节点 43 { 44 string DocumentDefiniteClassified = dr[j][k].ToString(); 45 if (DocumentDefiniteClassified == "") 46 { 47 DocumentDefiniteClassified = "*"; 48 } 49 int state = 1; 50 int num = j*3 + k; 51 cD.AdddefiniteclassifiedDate(((i * 3) + 1), j+1,num, DocumentDefiniteClassified, state);//向叶子节点表中插入数据 52 } 53 } 54 } 55 Response.Write("<script>alert('Excle表导入成功!');</script>"); 56 } 57 } 58 59 #region 连接Excel 读取Excel数据 并返回DataSet数据集合 60 /// <summary> 61 /// 连接Excel 读取Excel数据 并返回DataSet数据集合 62 /// </summary> 63 /// <param name="filepath">Excel服务器路径</param> 64 /// <param name="tableName">Excel表名称</param> 65 /// <returns></returns> 66 public static System.Data.DataSet ExcelSqlConnection(string filepath, string tableName,string isxls) 67 { 68 string strCon = ""; 69 if (isxls == ".xls") 70 { 71 strCon = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + filepath + ";Extended Properties='Excel 8.0;HDR=YES;IMEX=1'"; 72 } 73 else 74 { 75 strCon = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + filepath + ";Extended Properties='Excel 12.0;HDR=YES;IMEX=1'"; 76 } 77 OleDbConnection ExcelConn = new OleDbConnection(strCon); 78 try 79 { 80 string strCom = string.Format("SELECT * FROM [Test$]"); 81 ExcelConn.Open(); 82 OleDbDataAdapter myCommand = new OleDbDataAdapter(strCom, ExcelConn); 83 DataSet ds = new DataSet(); 84 myCommand.Fill(ds, "[" + tableName + "$]"); 85 ExcelConn.Close(); 86 return ds; 87 } 88 catch 89 { 90 ExcelConn.Close(); 91 return null; 92 } 93 } 94 #endregion