将不规则Excel文件数据写入数据库

此次是要将以下Excel文件里面的数据写入火车订票系统数据库表里面。那我们先来看看是什么样子的Excel数据。

1

这个文件里面共有2个工作表,里面的数据按上图样式排列。接下来看我们要导入的数据库表。

2

上图有3张表,其中TrainType为火车类型表,存储的是火车的类型,比如普通车,动车组等。

TrainTrip存储的是火车的车次,ReachStation存储的是火车的到达站点,由于起始站都是福州,

所以表暂且这么设计了。

按照上图Excel的格式,如果按常规的数据源来读取数据肯定是行不通的,应该采用更灵活的方式来,

所以可以利用程序的循环来读取每一单元格的信息。通过网上的不断寻找终于让我找到一个开源的读取

Excel格式文件的代码NExcel。想了解更多的可以直接去访问官方网站http://nexcel.sourceforge.net/

 

那么再开始我们的程序代码之前先看看我们的程序界面吧。

3

该界面实现的是先上传文件,然后把文件里面的数据导入到数据库里面,文件的路径暂且保存到Session里面。

接下来就是代码啦:

if (this.IsValid && txtCheckCode.Text.ToLower() == Convert.ToString(Session["checkCode"]).ToLower())
{
    try
    {
        using (SqlConnection conn = new SqlConnection(SqlHelper.ConnectionString))
        {
            conn.Open();

            SqlDataAdapter sdaTrainType = new SqlDataAdapter("Select * From TrainType", conn);
            SqlDataAdapter sdaTrainTrip = new SqlDataAdapter("Select * From TrainTrip", conn);
            SqlDataAdapter sdaReachStation = new SqlDataAdapter("Select * From ReachStation", conn);
            SqlCommandBuilder builderTrainType = new SqlCommandBuilder(sdaTrainType);
            SqlCommandBuilder builderTrainTrip = new SqlCommandBuilder(sdaTrainTrip);
            SqlCommandBuilder builderReachStation = new SqlCommandBuilder(sdaReachStation);
            SqlCommand cmdTrainType = builderTrainType.GetInsertCommand();
            SqlCommand cmdTrainTrip = builderTrainTrip.GetInsertCommand();
            SqlCommand cmdReachStation = builderReachStation.GetInsertCommand();

            DataSet ds = new DataSet();

            sdaTrainType.Fill(ds, "TrainType");
            sdaTrainTrip.Fill(ds, "TrainTrip");
            sdaReachStation.Fill(ds, "ReachStation");

            DataTable trainType = ds.Tables["TrainType"];
            DataTable trainTrip = ds.Tables["TrainTrip"];
            DataTable reachStation = ds.Tables["ReachStation"];

            // Excel数据操作
            string filepath = Server.MapPath(Session["FileName"].ToString());
            Workbook workbook = Workbook.getWorkbook(filepath);
            int trainTypeId = 1;
            int trainTripId = 1;
            int reachStationId = 1;

            foreach (Sheet sheet in workbook.Sheets)
            {
                //添加数据到TrainType
                DataRow trainTypeRow = trainType.NewRow();
                trainTypeRow["ID"] = trainTypeId++;
                trainTypeRow["Name"] = sheet.Name;
                trainType.Rows.Add(trainTypeRow);
                for (int irow = 1; irow < sheet.Rows; irow = irow + 3)
                {
                    // 添加数据到TrainTrip
                    if (sheet.getCell(0, irow).Contents != "")
                    {
                        DataRow trainTripRow = trainTrip.NewRow();
                        trainTripRow["ID"] = trainTripId++;
                        trainTripRow["TripName"] = sheet.getCell(0, irow).Contents;
                        trainTripRow["StartTime"] = sheet.getCell(1, irow).Contents;
                        trainTripRow["TypeID"] = trainTypeId - 1;
                        trainTripRow["TicketCount"] = 0;
                        trainTrip.Rows.Add(trainTripRow);
                    }
                    // 添加数据到ReachStation
                    for (int icol = 2; icol < sheet.Columns; icol++)
                    {
                        if (sheet.getCell(icol, irow).Contents == "")
                        {
                            break;   // 到达站为空则退出循环
                        }
                        DataRow reachStationRow = reachStation.NewRow();
                        reachStationRow["ID"] = reachStationId++;
                        reachStationRow["Name"] = sheet.getCell(icol, irow).Contents;
                        reachStationRow["ReachTime"] = sheet.getCell(icol, irow + 1).Contents;
                        reachStationRow["HardSeatPrice"] = sheet.getCell(icol, irow + 2).Contents;
                        reachStationRow["AdvancePrice"] = Common.GetAdvancePrice(Convert.ToDecimal(sheet.getCell(icol, irow + 2).Contents));
                        reachStationRow["TripID"] = trainTripId - 1;
                        reachStationRow["TicketCount"] = 0;
                        reachStation.Rows.Add(reachStationRow);
                    }
                }
            }
            sdaTrainType.Update(ds, "TrainType");
            sdaTrainTrip.Update(ds, "TrainTrip");
            sdaReachStation.Update(ds, "ReachStation");   
            workbook.close();
            lblMsg.Text = "导入数据成功!";
        }
    }
    catch
    {
        lblMsg.Text = "导入数据失败!";
    }
}
else
{
    lblMsg.Text = "验证码错误!";
}
 
此次整个系统的制作需求一直再改,我是弄得筋疲力尽了。不过现在把一些感想记在此处。
首先数据库的设计,如果涉及到数据库导入的话,应该考虑到表ID是否要弄成非自增量,否则将给后面的开发造成一定的困难。

还有时间字段问题,如果时间为12:00并未有日期的话,涉及到数据库导出到Excel应该设置为字符串类型,而不是datetime类型。

整个系统数据库设计到多个表数据删除问题,应该考虑是否添加外键约束,如果有外键约束可能最终造成多个表因为互相关联导致数据删除

无法顺利进行。

接着是程序的设计,记着不要一直追求代码的最简洁化,该多写几句还是得写,不要怕重复,就像上面那段我把datatable更新到数据库的

代码,我一直想只用一个SqlDataAdapter就做完所有的数据操作,我想该多写几个SqlDataAdapter还是得多写的。以上纯属个人见解。

 

欢迎转载,请注明出处

posted @ 2009-12-09 14:07  Timothy  阅读(1978)  评论(1编辑  收藏  举报