使用SqlBulkCopy类实现导入excel表格
前言:
上篇博客介绍了SqlBulkCopy类批量操作数据库的相关操作,最后提到了可以使用这个类实现excel文件导入数据库,接下来我做简单介绍。
首先说一下思路:
- 把excel中的数据读出来并放入到DataTable中。
- 使用SqlBulkCopy类的方法批量导入数据库。
虽然只用简单的两部。但是我们需要考虑的问题还是用很多的,其中很重要的一点就是判断需要导入即excel中的数据是否合法,包括:是不是为空,是不是太长,是不是有重复,导入的字段是否对应。看起来挺吓人的,其实思路还是最重要的。只要敢想什么都能实现。
下面我简单的写一个小例子来说明一下。
多余的不说,直接到点击导入按钮:
protected void btnImportTeacher_Click(object sender, EventArgs e)
{
//成员业务逻辑层
MemberInfoBLL memberInfo = new MemberInfoBLL() ;
//BLL层把Excel转化为datatable类
CreateExcelDataBLL createExcelData = new CreateExcelDataBLL();
//将错误信息导出到Excel
DataTableToExcel dataTableToExcel = new DataTableToExcel();
/*-------------------------------------准备Excel文件--------------------------------------*/
//获取上传文件地址
string url = fupImportTeacher.PostedFile.FileName.ToString(); if (url == "")
{
//数据源为空,弹出提示:请选择Excel文件!
Page.ClientScript.RegisterStartupScript(Page.GetType(), "message", "<script language='javascript' defer>alert('请选择Excel文件!');</script>");
return;
} string urlLocation = url.Substring(url.LastIndexOf("\\") + 1);//获取文件名 DataTable dtAllMember;
//在系统中建文件夹up,并将excel文件另存
this.fupImportTeacher.SaveAs(Server.MapPath("~\\UploadFile") + "\\" + urlLocation);//记录文件名到服务器相对应的文件夹中 //获得文件路径
string strpath = Server.MapPath("~\\UploadFile") + "\\" + urlLocation; //把上传的Excel转换为datatable
dtAllMember = createExcelData.CreateExcelDataSource(strpath);
以上代码涉及到的类包括CreateExcelDataBLL 、DataTableToExcel
/*******************************************************************************
*文 件:CreateExcelDataBLL.cs
*作 者:韩义
*所属小组:图书馆维修管理系统
*文件说明:基础系统-把excel转化为datatable
*创建日期:2013年1月23日9:43:16
*修改作者:
*修改日期:
*修改描述:
*版 本 号:V1.0
*版本号变更记录:
********************************************************************************/ using System;
using System.Collections.Generic;
using System.Linq;
using System.Text; //引用各命名空间
using System.Data;
using System.Data.OleDb;
using System.Data.SqlClient;
using System.IO; namespace BLL
{
public class CreateExcelDataBLL
{
//构造方法
public CreateExcelDataBLL()
{ }
/// <summary>
/// 传入excel路径,转换为datatable
/// </summary>
/// <param name="url"></param>
/// <returns></returns>
public DataTable CreateExcelDataSource(string url)
{
//定义一个DataTable数据表
DataTable dt = null; //获得excel数据
string connetionStr = "Provider=Microsoft.Jet.OleDb.4.0;" + "data source=" + url + ";Extended Properties='Excel 8.0; HDR=YES; IMEX=1'";
//从Excel表的Sheet1单元格获取数据
string strSql = "select * from [Sheet1$]";
OleDbConnection oleConn = new OleDbConnection(connetionStr); OleDbDataAdapter oleAdapter = new OleDbDataAdapter(strSql, connetionStr);
try
{
//把Excel数据填充给DataTable
dt = new DataTable();
oleAdapter.Fill(dt);
//返回数据表
return removeEmpty(dt);
}
catch (Exception ex)
{
throw ex;
}
finally
{
oleAdapter.Dispose();
oleConn.Close();
oleConn.Dispose();
//删除上传的Excel文件(因为该文件的存在会占用多余的网站空间)
if (File.Exists(url))
{
File.Delete(url);
}
}
}
/// <summary>
/// 循环去除datatable中的空行
/// </summary>
/// <param name="dt"></param>
protected DataTable removeEmpty(DataTable dt)
{
List<DataRow> removelist = new List<DataRow>();
for (int i = 0; i < dt.Rows.Count; i++)
{
bool rowdataisnull = true;
for (int j = 0; j < dt.Columns.Count; j++)
{ if (!string.IsNullOrEmpty(dt.Rows[i][j].ToString().Trim()))
{ rowdataisnull = false;
} }
if (rowdataisnull)
{
removelist.Add(dt.Rows[i]);
} }
for (int i = 0; i < removelist.Count; i++)
{
dt.Rows.Remove(removelist[i]);
}
return dt;
}
}
}
/*******************************************************************************
*文 件:DataTableToExcel.cs
*作 者:韩义
*所属小组:图书馆维修管理系统
*文件说明:基础系统-把datatable转化为excel
*创建日期:2013年1月23日10:43:16
*修改作者:
*修改日期:
*修改描述:
*版 本 号:V1.0
*版本号变更记录:
********************************************************************************/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
//导入命名空间
using System.Data;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.IO;
namespace BLL
{
public class DataTableToExcel
{
/// <summary>
/// 导出Excel
/// </summary>
/// <param name="dt"></param>
/// <param name="ExportFileName"></param>
public void ToExcel(DataTable dt)
{
DataGrid dgExcel = new DataGrid();
dgExcel.DataSource = dt;
dgExcel.DataBind(); HttpContext.Current.Response.Charset = "GB2312";
string fileName = HttpUtility.UrlEncode(Guid.NewGuid().ToString(), System.Text.Encoding.UTF8);
string str = "attachment;filename=" + fileName + ".xls";
HttpContext.Current.Response.ContentEncoding = System.Text.Encoding.UTF8;
HttpContext.Current.Response.ContentType = "application/ms-excel";
HttpContext.Current.Response.AppendHeader("content-disposition", str);
StringWriter sw = new StringWriter();
HtmlTextWriter htmTextWriter = new HtmlTextWriter(sw);
dgExcel.RenderControl(htmTextWriter);
HttpContext.Current.Response.Write("<html><head><meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\" />");
string style = "<style>td{mso-number-format:\"\\@\";}</style>";//防止导出excel时将以0开头的全数字数据的0去掉
HttpContext.Current.Response.Write(style);
HttpContext.Current.Response.Write("</head><body>");
HttpContext.Current.Response.Write(sw);
HttpContext.Current.Response.Write("</body></html>");
HttpContext.Current.Response.End(); }
}
}
两个类的作用我想通过上面的解释大家都应该明白他们的作用了。
验证excel中数据的有效性:
下面介绍如何验证excel中数据的有效性。
/*-------------------------------------判断数据源是否合法--------------------------------------*/
//定义要求的字段数据
string[] headfields = { "成员姓名","学号","身份等级","小组名称","密码","性别","年龄","手机号","QQ号","邮箱","备注"};
//判断dtAllTeacher中是否包含全部要求的字段
for (int i = 0; i < headfields.Length; i++)
{
//只要有一个字段不被包含,则提示"数据源缺少必要的字段",并退出循环和整个方法
if (!dtAllMember.Columns.Contains(headfields[i]))
{
Page.ClientScript.RegisterStartupScript(Page.GetType(), "message", "<script language='javascript' defer>alert('数据源缺少必要的字段,请检查Excel数据源!');</script>");
//退出方法
return;
}
} //判断数据源中是否有数据
if (dtAllMember.Rows.Count == 0)
{
Page.ClientScript.RegisterStartupScript(Page.GetType(), "message", "<script language='javascript' defer>alert('Excel文件中没有任何数据,请填充数据!');</script>");
//退出方法
return;
} //判断是否有相同学号的行
DataView dvTeacher = new DataView(dtAllMember);
if (dvTeacher.Count != dvTeacher.ToTable(true, "学号").Rows.Count)
{
Page.ClientScript.RegisterStartupScript(Page.GetType(), "message", "<script language='javascript' defer>alert('Excel中有相同的学号,学号不能相同!');</script>");
//退出方法
return;
} DataSet dsMember = new DataSet("dt_Member"); //创建一个名为dt_Member的DataSet //手动创建的新数据表-学生数据表
DataTable dtAddMember = new DataTable("dt_AddMember"); //创建一个名为dt_AddMember的DataTalbe
//为dt_AddMember表内建立Column(表头),添加数据列:
dtAddMember.Columns.Add(new DataColumn("memberName", typeof(string)));
dtAddMember.Columns.Add(new DataColumn("memberStudentID", typeof(string)));
dtAddMember.Columns.Add(new DataColumn("level", typeof(string)));
dtAddMember.Columns.Add(new DataColumn("groupID", typeof(string)));
dtAddMember.Columns.Add(new DataColumn("memberPW", typeof(string)));
dtAddMember.Columns.Add(new DataColumn("sex", typeof(string)));
dtAddMember.Columns.Add(new DataColumn("age", typeof(string)));
dtAddMember.Columns.Add(new DataColumn("phone", typeof(string)));
dtAddMember.Columns.Add(new DataColumn("qq", typeof(string)));
dtAddMember.Columns.Add(new DataColumn("email", typeof(string)));
dtAddMember.Columns.Add(new DataColumn("explian", typeof(string))); //新建数据表用于存放错误数据
DataTable dtErrorRow = new DataTable();
//为dtErrorRow创建列
dtErrorRow.Columns.Add(new DataColumn("成员姓名", typeof(string)));
dtErrorRow.Columns.Add(new DataColumn("学号", typeof(string)));
dtErrorRow.Columns.Add(new DataColumn("身份等级", typeof(string)));
dtErrorRow.Columns.Add(new DataColumn("小组名称", typeof(string)));
dtErrorRow.Columns.Add(new DataColumn("密码", typeof(string)));
dtErrorRow.Columns.Add(new DataColumn("性别", typeof(string)));
dtErrorRow.Columns.Add(new DataColumn("年龄", typeof(string)));
dtErrorRow.Columns.Add(new DataColumn("手机号", typeof(string)));
dtErrorRow.Columns.Add(new DataColumn("QQ号", typeof(string)));
dtErrorRow.Columns.Add(new DataColumn("邮箱", typeof(string)));
dtErrorRow.Columns.Add(new DataColumn("备注", typeof(string)));
dtErrorRow.Columns.Add(new DataColumn("错误原因", typeof(string))); //从上传的Excel转换为的datatable表中取出数据,放入成员信息。
for (int intRow = 0; intRow < dtAllMember.Rows.Count; intRow++)
{ //成员姓名
strMemberName = dtAllMember.Rows[intRow]["成员姓名"].ToString();
//成员姓名
memberStudentID = dtAllMember.Rows[intRow]["学号"].ToString();
strLevel = dtAllMember.Rows[intRow]["身份等级"].ToString();
strGroupName = dtAllMember.Rows[intRow]["小组名称"].ToString(); strmemberPW = dtAllMember.Rows[intRow]["密码"].ToString();
strSex = dtAllMember.Rows[intRow]["性别"].ToString();
strAge = dtAllMember.Rows[intRow]["年龄"].ToString();
strPhone = dtAllMember.Rows[intRow]["手机号"].ToString();
strQQ = dtAllMember.Rows[intRow]["QQ号"].ToString(); strEmail = dtAllMember.Rows[intRow]["邮箱"].ToString();
strExplian=dtAllMember.Rows[intRow]["备注"].ToString(); //根据小组名称判断,小组是否存在
Boolean bFlag = false;
//判断输入的组名是否存在
bFlag = new BLL.GroupInfoBLL().ExistsByName(strGroupName); // ID
if (bFlag ==true )
{
//小组ID为--韩义
strGroupID = new BLL.GroupInfoBLL().GetModelByGroupName(strGroupName).groupID;
}
//否则将当前行添加到错误列表并跳出当前循环
else
{
//向错误列表中添加当前行
AddErrorRow(dtErrorRow, "指定的组名称不存在");
//跳出当前循环
continue;
} //判断成员ID是否存在
bFlag = false;//定义标识变量
//判断学号是否存在
bFlag = new BLL.MemberInfoBLL().Exists(memberStudentID);
//如果指定的成员代码已存在则将当前行添加到错误列表,并跳出当前循环
if (bFlag==true )
{
//向错误列表中添加当前行
AddErrorRow(dtErrorRow, "指定的成员已存在");
//跳出当前循环
continue;
}
//判断性别类型是否正确
if (strSex != "男" && strSex != "女")
{
//向错误列表中添加当前行
AddErrorRow(dtErrorRow, "成员性别错误");
//跳出当前循环
continue;
}
//判断身份等级是否正确
if (strLevel !="组员")
{
//向错误列表中添加当前行
AddErrorRow(dtErrorRow, "导入成员身份级别只能为“组员”,组长请在系统中指定");
//跳出当前循环
continue;
}
//判断是否包含密码信息
if (strmemberPW =="")
{
//向错误列表中添加当前行
AddErrorRow(dtErrorRow, "成员密码不能为空");
//跳出当前循环
continue;
}
//判断是否包含电话信息
if (strPhone =="")
{
//向错误列表中添加当前行
AddErrorRow(dtErrorRow, "成员手机号不能为空");
//跳出当前循环
continue;
}
//判断是否包含邮箱信息
if (strEmail =="")
{
//向错误列表中添加当前行
AddErrorRow(dtErrorRow, "成员邮箱不能为空");
//跳出当前循环
continue;
}
//判断是否包含学号信息
if (memberStudentID == "")
{
//向错误列表中添加当前行
AddErrorRow(dtErrorRow, "成员学号不能为空");
//跳出当前循环
continue;
}
//判断是否包含姓名信息
if (strMemberName == "")
{
//向错误列表中添加当前行
AddErrorRow(dtErrorRow, "成员姓名不能为空");
//跳出当前循环
continue;
} //添加成员信息表的新行
DataRow drAddMember = dtAddMember.NewRow();//注意这边创建dt的新行的方法。指定类型是DataRow而不是TableRow,然后不用new直接的用创建的DataTable下面的NewRow方法。
//学生信息表对应的各列值
drAddMember["memberName"] = strMemberName;
drAddMember["memberStudentID"] = memberStudentID;
drAddMember["level"] = strLevel;
drAddMember["groupID"] = strGroupID;
drAddMember["memberPW"] = strmemberPW;
drAddMember["sex"] = strSex;
drAddMember["age"] = strAge;
drAddMember["phone"] = strPhone;
drAddMember["qq"] = strQQ;
drAddMember["email"] = strEmail;
drAddMember["explian"] = strExplian;
dtAddMember.Rows.Add(drAddMember); //将一整条数据写入表中
} //将表加入DataSet中:成员信息
dsMember.Tables.Add(dtAddMember); //将DataSet中数据表导入数据库
Boolean flagImportMember = memberInfo.ImportMember(dsMember);
//判断成员是否导入成功
if (true == flagImportMember && dtErrorRow.Rows.Count == 0)
{
//导入成功,弹出提示
Page.ClientScript.RegisterStartupScript(Page.GetType(), "message", "<script language='javascript' defer>alert('成员信息导入成功!');</script>");
}
else if (false == flagImportMember)
{
//导入失败,弹出提示
Page.ClientScript.RegisterStartupScript(Page.GetType(), "message", "<script language='javascript' defer>alert('成员信息导入失败!');</script>");
}
else if (true == flagImportMember && dtErrorRow.Rows.Count != 0)
{
//只有部分数据导入成功,弹出提示
Page.ClientScript.RegisterStartupScript(Page.GetType(), "message", "<script language='javascript' defer>alert('成员信息只有部分导入成功,有错误的部分已导出为EXCEL,请查看新导出的EXCEL;新导出的Excel修改错误后可作为数据源重新导入');</script>");
//将错误数据导出到Excel并打开显示
dataTableToExcel.ToExcel(dtErrorRow);
}
}
说明:以上代码中建立了两个表一个用于导入:字段改为与数据库对应,另一个表用于导出:字段改为汉字说明。其中memberInfo.ImportMember方法就是实现数据库的批量导入,这在上一篇博客中已经有介绍了这里就不再累述了。
总结:
原来感觉挺难的东西,现在都已经完整的总结了出来。体会挺深的,什么东西首先不能被吓住,平常心态对待每一个新知识,总会找到熟悉的身影,总有那么个头绪让你一点一点屡清楚了。
使用SqlBulkCopy类实现导入excel表格的更多相关文章
- java解析导入excel表格转为实体类javabean,根据实体类中的中文名称
最近公司需求解析excel,一开始使用poi做的挺好的,后来直接上了几十万条数据的excel文件,内存直接溢出了,网上查到apache poi还提供了专门处理海量数据的方法,使用sax解析,果然用了内 ...
- php导入excel表格
我们做网站的时候经常要用到excel导入和导出的功能,我们通常的做法是用phpexcel工具包来完成,具体方法如下: html代码: <form action="{:U('Mall/u ...
- phpexcel导入excel表格
html代码 <form action="{:U('Mall/updExcel')}" method="POST" enctype="multi ...
- php利用PHPExcel类导出导入Excel用法
PHPExcel类是php一个excel表格处理插件了,下面我来给大家介绍利用PHPExcel类来导入与导出excel表格的应用方法,有需要了解的朋友不防参考参考(PHPExcel自己百度下载这里不介 ...
- C# SqlBulkCopy类批量导入数据
特别注意 sqlbulkcopy.ColumnMappings.Add(dt.Columns[i].ColumnName, dt.Columns[i].ColumnName); 插入的时候列的顺序可 ...
- 导入Excel表格(二)
1. 提取session中的数据.并进行分页操作,上传excel表格,保存到临时表格. 初始化临时表格,提交表单,判断状态是否为真,若为真,则启用 导入到数据库 的按钮:为false,让查询的url ...
- 怎样把Word文档导入Excel表格
Word是现在办公中的基础文件格式了,很多的内容我们都通过Word来进行编辑,那么当我们需要将Word文档里的信息导入到Excel里面的时候,我们应该怎样做呢?下面我们就一起来看一下吧. 操作步骤: ...
- 第三次作业--导入excel表格(完整版)
031302322 031302316 将教师排课表导入系统 使用powerdesigner设计数据库表格 设计概念模型 打开new -> Conceptual Data Model创建概念模型 ...
- 【tp5.1】通过PHPExcel实现导入excel表格
1.上github下载PHPExcel,链接:https://github.com/PHPOffice/PHPExcel 2.下载解压后,将Classes改名为PHPExcel如图 3.将文件夹复制到 ...
随机推荐
- Npm安装以及express框架的使用
一.安装node.js 下载node.js,并将其放置合适的位置 二.修改环境变量 添加Node执行路径添加到系统的环境变量PATH中,如图:在PATH变量的值的最后添加“C:\Program Fil ...
- 【python】python安装tensorflow报错:python No matching distribution found for tensorflow==1.12.0
python安装tensorflow报错:python No matching distribution found for tensorflow==1.12.0 python版本是3.7.2 要安装 ...
- ASP.NET MVC:三个被隐藏的扩展性“钻石”(转载)
原文地址:http://haacked.com/archive/2010/05/16/three-hidden-extensibility-gems-in-asp-net-4.aspx/. ASP.N ...
- crm操作产品实体
using System; using Microsoft.Xrm.Sdk; using Microsoft.Crm.Sdk.Messages; /// <summary> ...
- Linux 安全信息查看
终端登录情况 last ssh登录情况 cat /var/log/secure | grep -i "accepted password" 定时任务 cat /var/log/cr ...
- VMware vSphere中的HA工作原理介绍
http://blog.51cto.com/linkinsds/416738 HA全称High Availability.它是VMware的企业应用环境中用来保障企业级应用的不间断运行需求所产生的一个 ...
- C# Encoding UTF-16 ,C#中的UTF16
http://www.cnblogs.com/criedshy/archive/2012/08/07/2625358.html 前言 众所周知计算机只能识别二进制数字,如1010,1001.我们屏幕所 ...
- Windows7安装CodeTyphon
WARNING 1: On windows (XP, Vista and Win7), you must install this software as user with administrato ...
- 正向代理与反向代理区别图解 (nginx)
1. 背景 经常听到代理,比如通常我们要上国外的网站时,需要买vpn作为跳板机器进行访问. 但是在公司里面也听到了nginx支持反向代理. 那什么是正向代理,什么是反向代理?在网上看了写内容,说一下自 ...
- [leetcode]Sort Colors @ Python
原题地址:https://oj.leetcode.com/problems/sort-colors/ 题意: Given an array with n objects colored red, wh ...