將不規則Excel文件數據寫入數據庫

將不規則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還是得多寫的。以上純屬個人見解。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章