对于从sqlserver中导入、导出excel,虽然sqlserver已经给了较为简单的方式,通过交互式的对话框形式实现,但是有时这种方式存在的很多问题,比方说导入、导出数据不全。而且,对于一个项目而言,我们都不希望功能的实现离开该软件程序。因此,我们便想着用程序来实现sqlserver的导入导出。
一、从sqlserver中导出excel表
我们将查出的数据首先要保存到数据表中DataTable,这里我就不具体说明如何从查出结果,存放到DataTable中了,相信网上有很多实现的例子。
接下拉我们做的就是先找到存放这个文件的路径,代码如下:
这段代码,意思是看是否存在文件夹,如果存在,则查看是否存在文件,如果不存在文件夹或者文件,都将进行创建。
private void exportout_Click(object sender, EventArgs e) { Helper helper = new Helper();//这是我自己写的类,具体你可以不用看,只知道它是用来获取Debug路径的就可以了。具体代码看我上一篇文章:http://blog.csdn.net/ztzi321/article/details/44077563 Global.filepath = helper.GetAssemblyFileDirectory()+@"\Excel"; if (!Directory.Exists(Global.filepath)) { Directory.CreateDirectory(Global.filepath); } saveFile=Global.filepath +=@"\党员基本信息表.xlsx"; if (!File.Exists(saveFile)) { File.Create(saveFile); } Global.ExportExcel(partyMemberTable, Global.filepath);//调用导出excel函数,partyMemberTable为存储查询结果的DataTable。Global是我定义的一个全局类,里面有全局变量和函数,这里我将实现导出excel函数也放在了里面。 }导出excel函数具体实现如下:
public static void ExportExcel(System.Data.DataTable dt,String saveFile ) { object objectMissing; objectMissing = System.Reflection.Missing.Value;//将一个默认值返回个objectMissing if (dt == null || dt.Rows.Count == 0) return; Microsoft.Office.Interop.Excel.Application xlApp = new Microsoft.Office.Interop.Excel.Application();//创建Excel应用程序。 if (xlApp == null) { return; } //System.Globalization.CultureInfo CurrentCI = System.Threading.Thread.CurrentThread.CurrentCulture; //System.Threading.Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo("en-US"); Microsoft.Office.Interop.Excel.Workbooks workbooks = xlApp.Workbooks;//创建一个工作簿集合对象。 Microsoft.Office.Interop.Excel.Workbook workbook = workbooks.Add(objectMissing);//创建一个新的工作簿 Microsoft.Office.Interop.Excel.Worksheet worksheet = workbook.Worksheets[1] as Microsoft.Office.Interop.Excel.Worksheet;//创建一个工作表对象。 Microsoft.Office.Interop.Excel.Range range;//创建一个excel表格的范围对象。 long totalCount = dt.Rows.Count; //获取导出数据行数 long rowRead = 0; float percent = 0;
此段代码为表格标题列内容
for (int i = 0; i < dt.Columns.Count; i++) { worksheet.Cells[1, i + 1] = dt.Columns[i].ColumnName;//excel的行列是从1开始的 range = (Microsoft.Office.Interop.Excel.Range)worksheet.Cells[1, i + 1]; range.Interior.ColorIndex = 15; //15号字体 range.Font.Bold = true;//粗体 }
此段代码为将数据表中的内容导入到excel表中,因此是从第二行开始的
for (int r = 0; r < dt.Rows.Count; r++) { for (int i = 0; i < dt.Columns.Count; i++) { worksheet.Cells[r + 2, i + 1] = dt.Rows[r][i].ToString(); } rowRead++; percent = ((float)(100 * rowRead)) / totalCount; } // xlApp.Visible = true; try {//因为在之前我们已经创建了excel表,但是之前那个还没有数据,因此需要保存。msdn上介绍了save的用法,“当第一次保存excel表示用SaveAs来进行保存文件,下边具体的参数含义,可以具体参照msdn介绍的WookBool.SaveAs()方法” workbook.SaveAs(saveFile, objectMissing, objectMissing, objectMissing, objectMissing, objectMissing, XlSaveAsAccessMode.xlShared, objectMissing, objectMissing, objectMissing, objectMissing, objectMissing); } catch(Exception ex) { MessageBox.Show("有错误:"+ex.ToString()); } MessageBox.Show("保存成功!"); xlApp.Quit();//关闭程序。 //xlApp. }
这样我们就完成了数据库中数据导出到excel中。
二、从Excel表中将数据导入到sqlserver中
首先,我们需要确定的是,excel表中的表列名应该和数据库中的表列名相一致。
这里我先讲解一下实现过程的原理:创建一个DataTable,首先将excel表与DataTable进行创建连接,将excel表中的数据保存到DataTable中,然后用sql语句进行循环的一行行插入到sqlserver中。
具体实现代码如下:
这里我创建了一个按钮,通过按钮的点击事件进行处理
private void exportin_Click(object sender, EventArgs e) { DataTable dt = new DataTable();//创建一个DataTable表,用于存储从excel表中读取的数据 OpenFileDialog open = new OpenFileDialog();//创建一个打开文件窗口类 if(open.ShowDialog()==DialogResult.OK) { string fileName = open.FileName;//获取选取的文件,这里你也可以用过滤方式,过滤一下文件类型。 bind(dt,fileName);//excel表中数据导入到DataTable中过程函数 } }
将excel中的数据导入到DataTable中
private void bind(DataTable table,string fileName) { /*1.数据库引擎:microsoft.ace.oledb.12.0和Microsoft.Jet.OLEDB.4.0 *2.Extended Properties:扩展属性, Excel中8.0为07以上至03,Excel 12.0为07和10 *3.HDR=Yes,这代表第一行是标题,不做为数据使用 ,如果用HDR=NO,则表示第一行不是标题,做为数据来使用。系统默认的是YES\ *4.IMEX ( IMport EXport mode )设置 IMEX 有三种模式: 0 is Export mode 1 is Import mode 2 is Linked mode (full update capabilities) 我这里特别要说明的就是 IMEX 参数了,因为不同的模式代表著不同的读写行为: 当 IMEX=0 时为“汇出模式”,这个模式开启的 Excel 档案只能用来做“写入”用途。 当 IMEX=1 时为“汇入模式”,这个模式开启的 Excel 档案只能用来做“读取”用途。 当 IMEX=2 时为“连結模式”,这个模式开启的 Excel 档案可同时支援“读取”与“写入”用途。 意义如下: 0 ---输出模式; 1---输入模式; 2----链接模式(完全更新能力) */ string strConn = "Provider=Microsoft.ACE.OLEDB.12.0;" + "Data Source=" + fileName + ";" + "Extended Properties='Excel 12.0; HDR=Yes; IMEX=1'"; //String sheetName = "党员基本信息表"; String excelStr =String.Format("select * from [党员基本信息表$]");//这里是sheet表名 OleDbDataAdapter da = new OleDbDataAdapter( excelStr,strConn); DataSet ds = new DataSet();//创建数据集,数据集这里你可以看作包含多个数据表 try { da.Fill(ds);//将excel表中的数据保存到DataTable中。 table = ds.Tables[0]; //this.dataGridView1.DataSource = dt; } catch (Exception err) { MessageBox.Show("操作失败!" + err.ToString()); } foreach(DataRow dr in table.Rows) { insertToSql(dr);//此函数是将数据表table中的数据一行行的插入到sqlserver中。 } }将数据表中的数据插入到sqlserver中
private void insertToSql(DataRow dataRow ) {//1、Data Source:数据库引擎名,一般用(lcoal),如果设置了实例,则用.\实例名方式。
//2、Initial Catalog:数据库名字
//3、User ID:用户名
//4、Password:密码;其它的不做过多解释了,可以不用写 string connString = @"Data Source=.\SQLSERVER2008R2;Initial Catalog=organization;Persist Security Info=False;User ID=sa;Password=123;Min Pool Size=10;Max Pool Size=1000"; SqlConnection conn = new SqlConnection(connString);//创建连接 conn.Open();//打开连接
//数据库sql语句 String sqlstring = "use Organization insert into partyMembers(memberID,memberName,sex,cardID,birthDate,nation,nativePlace,politicalStatus,education," + "partyDate,orgID,branchID,depID,duty,beginYear,endYear,editor,editTime,parentOrg,audit,auditTime,status,remark) " + "values('{0}','{1}','{2}','{3}','{4}','{5}','{6}','{7}','{8}','{9}'," + "'{10}','{11}','{12}','{13}',{14},{15},'{16}','{17}','{18}','{19}'," + "'{20}','{21}','{22}')"; sqlstring = String.Format(sqlstring, Convert.ToString(dataRow["memberID"]), Convert.ToString(dataRow["memberName"]), Convert.ToString(dataRow["sex"]), Convert.ToString(dataRow["cardID"]), Convert.ToDateTime(dataRow["birthDate"]).ToString("yyyy-MM-dd"), Convert.ToString(dataRow["nation"]), Convert.ToString(dataRow["nativePlace"]), Convert.ToString(dataRow["politicalStatus"]), Convert.ToString(dataRow["education"]), Convert.ToDateTime(dataRow["partyDate"]).ToString("yyyy-MM-dd"), Convert.ToString(dataRow["orgID"]), Convert.ToString(dataRow["branchID"]), Convert.ToString(dataRow["depID"]), Convert.ToString(dataRow["duty"]), Convert.ToString(dataRow["beginYear"]), Convert.ToString(dataRow["endYear"]), Convert.ToString(dataRow["editor"]), DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), Convert.ToString(dataRow["parentOrg"]), Convert.ToString(dataRow["audit"]), Convert.ToString(dataRow["auditTime"]), Convert.ToString(dataRow["status"]), Convert.ToString(dataRow["remark"])); SqlCommand command = new SqlCommand(sqlstring, conn); command.ExecuteNonQuery();//执行sql语句 }
这里我列出在编写从excel表中导入到sqlserver中的一些问题,希望这些说明可以对你在做本操作时有用
1、
这个问题我们第一眼上会认为是计算机本身安装的office有问题,其实问题并不在此,因为excel导入到sqlserver中程序对于64位支持性不好,所以我们将项目的CPU由ANY Cpu改为x86.如下图所示:
如果没有x86,需要先创建,点击“配置管理器”,具体界面如下:
这样此问题就解决了。
(续:随后发现这样修改也并不能实际解决问题,于是又参考了一下,右击项目-属性,然后将生成改为x86,发现之前为any cpu ,上边那种方式还是无法根本修改。)
如下图所示:
2、
外部表不是预期格式,此问题有以下几个:
1)、不要用程序生成的excel
2)、将excel保存为97-03版excel,格式为.xls(我个人理解是excel兼容性问题,97-03更加适合编程使用)
3、显示“连接登录失败”
查看连接字符串是否正确,可以从以下几方面查看:
1)、Data Source 中实例名是否正确
2)、数据库名是否正确
3)、数据库用户是否存在,若存在,密码是否正确
4、对于excel表中的多位数的格式设置:
例如身份者证号:18位,在excel表设置格式,应设置为text格式,如果设置成数值形式的话,它会将在数据库中以16进制表示形式表示。
至此,sqlserver与excel表的导入、导出完毕!!祝好运!!