C# 將excel文件導入到SqlServer數據庫


此文轉載自:https://blog.csdn.net/qq_40422692/article/details/110121524#commentBox

項目結構(很標准的三層架構):
在這里插入圖片描述

一、做一些准備

  1. 這里上傳文件用到的控件是webuploader,下載地址:http://fex.baidu.com/webuploader/
    webuploader的使用方法:https://www.jianshu.com/p/005341448bd0
  2. 如果需要使用到easyUI,下載地址:https://www.jeasyui.cn/ ,使用方法也在這里
  3. 導入ExcelDataReader和ExcelDataReader.DatasSet在這里插入圖片描述
    在這里插入圖片描述
  4. 導入模板,記得與數據庫的內容對應
    (1)我的excel模板,注意:保留一張sheet
    在這里插入圖片描述
    (2)數據庫(其實這里是不允許為空的,因為沒有對excel表中為空的數據進行處理,因為注重的不是這個,所以沒有做處理。自己添加約束即可。)
    在這里插入圖片描述

二、正式開始

注:為了貼圖方便,順序可能和實際編寫代碼的順序不一致

  1. 下面是前端頁面的代碼。標明了導入必須的代碼以及非必須的代碼,可以根據需要查看。
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title></title>
    <link href="jquery-easyui-1.8.6/themes/default/easyui.css" rel="stylesheet" />
    <link href="jquery-easyui-1.8.6/themes/icon.css" rel="stylesheet" />
    <script src="jquery-easyui-1.8.6/jquery.min.js"></script> <script src="jquery-easyui-1.8.6/jquery.easyui.min.js"></script> <link href="webuploader-0.1.5/webuploader.css" rel="stylesheet" /> <script src="webuploader-0.1.5/webuploader.js"></script> <style> /*修改webuploader的樣式*/ #picker { display: inline-block; line-height: 1.428571429; vertical-align: middle; margin: 0 1px 0 0; width: 90px; } #picker .webuploader-pick { padding: 0; display: block; } </style> </head> <body> <a id="picker" href="#" plain="true" class="easyui-linkbutton l-btn l-btn-plain">導入學員</a> <table id="dg"></table><!--只要導入非必須--> </body> </html> <script> $(function () { ImportExcelData(); //下面內容只要導入非必須。只調用上面的函數就可。 $("#dg").datagrid({ nowrap: false, autoRowHeight: true, striped: true, collapsible: false, fit: true, fitColumns: false, singleSelect: true, remoteSort: false, columns: [[ { field: 'name', title: '姓名', width: 100 }, { field: 'gender', title: '姓別', width: 100, formatter: function (value, row, index) { if (value == 0) { return value = "男"; } else { return value = "女"; } } }, { field: 'idcardnum', title: '身份證號', width: 300 }, { field: 'address', title: '地址', width: 300 }, { field: 'phone', title: '電話號碼', width: 300 }, ]], pagination: false, rownumbers: false, }); BindData(); }) //該方法只要導入非必要,是用來綁定數據到datagrid的 function BindData() { $.post("InAndOut.ashx", { type: 'GetDataList' }, function (data) { $("#dg").datagrid("loadData", data.list); }, 'json'); } //導入 function ImportExcelData() { //初始化webuploader控件 var uploader = WebUploader.create({ auto: true,// 選完文件后,是否自動上傳。 swf: "webuploader-0.1.5/Uploader.swf",// swf文件路徑 server: 'InAndOut.ashx?type=UploadImportExcel',// 文件接收服務端。 //dnd: '.upload-container', pick: '#picker',// 內部根據當前運行是創建,可能是input元素,也可能是flash. 這里是div的id multiple: false, // 選擇多個 chunked: true,// 開起分片上傳。 method: 'POST', // 文件上傳方式,POST或者GET。 fileSizeLimit: 1024 * 1024 * 100 * 10, //驗證文件總大小是否超出限制, 超出則不允許加入隊列。 fileSingleSizeLimit: 1024 * 1024 * 100, //驗證單個文件大小是否超出限制, 超出則不允許加入隊列。 //fileVal: 'epub', // [默認值:'file'] 設置文件上傳域的name。 }); //上傳成功后的操作 uploader.on('uploadSuccess', function (file, json) { if (json.code == 1) { BindData(); } else { alert(json.msg); return false; } }); } </script> 

再次提醒!!這里和實際編寫代碼順序不一樣,這里相當於程序實際運行起來的調用順序,所以會有一些小問題,繼續看下去就好啦

在這里插入圖片描述

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Model
{
    //和數據庫的字段一一對應
    public class InAndOutModel
    {
        public int id { get; set; }
        public string name { get; set; }
        public int gender { get; set; }
        public string idcardnum { get; set; }
        public string address { get; set; }
        public string phone { get; set; }
    }
}
  1. 在這里插入圖片描述
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Web;
using Model;
using BLL;
using System.IO;
using System.Data;
using ExcelDataReader;

namespace 導入導出
{
    /// <summary>
    /// InAndOut 的摘要說明
    /// </summary>
    public class InAndOut : IHttpHandler
    {

        public void ProcessRequest(HttpContext context)
        {
            context.Response.ContentType = "text/plain";
            //這里是用委托調用對應方法
            var type = context.Request["type"];
            if(!string.IsNullOrEmpty(type))
            {
                MethodInfo method = this.GetType().GetMethod(type);
                if(method != null)
                {
                    method.Invoke(this, null);
                }
            }
        }

        /// <summary>
        /// 獲取列表,非必須
        /// </summary>
        public void GetDataList()
        {
            InAndOutBll bll = new InAndOutBll();
            List<InAndOutModel> list = new List<InAndOutModel>();
            list = bll.GetList("");
            if(list != null && list.Count > 0)
            {
                var item = new
                {
                    code = 1,
                    list = list
                };
                //這里還需要引入一個人Newtonsoft包
                HttpContext.Current.Response.Write(Newtonsoft.Json.JsonConvert.SerializeObject(item));
            }
            else
            {
                var item = new
                {
                    code = 0,
                    msg = "當前沒有數據可以綁定"
                };
                HttpContext.Current.Response.Write(Newtonsoft.Json.JsonConvert.SerializeObject(item));
            }
        }

        /// <summary>
        /// 重要步驟
        /// </summary>
        public void UploadImportExcel()
        {
            //1.獲取上傳的文件
            HttpFileCollection files = HttpContext.Current.Request.Files;
            //2.獲取要保存文件的路徑
            string path = HttpContext.Current.Server.MapPath("~/upload/");
            //3.判斷該路徑文件夾是否存在
            if (!Directory.Exists(path))
            {
                //3.1不存在就創建
                Directory.CreateDirectory(path);
            }
            //4.獲取當前時間戳,用來命名保證名字文件夾
            string time = DateTime.Now.Ticks.ToString();
            //5.獲取上傳文件的文件名(主要是為了獲取后綴名),如果介意新的命名太長可以只獲取后綴名
            string filename = files[0].FileName;
            //6.得到完整的命名
            string name = path + time + filename;
            //7.保存
            files[0].SaveAs(name);
            //8.將excel取出轉化為datatable
            var tables = GetExcelSheets(name);
            var datatable = GetExcelSheet(name, tables[0]);
            //9.判斷datatable中是否有數據
            if(datatable.Rows.Count < 2)
            {
                var item = new
                {
                    code = 0,
                    msg = "表中沒有數據,請檢查"
                };
                HttpContext.Current.Response.Write(Newtonsoft.Json.JsonConvert.SerializeObject(item));
            }
            //9.2 有數據進行的操作
            else
            {
                InAndOutBll bll = new InAndOutBll();
                //因為涉及到多條數據的插入,所以需要用到事務。
                bool res = bll.Trans_Insert(datatable);
                if(res)
                {
                    var item = new
                    {
                        code = 1,
                        msg = "插入成功"
                    };
                    HttpContext.Current.Response.Write(Newtonsoft.Json.JsonConvert.SerializeObject(item));
                }
                else
                {
                    var item = new
                    {
                        code = 0,
                        msg = "插入失敗"
                    };
                    HttpContext.Current.Response.Write(Newtonsoft.Json.JsonConvert.SerializeObject(item));
                }
            }
        }

        #region 獲取工作簿
        /// <summary>
        /// 獲取所有的sheet名稱
        /// </summary>
        /// <param name="path"></param>
        /// <returns></returns>
        public static List<string> GetExcelSheets(string path)
        {
            List<string> TableNames = new List<string>();
            DataSet ds = GetDataForExcel(path);
            for (int i = ds.Tables.Count - 1; i >= 0; i--)
            {
                TableNames.Add(ds.Tables[i].TableName);
            }
            return TableNames;
        }
        /// <summary>
        /// sheetName 獲取單個sheet數據 
        /// </summary>
        /// <param name="path"></param>
        /// <param name="sheetname"></param>
        /// <returns></returns>
        public static System.Data.DataTable GetExcelSheet(string path, string sheetname)
        {
            System.Data.DataTable dt = new System.Data.DataTable();
            DataSet ds = GetDataForExcel(path);
            for (int i = 0; i < ds.Tables.Count; i++)
            {
                if (ds.Tables[i].TableName == sheetname)
                {
                    dt = ds.Tables[i];
                    break;
                }
            }
            return dt;
        }

        /// <summary>
        /// 獲取整個excel 數據
        /// </summary>
        /// <param name="filePath"></param>
        /// <returns></returns>
        public static DataSet GetDataForExcel(string filePath)
        {
            using (var stream = File.Open(filePath, FileMode.Open, FileAccess.Read))
            {
                using (var reader = ExcelReaderFactory.CreateReader(stream))
                {
                    DataSet result = reader.AsDataSet();
                    return result;
                }
            }
        }
        #endregion

        public bool IsReusable
        {
            get
            {
                return false;
            }
        }
    }
}

在這里插入圖片描述

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Model;
using DAL;
using System.Data;
using DBUtility;

namespace BLL
{
    public class InAndOutBll
    {
        private readonly InAndOutDal dal = new InAndOutDal();
        /// <summary>
        /// 獲取列表
        /// </summary>
        /// <param name="condition">查詢條件</param>
        /// <returns></returns>
        public List<InAndOutModel> GetList(string condition)
        {
            return dal.GetList(condition);
        }
        /// <summary>
        /// 多條數據插入
        /// </summary>
        /// <param name="dt">需要插入的datatable</param>
        /// <returns></returns>
        public bool Trans_Insert(DataTable dt)
        {
            bool istrue = true;
            //這里的SQLServerHelper是數據庫幫助類,網上有很多可以用
            SQLServerHelper.Transaction transaction = new SQLServerHelper.Transaction();
            //遍歷這個表的每一行
            foreach(DataRow dr in dt.Rows)
            {
                if(dr["Column0"].ToString() == "姓名")
                {
                    continue;
                }
                if(istrue)
                {
                    istrue = dal.Trans_Insert(transaction, dr) > 0;
                }
                else
                {
                    istrue = false;
                    break;
                }
            }
            //所有行都成功插入,提交事務
            if(istrue)
            {
                transaction.Commit();
            }
            //否則回滾
            else
            {
                transaction.RollBack();
            }
            return istrue;
        }
    }
}

調試的時候可以看到datatable的結構:
在這里插入圖片描述

在這里插入圖片描述

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Model;
using DBUtility;
using System.Data;
using System.Data.SqlClient;

namespace DAL
{
    public class InAndOutDal
    {
        /// <summary>
        /// 獲取列表,導入非必須
        /// </summary>
        /// <param name="condition">查詢條件</param>
        /// <returns></returns>
        public List<InAndOutModel> GetList(string condition)
        {
            List<InAndOutModel> list = new List<InAndOutModel>();
            string sql = "select * from InAndOut where 1 = 1 " + condition;
            DataSet ds = SQLServerHelper.Query(sql);
            if(ds != null && ds.Tables.Count > 0)
            {
                DataTable dt = ds.Tables[0];
                if(dt.Rows.Count > 0)
                {
                    foreach (DataRow dr in dt.Rows)
                    {
                        list.Add(this.GetModel(dr));
                    }
                }
            }
            return list;
        }
        /// <summary>
        /// 多條數據插入
        /// </summary>
        /// <param name="transaction">事務</param>
        /// <param name="dr">要插入的行</param>
        /// <returns></returns>
        public int Trans_Insert(SQLServerHelper.Transaction transaction, DataRow dr)
        {
            InAndOutModel model = new InAndOutModel();
            model = this.ExcelDrGetModel(dr);
            string sql = "insert into InAndOut(name, gender, idcardnum, address, phone) values (@name, @gender, @idcardnum, @address, @phone);select @@IDENTITY";
            SqlParameter[] parameters = {
                new SqlParameter("@name", SqlDbType.NVarChar,10),
                new SqlParameter("@gender", SqlDbType.Int, 4),
                new SqlParameter("@idcardnum", SqlDbType.NVarChar, 18),
                new SqlParameter("@address", SqlDbType.NVarChar, 20),
                new SqlParameter("@phone", SqlDbType.NVarChar, 12),
            };
            parameters[0].Value = model.name;
            parameters[1].Value = model.gender;
            parameters[2].Value = model.idcardnum;
            parameters[3].Value = model.address;
            parameters[4].Value = model.phone;
            object obj = SQLServerHelper.GetTrObject(transaction, sql, parameters);
            if(obj == null)
            {
                return 0;
            }
            else
            {
                return Convert.ToInt32(obj);
            }
        }

        public InAndOutModel GetModel(DataRow dr)
        {
            InAndOutModel model = new InAndOutModel();
            if (dr != null)
            {
                if(dr["name"] != null)
                {
                    model.name = dr["name"].ToString();
                }
                if(dr["gender"] != null)
                {
                    model.gender = Convert.ToInt32(dr["gender"]);
                }
                if(dr["idcardnum"] != null)
                {
                    model.idcardnum = dr["idcardnum"].ToString();
                }
                if(dr["address"] != null)
                {
                    model.address = dr["address"].ToString();
                }
                if(dr["phone"] != null)
                {
                    model.phone = dr["phone"].ToString();
                }
            }
            return model;
        }

        public InAndOutModel ExcelDrGetModel(DataRow dr)
        {
            InAndOutModel model = new InAndOutModel();
            if (dr != null)
            {
//這里用dr[0]是根據dr結構的,調試可以看到的哦
                if (dr[0] != null)
                {
                    model.name = dr[0].ToString();
                }
                if (dr[1] != null)
                {
                    if(dr[1].ToString() == "男")
                    {
                        dr[1] = 0;
                    }
                    else
                    {
                        dr[1] = 1;
                    }
                    model.gender = Convert.ToInt32(dr[1]);
                }
                if (dr[2] != null)
                {
                    model.idcardnum = dr[2].ToString();
                }
                if (dr[3] != null)
                {
                    model.address = dr[3].ToString();
                }
                if (dr[4] != null)
                {
                    model.phone = dr[4].ToString();
                }
            }
            return model;
        }
    }
}

如果你使用了easyUI進行數據綁定,那么運行會有這樣的效果

  • 網頁
    在這里插入圖片描述

  • 數據庫
    在這里插入圖片描述

因為這里主要將excel文件導入數據庫,所以很多細節沒有處理,比如判空、判重等等等,需要自己添加限制條件哦。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM