Excel+GridView打造高级数据处理
利用Excel结合GridView进行数据导入/导出、编辑等功能,同时进行了扩展,好了下面简单列举实现的功能:)
原始数据表中数据:
Excel将要导入的数据:
导入后显示:
醒目/提示内容:
一键更新后显示(隐藏“一键更新”):
导入数据规则:
a. 如果编号不存在,则添加一条数据,同时状态显示黄色图标表示是“新增”;
b. 如果编号存在,则判断其他属性是否有更改,如果有更改则将字体加粗,同时鼠标放上时显示新值,状态显示为红色图标表示“有更新”;
c. 如果是有更改的数据,可以通过状态醒目标示,同时操作列加入一键“更新”功能,该功能会将所有的数据替换为最新的数值;
d. 新数据和旧数据都可在线编辑,更新后状态显示为绿色图标表示“已更新”(默认第一次打开时所有状态为“未更改”,显示图标同上)
数据库表结构:
关键代码+说明:
页面临时表/虚拟表结构
/// <summary>
/// Grid数据源
/// </summary>
private DataTable DataSource
{
get
{
if (ViewState["_dataSource"] == null)
{
DataTable dt = new DataTable();
dt.Columns.Add(new DataColumn("BSRID", typeof(long)));
dt.Columns.Add(new DataColumn("编号"));
dt.Columns.Add(new DataColumn("名称"));
dt.Columns.Add(new DataColumn("new名称"));
dt.Columns.Add(new DataColumn("备注"));
dt.Columns.Add(new DataColumn("new备注"));
dt.Columns.Add(new DataColumn("更改状态"));
ViewState["_dataSource"] = dt;
}
return ViewState["_dataSource"] as DataTable;
}
set
{
ViewState["_dataSource"] = value;
}
}
上传Excel处理函数
代码
/// <summary>
/// 上传Excel处理函数
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected void btnUpload_Click(object sender, EventArgs e)
{
#region 验证文件
if (string.IsNullOrEmpty(fudExcel.FileName))
{
AlertMessage("请选择上传文件!");
return;
}
string extension = fudExcel.FileName.Substring(fudExcel.FileName.LastIndexOf('.'));
if (extension == ".xlsx")
{
AlertMessage("目前模板只支持Excel2003版文件,请转换后再导入!");
return;
}
if (extension != ".xls")
{
AlertMessage("上传文件扩展必须是(xls/xlsx)文件!");
return;
}
#endregion
string filepath = string.Empty;
// 上传到服务器临时目录下
string tempdir = Server.MapPath("/temp/");
string filename = Guid.NewGuid() + extension;
filepath = tempdir + filename;
// 保存
fudExcel.SaveAs(filepath);
bool existsSheetname = false;
// 读取到DataTable
var data = ExcelDataSource(filepath, ref existsSheetname);
if (!existsSheetname)
{
AlertMessage("没有找到《模板工作表》工作表!");
return;
}
// 删除临时文件
System.IO.File.Delete(filepath);
if (data == null)
{
AlertMessage("解析Excel失败,请检查Excel是否符合模板要求!");
return;
}
foreach (DataRow row in data.Rows)
{
string id = row["编号"].ToString();
var arrRow = DataSource.Select("编号='" + id + "'");
if (arrRow != null && arrRow.Length > 0)
{
#region 比较是否有更新,有更新提示状态“有更新”
if (arrRow[0]["名称"].ToString() != row["名称"].ToString())
{
arrRow[0]["new名称"] = row["名称"].ToString();
arrRow[0]["更改状态"] = "有更新";
}
if (arrRow[0]["备注"].ToString() != row["备注"].ToString())
{
arrRow[0]["new备注"] = row["备注"].ToString();
arrRow[0]["更改状态"] = "有更新";
}
#endregion
}
else
{
DataRow newrow = DataSource.NewRow();
#region 设置状态为“新增”
newrow["更改状态"] = "新增";
newrow["编号"] = row["编号"];
newrow["名称"] = row["名称"];
newrow["new名称"] = row["名称"];
newrow["备注"] = row["备注"];
newrow["new备注"] = row["备注"];
#endregion
#region 添加到数据库
var bllRole = new BLL.BussSystemRole();
// 更新数据库记录
var modRole = new BussSystemRole();
if (modRole != null)
{
modRole.RoleID = row["编号"].ToString();
modRole.RoleName = row["名称"].ToString();
modRole.Remark = row["备注"].ToString();
bllRole.Add(modRole);
newrow["BSRID"] = modRole.BSRID;
}
#endregion
DataSource.Rows.Add(newrow);
}
DataSource.AcceptChanges();
// 绑定到Grid
gvwRoleBind();
}
}
/// <summary>
/// 上传Excel处理函数
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected void btnUpload_Click(object sender, EventArgs e)
{
#region 验证文件
if (string.IsNullOrEmpty(fudExcel.FileName))
{
AlertMessage("请选择上传文件!");
return;
}
string extension = fudExcel.FileName.Substring(fudExcel.FileName.LastIndexOf('.'));
if (extension == ".xlsx")
{
AlertMessage("目前模板只支持Excel2003版文件,请转换后再导入!");
return;
}
if (extension != ".xls")
{
AlertMessage("上传文件扩展必须是(xls/xlsx)文件!");
return;
}
#endregion
string filepath = string.Empty;
// 上传到服务器临时目录下
string tempdir = Server.MapPath("/temp/");
string filename = Guid.NewGuid() + extension;
filepath = tempdir + filename;
// 保存
fudExcel.SaveAs(filepath);
bool existsSheetname = false;
// 读取到DataTable
var data = ExcelDataSource(filepath, ref existsSheetname);
if (!existsSheetname)
{
AlertMessage("没有找到《模板工作表》工作表!");
return;
}
// 删除临时文件
System.IO.File.Delete(filepath);
if (data == null)
{
AlertMessage("解析Excel失败,请检查Excel是否符合模板要求!");
return;
}
foreach (DataRow row in data.Rows)
{
string id = row["编号"].ToString();
var arrRow = DataSource.Select("编号='" + id + "'");
if (arrRow != null && arrRow.Length > 0)
{
#region 比较是否有更新,有更新提示状态“有更新”
if (arrRow[0]["名称"].ToString() != row["名称"].ToString())
{
arrRow[0]["new名称"] = row["名称"].ToString();
arrRow[0]["更改状态"] = "有更新";
}
if (arrRow[0]["备注"].ToString() != row["备注"].ToString())
{
arrRow[0]["new备注"] = row["备注"].ToString();
arrRow[0]["更改状态"] = "有更新";
}
#endregion
}
else
{
DataRow newrow = DataSource.NewRow();
#region 设置状态为“新增”
newrow["更改状态"] = "新增";
newrow["编号"] = row["编号"];
newrow["名称"] = row["名称"];
newrow["new名称"] = row["名称"];
newrow["备注"] = row["备注"];
newrow["new备注"] = row["备注"];
#endregion
#region 添加到数据库
var bllRole = new BLL.BussSystemRole();
// 更新数据库记录
var modRole = new BussSystemRole();
if (modRole != null)
{
modRole.RoleID = row["编号"].ToString();
modRole.RoleName = row["名称"].ToString();
modRole.Remark = row["备注"].ToString();
bllRole.Add(modRole);
newrow["BSRID"] = modRole.BSRID;
}
#endregion
DataSource.Rows.Add(newrow);
}
DataSource.AcceptChanges();
// 绑定到Grid
gvwRoleBind();
}
}
用OleDB读取Excel数据
代码
/// <summary>
/// 读取Excel数据
/// </summary>
/// <param name="filepath"></param>
/// <returns></returns>
public DataTable ExcelDataSource(string filepath, ref bool existsSheetname)
{
DataTable dt = null;
string sheetname = "模板工作表$";
string strConn = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + filepath + ";Extended Properties=Excel 8.0;";
OleDbConnection conn = new OleDbConnection(strConn);
try
{
conn.Open();
DataTable sheetNames = conn.GetOleDbSchemaTable(System.Data.OleDb.OleDbSchemaGuid.Tables, new object[] { null, null, null, "TABLE" });
conn.Close();
// 获取第0个sheet
if (sheetNames.Rows.Count > 0)
{
foreach (DataRow row in sheetNames.Rows)
{
if (row[2].ToString() == sheetname)
{
existsSheetname = true;
break;
}
}
}
if (existsSheetname)
{
OleDbDataAdapter oada = new OleDbDataAdapter("select * from [" + sheetname + "]", strConn);
#region dt 定义
dt = new DataTable();
dt.Columns.Add(new DataColumn("编号"));
dt.Columns.Add(new DataColumn("名称"));
dt.Columns.Add(new DataColumn("备注"));
#endregion
oada.Fill(dt);
}
}
catch (Exception ex)
{
return null;
}
return dt;
}
/// <summary>
/// 读取Excel数据
/// </summary>
/// <param name="filepath"></param>
/// <returns></returns>
public DataTable ExcelDataSource(string filepath, ref bool existsSheetname)
{
DataTable dt = null;
string sheetname = "模板工作表$";
string strConn = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + filepath + ";Extended Properties=Excel 8.0;";
OleDbConnection conn = new OleDbConnection(strConn);
try
{
conn.Open();
DataTable sheetNames = conn.GetOleDbSchemaTable(System.Data.OleDb.OleDbSchemaGuid.Tables, new object[] { null, null, null, "TABLE" });
conn.Close();
// 获取第0个sheet
if (sheetNames.Rows.Count > 0)
{
foreach (DataRow row in sheetNames.Rows)
{
if (row[2].ToString() == sheetname)
{
existsSheetname = true;
break;
}
}
}
if (existsSheetname)
{
OleDbDataAdapter oada = new OleDbDataAdapter("select * from [" + sheetname + "]", strConn);
#region dt 定义
dt = new DataTable();
dt.Columns.Add(new DataColumn("编号"));
dt.Columns.Add(new DataColumn("名称"));
dt.Columns.Add(new DataColumn("备注"));
#endregion
oada.Fill(dt);
}
}
catch (Exception ex)
{
return null;
}
return dt;
}
导出Excel和Word脚本
代码
<SCRIPT LANGUAGE="javascript">
//指定页面区域内容导入Excel
function AllAreaExcel(id) {
var tb = document.getElementById(id);
if (tb == undefined) {
alert("没有可导出的数据");
return;
}
try {
var oXL = new ActiveXObject("Excel.Application");
var oWB = oXL.Workbooks.Add();
var oSheet = oWB.ActiveSheet;
var sel = document.body.createTextRange();
sel.moveToElementText(tb);
sel.select();
sel.execCommand("Copy");
oSheet.Paste();
oXL.Visible = true;
} catch (ex) {
alert("必须启用ActiveX!(步骤:Internet选项-->安全-->可信任站点-->点击站点--添加当前网站(去除服务器验证)\n\t-->设置自定义级别-->ActiveX控件和插件-->对未标记为可安全执行脚本的ActiveX控件初始化并执行脚本-->启用)");
}
}
//指定页面区域“单元格”内容导入Excel
function CellAreaExcel(tbID) {
var tb = document.getElementById(tbID);
if (tb == undefined) {
alert("没有可导出的数据");
return;
}
try {
var oXL = new ActiveXObject("Excel.Application");
var oWB = oXL.Workbooks.Add();
var oSheet = oWB.ActiveSheet;
var Lenr = tb.rows.length;
for (i = 0; i < Lenr; i++) {
var Lenc = tb.rows(i).cells.length - 2;
for (j = 0; j < Lenc; j++) {
oSheet.Cells(i + 1, j + 1).value = tb.rows(i).cells(j).innerText;
}
}
oXL.Visible = true;
} catch (ex) {
alert("必须启用ActiveX!(步骤:Internet选项-->安全-->可信任站点-->点击站点--添加当前网站(去除服务器验证)\n\t-->设置自定义级别-->ActiveX控件和插件-->对未标记为可安全执行脚本的ActiveX控件初始化并执行脚本-->启用)");
}
}
//指定页面区域内容导入Word
function AllAreaWord(id) {
var tb = document.getElementById(id);
if (tb == undefined) {
alert("没有可导出的数据");
return;
}
try {
var oWD = new ActiveXObject("Word.Application");
var oDC = oWD.Documents.Add("", 0, 1);
var oRange = oDC.Range(0, 1);
var sel = document.body.createTextRange();
sel.moveToElementText(tb);
sel.select();
sel.execCommand("Copy");
oRange.Paste();
oWD.Application.Visible = true;
} catch (ex) {
alert("必须启用ActiveX!(步骤:Internet选项-->安全-->可信任站点-->点击站点--添加当前网站(去除服务器验证)\n\t-->设置自定义级别-->ActiveX控件和插件-->对未标记为可安全执行脚本的ActiveX控件初始化并执行脚本-->启用)");
}
}
</SCRIPT>
//指定页面区域内容导入Excel
function AllAreaExcel(id) {
var tb = document.getElementById(id);
if (tb == undefined) {
alert("没有可导出的数据");
return;
}
try {
var oXL = new ActiveXObject("Excel.Application");
var oWB = oXL.Workbooks.Add();
var oSheet = oWB.ActiveSheet;
var sel = document.body.createTextRange();
sel.moveToElementText(tb);
sel.select();
sel.execCommand("Copy");
oSheet.Paste();
oXL.Visible = true;
} catch (ex) {
alert("必须启用ActiveX!(步骤:Internet选项-->安全-->可信任站点-->点击站点--添加当前网站(去除服务器验证)\n\t-->设置自定义级别-->ActiveX控件和插件-->对未标记为可安全执行脚本的ActiveX控件初始化并执行脚本-->启用)");
}
}
//指定页面区域“单元格”内容导入Excel
function CellAreaExcel(tbID) {
var tb = document.getElementById(tbID);
if (tb == undefined) {
alert("没有可导出的数据");
return;
}
try {
var oXL = new ActiveXObject("Excel.Application");
var oWB = oXL.Workbooks.Add();
var oSheet = oWB.ActiveSheet;
var Lenr = tb.rows.length;
for (i = 0; i < Lenr; i++) {
var Lenc = tb.rows(i).cells.length - 2;
for (j = 0; j < Lenc; j++) {
oSheet.Cells(i + 1, j + 1).value = tb.rows(i).cells(j).innerText;
}
}
oXL.Visible = true;
} catch (ex) {
alert("必须启用ActiveX!(步骤:Internet选项-->安全-->可信任站点-->点击站点--添加当前网站(去除服务器验证)\n\t-->设置自定义级别-->ActiveX控件和插件-->对未标记为可安全执行脚本的ActiveX控件初始化并执行脚本-->启用)");
}
}
//指定页面区域内容导入Word
function AllAreaWord(id) {
var tb = document.getElementById(id);
if (tb == undefined) {
alert("没有可导出的数据");
return;
}
try {
var oWD = new ActiveXObject("Word.Application");
var oDC = oWD.Documents.Add("", 0, 1);
var oRange = oDC.Range(0, 1);
var sel = document.body.createTextRange();
sel.moveToElementText(tb);
sel.select();
sel.execCommand("Copy");
oRange.Paste();
oWD.Application.Visible = true;
} catch (ex) {
alert("必须启用ActiveX!(步骤:Internet选项-->安全-->可信任站点-->点击站点--添加当前网站(去除服务器验证)\n\t-->设置自定义级别-->ActiveX控件和插件-->对未标记为可安全执行脚本的ActiveX控件初始化并执行脚本-->启用)");
}
}
</SCRIPT>
剩下的自己看实例代码:https://files.cnblogs.com/yizhuqing/ExcelGridViewSample.rar
对于Excel的导入/导出功能想必是目前企业业务系统中比较常见的功能模块,对于用户的易用性和功能完整性可能一般没有太多的关注和支持,本例目的在于提供一种新的对Excel导入/导出和GridView数据操作的功能实现和思路;本例技术含量不高,如果您有更好的建议请共享一二:)
作者:木子清
联系方式:微信 billy_yi QQ: 909501683 多年.NET平台开发经验,擅长物联网各类设备(地磅、轨道秤、RFID等)集成开发。
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。