C#中如何将Excel中的数据批量导入到sql server?

C#中如何将Excel中的数据批量导入到sql server?,第1张

1.本文实现在c#中可高效的将excel数据导入到sqlserver数据库中,很多人通过循环来拼接sql,这样做不但容易出错而且效率低下,最好的办法是使用bcp,也就是System.Data.SqlClient.SqlBulkCopy 类来实现。不但速度快,而且代码简单,下面测试代码导入一个6万多条数据的sheet,包括读取(全部读取比较慢)在我的开发环境中只需要10秒左右,而真正的导入过程只需要4.5秒。\x0d\x0a2.代码如下:\x0d\x0ausing System \x0d\x0ausing System.Data \x0d\x0ausing System.Windows.Forms \x0d\x0ausing System.Data.OleDb \x0d\x0anamespace WindowsApplication2 \x0d\x0a{ \x0d\x0apublic partial class Form1 : Form \x0d\x0a{ \x0d\x0apublic Form1() \x0d\x0a{ \x0d\x0aInitializeComponent() \x0d\x0a} \x0d\x0a\x0d\x0aprivate void button1_Click(object sender, EventArgs e) \x0d\x0a{ \x0d\x0a//测试,将excel中的sheet1导入到sqlserver中 \x0d\x0astring connString = "server=localhostuid=sapwd=sqlgisdatabase=master" \x0d\x0aSystem.Windows.Forms.OpenFileDialog fd = new OpenFileDialog() \x0d\x0aif (fd.ShowDialog() == DialogResult.OK) \x0d\x0a{ \x0d\x0aTransferData(fd.FileName, "sheet1", connString) \x0d\x0a} \x0d\x0a} \x0d\x0a\x0d\x0apublic void TransferData(string excelFile, string sheetName, string connectionString) \x0d\x0a{ \x0d\x0aDataSet ds = new DataSet() \x0d\x0atry\x0d\x0a{ \x0d\x0a//获取全部数据 \x0d\x0astring strConn = "Provider=Microsoft.Jet.OLEDB.4.0" + "Data Source=" + excelFile + "" + "Extended Properties=Excel 8.0" \x0d\x0aOleDbConnection conn = new OleDbConnection(strConn) \x0d\x0aconn.Open() \x0d\x0astring strExcel = "" \x0d\x0aOleDbDataAdapter myCommand = null \x0d\x0astrExcel = string.Format("select * from [{0}$]", sheetName) \x0d\x0amyCommand = new OleDbDataAdapter(strExcel, strConn) \x0d\x0amyCommand.Fill(ds, sheetName) \x0d\x0a\x0d\x0a//如果目标表不存在则创建 \x0d\x0astring strSql = string.Format("if object_id('{0}') is null create table {0}(", sheetName) \x0d\x0aforeach (System.Data.DataColumn c in ds.Tables[0].Columns) \x0d\x0a{ \x0d\x0astrSql += string.Format("[{0}] varchar(255),", c.ColumnName) \x0d\x0a} \x0d\x0astrSql = strSql.Trim(',') + ")" \x0d\x0a\x0d\x0ausing (System.Data.SqlClient.SqlConnection sqlconn = new System.Data.SqlClient.SqlConnection(connectionString)) \x0d\x0a{ \x0d\x0asqlconn.Open() \x0d\x0aSystem.Data.SqlClient.SqlCommand command = sqlconn.CreateCommand() \x0d\x0acommand.CommandText = strSql \x0d\x0acommand.ExecuteNonQuery() \x0d\x0asqlconn.Close() \x0d\x0a} \x0d\x0a//用bcp导入数据 \x0d\x0ausing (System.Data.SqlClient.SqlBulkCopy bcp = new System.Data.SqlClient.SqlBulkCopy(connectionString)) \x0d\x0a{ \x0d\x0abcp.SqlRowsCopied += new System.Data.SqlClient.SqlRowsCopiedEventHandler(bcp_SqlRowsCopied) \x0d\x0abcp.BatchSize = 100//每次传输的行数 \x0d\x0abcp.NotifyAfter = 100//进度提示的行数 \x0d\x0abcp.DestinationTableName = sheetName//目标表 \x0d\x0abcp.WriteToServer(ds.Tables[0]) \x0d\x0a} \x0d\x0a} \x0d\x0acatch (Exception ex) \x0d\x0a{ \x0d\x0aSystem.Windows.Forms.MessageBox.Show(ex.Message) \x0d\x0a}\x0d\x0a} \x0d\x0a\x0d\x0a//进度显示 \x0d\x0avoid bcp_SqlRowsCopied(object sender, System.Data.SqlClient.SqlRowsCopiedEventArgs e) \x0d\x0a{ \x0d\x0athis.Text = e.RowsCopied.ToString() \x0d\x0athis.Update() \x0d\x0a}\x0d\x0a} \x0d\x0a} \x0d\x0a3.上面的TransferData基本可以直接使用,如果要考虑周全的话,可以用oledb来获取excel的表结构,并且加入ColumnMappings来设置对照字段,这样效果就完全可以做到和sqlserver的dts相同的效果了。

可用第三方来导数据,参考spire.xls for .net的数据导入方法:

//创建Workbook对象并加载Excel文档

Workbook workbook = new Workbook()

workbook.LoadFromFile(@"F:\ExportData.xlsx" , ExcelVersion.Version2013)

//获取第一张sheet

Worksheet sheet = workbook.Worksheets[0]

//设置range范围

CellRange range = sheet.Range[sheet.FirstRow, sheet.FirstColumn, sheet.LastRow, sheet.LastColumn]

//输出数据, 同时输出列名以及公式值

DataTable dt = sheet.ExportDataTable(range, true, true)

代码参考自原文。

思路很简单,就是先依次获取Excel中表的表名,然后再将Excel表的数据导入到内存以DataTable格式存在,最后再把dataTable数据导入到Mdb数据库文件中。最后实现的功能可以使Excel多表进行导入,如果Mdb数据库文件中已有新建的表, *** 作是先删除数据库中的已存在表,再重新创建表,导数据。

源码:

using Systemusing System.Collections.Genericusing System.ComponentModelusing System.Datausing System.Drawingusing System.Linqusing System.Textusing System.Threading.Tasksusing System.Windows.Formsusing System.Data.OleDb

namespace TestK

{

public partial class Form1 : Form    {

public Form1()

{

InitializeComponent()

}

public int tableNameNum = 0   //记录Excel中所有表的数量        public OleDbConnection connection = new OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0Data Source=C:\\Users\\CES\\Desktop\\CES.mdb")

//建立与数据库文件CES.mdb的连接

//打开以.xls或者.xlsx结尾的文件        private void button1_Click(object sender, EventArgs e)

{

OpenFileDialog dlg = new OpenFileDialog()   //创建窗体            dlg.Filter = "Excel文件 (*.xls*.xlsx)|*.xls*.xlsx"    //浏览过滤出以.xls或者.xlsx结尾的文件            if(dlg.ShowDialog() ==  DialogResult.OK)

{

string filePath = dlg.FileName  //获取打开文件的路径                this.textBox1.Text = filePath

}

}

//获取Excel中所有表的表名        public string[] GetTableName(string excelFilename)

{

//建立与指定Excel文件的连接            string connectionString = string.Format("Provider=Microsoft.ACE.OLEDB.12.0Data Source={0}Jet OLEDB:Engine Type=35Extended Properties=Excel 8.0Persist Security Info=False", excelFilename)

string[] tableName = new string[20] //存储Excel中所有表的表名            string temp  //中间变量

using (System.Data.OleDb.OleDbConnection connection = new System.Data.OleDb.OleDbConnection(connectionString))

{

connection.Open()

//获取数据库架构信息,包括列、主键、表等信息                DataTable table = connection.GetOleDbSchemaTable(System.Data.OleDb.OleDbSchemaGuid.Tables, null)

for (int i = 0 i < table.Rows.Counti++ )

{

temp = table.Rows[i]["Table_Name"].ToString()  //获取Excel中的表名                    tableName[i] = temp.Replace("$", "")   //因为获取的表名最后会有$符号,所以要替换                }

tableNameNum = table.Rows.Count

connection.Close()

}

return tableName

}

//获取Excel中每张表的数据,以datatable类型返回        public DataTable GetExcelTable(string excelFilename,string tableName)

{

//建立与指定Excel文件的连接            string connectionString = string.Format("Provider=Microsoft.ACE.OLEDB.12.0Data Source={0}Jet OLEDB:Engine Type=35Extended Properties=Excel 8.0Persist Security Info=False", excelFilename)

DataSet ds = new DataSet()  //数据集            //using中声明的对象connection,在using语句块结束后会自动释放            using (System.Data.OleDb.OleDbConnection connection = new System.Data.OleDb.OleDbConnection(connectionString))

{

connection.Open()

//获取数据库架构信息,包括列、主键、表等信息                DataTable table = connection.GetOleDbSchemaTable(System.Data.OleDb.OleDbSchemaGuid.Tables, null)

string strExcel = "select * from " + "[" + tableName + "$]"

//打开数据链接,得到一个数据集                OleDbDataAdapter adapter = new OleDbDataAdapter(strExcel, connectionString)

//在数据集中查询表名为tableName的表,然后把其数据在装入数据集ds中                adapter.Fill(ds, tableName)

connection.Close()

}

return ds.Tables[tableName]//以datatable类型返回数据集ds中表名为tableName的表        }

//判断在数据库中,指定表名的表是否存在        public bool TableExists(string table)

{

bool rythm

connection.Open()

//读取表名为table的表的行数信息            rythm = connection.GetSchema("Tables", new string[4] { null, null, table, "TABLE" }).Rows.Count > 0

connection.Close()

return rythm

}

//如果在建表之前,数据库已经存在该表,那么首先要先删除此表        public void DeleteTable(string tableName)

{

string sql = "drop table "+tableName+""

connection.Open()

OleDbCommand cmd = new OleDbCommand(sql, connection)

cmd.ExecuteNonQuery()

connection.Close()

}

//中间类型为dataTable的表数据转换到数据库mdb文件中        public bool dataTableToMdb(string excelPath,string tableName)

{

//获取Excel中表的数据            DataTable dt = GetExcelTable(excelPath,tableName)

//表中数据大于等于两行,数据转入格式才是正确的            if (dt.Rows.Count >= 2)

{

string[] cloumnName = new string[50]

//获取Excel中表的所有列名                for (int i = 0 i < dt.Columns.Count i++)

{

cloumnName[i] = dt.Rows[0][i].ToString()

}

//在mdb数据库文件中创建表                string sql = "create table " + tableName + " (" + cloumnName[0] + " varchar null)"

connection.Open()

OleDbCommand cmd = new OleDbCommand(sql, connection)

cmd.ExecuteNonQuery()

//在mdb数据库文件中,给已创建好的表添加好所有列                    for (int i = 1 i < dt.Columns.Count i++)

{

sql = "alter table " + tableName + " add " + cloumnName[i] + " varchar null"

cmd = new OleDbCommand(sql, connection)

cmd.ExecuteNonQuery()

}

//在mdb数据库文件中,给已创建好的表加入数据                            for (int t = 1 t < dt.Rows.Count t++)

{

sql = "insert into " + tableName + " values('"

for (int k = 0 k < dt.Columns.Count k++)

{

if (k != dt.Columns.Count - 1)

{

sql = sql + dt.Rows[t][k].ToString() + "','"

}

else                                    {

sql = sql + dt.Rows[t][k].ToString() + "')"

}

}

cmd = new OleDbCommand(sql, connection)

cmd.ExecuteNonQuery()

}

connection.Close()

return true

}

else            {

MessageBox.Show("Excel中"+ tableName +"表的原始数据格式不正确!")

}

return false

}

private void button2_Click(object sender, EventArgs e)

{

int flag = 1  //判断由Excel表导入到Mdb是否成功的标记变量                      


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/sjk/9575030.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-29
下一篇 2023-04-29

发表评论

登录后才能评论

评论列表(0条)

保存