1. 程式人生 > >ASP.NET控制元件FileUpload實現Excel檔案內容上傳到資料庫

ASP.NET控制元件FileUpload實現Excel檔案內容上傳到資料庫

實現思路:Excel的內容並不可以直接上傳到資料庫,所以先將Excel內容讀取出來轉化為DataSet,然後可以得到DataTable,遍歷每一行,存到資料庫裡就好了。

前臺只放了兩個控制元件:

<asp:Button ID="btnUpload" class="btnStyle" runat="server" Text="上傳" OnClick="btnUpload_Click" />
<asp:FileUpload ID="FileUpload1" runat="server" />

後臺如下:

namespace *********不顯示了無關緊要************
{
    public partial class UploadExcelFile : System.Web.UI.Page
    {
        UploadExcelFileBiz uploadExcelFileBiz = new UploadExcelFileBiz(); 
        protected void Page_Load(object sender, EventArgs e)
        {

        }
        /// <summary>
        /// 上傳至資料庫
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void btnUpload_Click(object sender, EventArgs e)
        {

            //bool style = false;
            string road = "";
            #region 檔案上傳
            try
            {
		//全名
                string excelFile = this.FileUpload1.PostedFile.FileName;
		//獲取檔名(不包括副檔名)
 		string fileName = Path.GetFileNameWithoutExtension(FileUpload1.PostedFile.FileName);
		//副檔名
                string extentionName = excelFile.Substring(excelFile.LastIndexOf(".") + 1);
                if (fileName == "" || fileName == null)
                {
                    Response.Write("<script>alert('請先選擇Excel檔案!')</script>");
                    return;
                }
                if (extentionName != "xls" && extentionName != "xlsx")
                {
                    Response.Write("<script>alert('您上傳的不是Excel檔案!')</script>");
                    return;
                }
		//瀏覽器安全性限制 無法直接獲取客戶端檔案的真實路徑,將檔案上傳到伺服器端 然後獲取檔案源路徑

                #region 設定上傳路徑將檔案儲存到伺服器
                string dateTime = DateTime.Now.Date.ToString("yyyyMMdd");
                string time = DateTime.Now.ToShortTimeString().Replace(":", "");
                string newFileName = dateTime + time + DateTime.Now.Millisecond.ToString() + ".xls"; ;
		//Annex是自己建立的資料夾  位置隨意   合理即可
                road = Server.MapPath("..\\..\\Annex") + "\\" + newFileName;
                this.FileUpload1.PostedFile.SaveAs(road);
                //Response.Write("<script>alert('已經上傳到伺服器資料夾')</script>");
                #endregion

            }
            catch
            {
                Response.Write("<script>alert('資料上傳失敗,請重新匯入')</script>");
                return;
            }
            #endregion
            #region 資料匯入
            try
            {
                #region 讀取成DataSet  然後轉化為Table
                string strConn = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source='" + road + "';" + 
			"Extended Properties='Excel 8.0;IMEX=1'";
                DataSet dsMin = new DataSet();
                OleDbDataAdapter oada = new OleDbDataAdapter("select * from [模板(5分鐘)$]", strConn);
                oada.Fill(dsMin);
                DataSet dsHour = new DataSet();
                OleDbDataAdapter oada2 = new OleDbDataAdapter("select * from [模板(小時)$]", strConn);
                oada2.Fill(dsHour);
                DataTable dtMin = dsMin.Tables[0];
                DataRow[] dr = dtMin.Select();
                int rowsNum = dtMin.Rows.Count;
                string a, b, c, d, f, g, h;
                //遍歷獲取的Excel內容  dr[行][列] 下標索引從0開始
                for (int i = 2; i < rowsNum; i++)
                {
                    //序號
                    a = dr[i][0].ToString();
                    //時間
                    b = dr[i][1].ToString();
		    //本人上傳的Excel第三列有空格,所以輪空
                    c = dr[i][3].ToString();
                    d = dr[i][4].ToString();
                    f = dr[i][5].ToString();
                    g = dr[i][6].ToString();
                    h = dr[i][7].ToString();
                    //插入資料庫  Add是自定義的方法
                    uploadExcelFileBiz.Add(Convert.ToDateTime(b), c, d, f, g, h);
                }
		
	      	#region   SqlBulkCopy批量寫入資料庫
 		DataTable dtHour = dsHour.Tables[0];
		dtHour .Columns[0].ColumnName = "UploadTime";
		dtHour.Columns[1].ColumnName = "Data1";
		dtHour.Columns[2].ColumnName = "Data2";
		dtHour.Columns[3].ColumnName = "Data3";
		dtHour.Columns[4].ColumnName = "Data4";
		dtHour.Columns[5].ColumnName = "Data5";
		uploadExcelFileBiz.WriteIntoDataBase(dtHour);
		#endregion
                #endregion
            }
            catch
            {
                Response.Write("<script>alert('匯入資料失敗!')</script>");
                return;
            }
            #endregion
        }

    }
}
附上SqlBulkCopy批量寫入資料庫的方法如下:
DAL層:
/// <summary>
/// 利用SqlBulkCopy批量寫入資料庫
/// </summary>
/// <param name="dt"></param>
public void WriteIntoDataBase(DataTable dt)
{
	SqlConnection myConn = new SqlConnection(System.Configuration.ConfigurationManager.ConnectionStrings["dbBaseDatabase"].ConnectionString);
	myConn.Open();
	SqlBulkCopy bulkCopy = new SqlBulkCopy(myConn);
	bulkCopy.BatchSize = 10000;
	bulkCopy.BulkCopyTimeout = 60;
	bulkCopy.DestinationTableName = "T_Sys_UploadTest";
	for (int i = 0; i < dt.Columns.Count; i++)
	{
		string columnName = dt.Columns[i].ColumnName;
		bulkCopy.ColumnMappings.Add(columnName, columnName);
	}
	bulkCopy.WriteToServer(dt);
	//myConn.Close();
	myConn.Dispose();
}

注意事項:
dataTable的表頭得和所要插入的資料庫表中的欄位名稱一一對應,注意重新命名:如:dataTable.Columns[0].ColumnName = "內容";
備註:
SqlBulkCopy這種批量寫入方式,可以大大的節約資料庫匯入資料的時間,因為字串的拼接的方式寫入資料庫需要不停的開啟和關閉連線。
上述內容則提供了這兩種方法,方便對比

-----------------------分割線----2017.06.26更新-------附上UploadExcelFileBiz.cs--------------------

using ApplyForNetwork.DAL.ApplyForNetwork.Sys;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;

namespace ApplyForNetwork.BLL.ApplyForNetwork.Sys
{
    public class UploadExcelFileBiz
    {
        UploadExcelFileDA uploadExcelFileDA = new UploadExcelFileDA();
        public UploadExcelFileBiz()
        {
        }

        /// <summary>
        /// 利用SqlBulkCopy批量寫入資料庫
        /// </summary>
        /// <param name="dt"></param>
        public void WriteIntoDataBase(DataTable dt,string tableName)
        {
            uploadExcelFileDA.WriteIntoDataBase(dt, tableName);
        }
        /// <summary>
        /// 建立臨時表
        /// </summary>
        /// <returns></returns>
        public DataTable tmpTable()
        {
            DataTable dt = new DataTable();
            dt.Columns.Add("ID", typeof(int));
            dt.Columns.Add("PortId",typeof(string));
            dt.Columns.Add("Tstamp", typeof(DateTime));
            dt.Columns.Add("ZAD_DATA1", typeof(Decimal));
            dt.Columns.Add("MinusData1", typeof(Decimal));
            dt.Columns.Add("ZAD_DATA3", typeof(Decimal));
            dt.Columns.Add("MinusData3", typeof(Decimal));
            dt.Columns.Add("ZAD_DATA4", typeof(Decimal));
            dt.Columns.Add("MinusData4", typeof(Decimal));
            dt.Columns.Add("ZAD_DATA6", typeof(Decimal));
            dt.Columns.Add("MinusData6", typeof(Decimal));
            dt.Columns.Add("ZAD_DATA9", typeof(Decimal));
            dt.Columns.Add("MinusData9", typeof(Decimal));
            dt.Columns.Add("CheckBatch", typeof(string));      
            return dt;
        }

    }
}