GridView选择性导出Excel解决方案
程序员文章站
2024-02-26 17:49:58
一、需求分析 首先根据用户需求,可以进行选择性导出,之前已经做了全部导出,这次新需求又来了,不过仔细想想也对,全部导出几万条数据,意义并不大,而可选择性的导出用户需要的数据...
一、需求分析
首先根据用户需求,可以进行选择性导出,之前已经做了全部导出,这次新需求又来了,不过仔细想想也对,全部导出几万条数据,意义并不大,而可选择性的导出用户需要的数据才是用户需要的。有需求就有解决方法。
任何问题的解决方法都不止一个,gridview的选择性导出也一样,首先gridview绑定的是数据库的表数据,选择导出,我们也可以从数据中查询需要的数据,可以直接从前台gridview表中取得数据,问题来了,怎么判断选中了,怎么后去选中的那条信息的主键(或者获得整条信息)两个方向,到底哪个效率哪个更优?
二、解决方法
one
1. 前台获取选中行的主键信息,通过json格式,传送到后台,后台解析后,再从数据库中取得数据,通过datatable导出到excel
⑴. 导出所选操作
<asp:button id="export" runat="server" cssclass="btn-lit" text="导出所选" onclientclick="return getnumberexport()" onclick="export_click"/>
⑵. 前台js,获取选中行的那条信息的主键,也就是gridview要有一列是主键,获取到所有的主键以json格式保存,然后传到服务器
<script type="text/javascript">
function getnumberexport() {
if (exportcheck()) {
//通过gridview id获取元素
var gv = document.getelementbyid("ctl00_contentplaceholder1_gridview");
//获取gridview的input html
var mycheck = gv.getelementsbytagname("input");
//定义一个新数组
var fam = new array();
var hg;
var id;
//循环检测checkbox标签,获取每条数据的主键信息
for (var i = 0; i < mycheck.length; i++) {
if (mycheck[i].type == 'checkbox')//hidden
{
//如果checkbox被选中
if (mycheck[i].checked == true) {
var numid = new object();
hg = gv.rows(i + 1).cells(20).innerhtml;
//substring() 方法用于提取字符串中介于两个指定下标之间的字符。
//lastindexof()倒取字符串,从后往前取到指定的字符
hg = hg.substring(hg.lastindexof("=") + 1, hg.lastindexof("\""));
//获取一条数据的主键
id = gv.rows(i + 1).cells(1).innerhtml;
numid.number = hg;
numid.id = id;
fam.push(numid);
}
}
}
//$.ajaxsetup({
// async: false //设置为同步请求
//});
//将数组转换成json类型
var nid = json.stringify(fam);
//post方式,向服务器传送数据
$.post("list.aspx", { action: "action", numid: nid}, function (result) {
});
}
else {
return false;
}
}
</script>
⑶. 后台解析json,转换成datatable,导出到excel
protected void page_load(object sender, eventargs e)
{
//判断服务器是否正确接收数据
if (request.params["action"] !=null)
{
//获取前台的json
string numid = request.params["numid"].tostring();
session["numid"] = numid;
}
}
/// <summary>
/// 选择性导出excel
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected void export_click(object sender, eventargs e)
{
familyplanningfacade familyplanningfacade = new familyplanningfacade(); //实例化计生外观层
dataset dsallfamily = new dataset();
dataset dsonefamily = new dataset();
dsallfamily = familyplanningfacade.getalllist(); //获得所有计生信息
dsallfamily.tables[0].rows.clear();
//解析json;需引入newtonsoft.json和newtonsoft.json.linq库
jarray numidget = (jarray)jsonconvert.deserializeobject(session["numid"].tostring());
//遍历json中所需要的值,在通过这个值查询数据库获取一条数据,将数据加入新行
for (int i = 0; i < numidget.count; i++)
{
jobject numberget = (jobject)numidget[i];
string num = numberget["number"].tostring();
if (num.equals(""))
{
//获取id的键值
string id = numberget["id"].tostring();
//enbasic.id = id;
//通过id的值(唯一)查询到一条数据
dsexport = famfacade.selectexport(id);
//新建行
datarow row = newdatatable.newrow();
//向新建行中添加数据
row.itemarray = dsexport.tables[0].rows[0].itemarray;
//添加此行到datatable中
newdatatable.rows.add(row);
}
}
datatable dtfamilyplanning = new datatable(); //创建计生信息数据表
dtfamilyplanning = newdatatable.tables[0];
//设置表字段
dtfamilyplanning = dtfamilyplanning.defaultview.totable(false, new string[] { "id", "name", "sex" });
//修改表头信息,为了使导出的excel表头为汉字
dtfamilyplanning.columns["id"].columnname = "编号";
dtfamilyplanning.columns["name"].columnname = "姓名";
dtfamilyplanning.columns["sex"].columnname = "性别";
//....表中其它信息不再细写
//新建datatabletoexcel类的对象
datatabletoexcel dttoexcel = new datatabletoexcel();
//导出数据到excel
dttoexcel.toexcel(dtfamilyplanning);
}
⑷. datatable导出为excel方法,很不错的方法,站在巨人肩膀上为我所用。
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();
}
最后看一遍这个方法的整个实现过程:
1 通过前台获取每个选中行的主键值,
2 再将所有的键值保存到数组,数组转化成json格式,
3 在通过ajax传到后台,
4 后台接收,解析json,取得json中的值,
5 即可查询数据库获得每条选中的数据,将每行数据添加到datatable中,
6 最后导出为excel。
这个方法存在的问题:一.前台获取gridview选中行的主键值,通过innerhtml获取主键的位置,也就是说如果html中主键位置变动,获取主键代码也要变,这个影响比较大,牵一发而动全身,这样对系统的灵活性很有影响。
再看第二个方法:
two
2. 后台直接后去前台gridview表的主键集合,获取到后的实现和上一个方法类似。
⑴.导出所选操作
<asp:button id="export" runat="server" cssclass="btn-lit" text="导出所选" onclick="export_click"/>
⑵. 后台button事件
protected void export_click(object sender, eventargs e)
{
dataset dsallfamily = new dataset();
dataset dsonefamily = new dataset();
familyplanningfacade familyplanningfacade = new familyplanningfacade(); //实例化计生外观
dsallfamily = familyplanningfacade.getalllist(); //获得所有计生信息
dsallfamily.tables[0].rows.clear();
//循环gridview每行,查找checkbox被选中的行
foreach (gridviewrow msgrow in this.gridview.rows)
{
//通过id获得所需要遍历的checkbox
checkbox chk = (checkbox)msgrow.findcontrol("deletethis");
//判断checkbox是否被选中
if (chk.checked)
{
//获取id的键值
string id = msgrow.cells[1].text.tostring();
dsonefamily = familyplanningfacade.getlist(id);
//新建行
datarow row = dsallfaamily.tables[0].newrow();
//向新建行中添加数据
row.itemarray = dsonefamily.tables[0].rows[0].itemarray;
//添加此行到datatable中
dsallfamily.tables[0].rows.add(row);
}
}
if (dsallfamily.tables[0].rows.count == 0)
{
personalfiles.web.messageshow.messagebox.show(this, "请选择需要导出的信息!");
return;
}
datatable dtfamilyplanning = new datatable(); //创建计生信息数据表
dtfamilyplanning = dsallfamily.tables[0];
//设置表字段
dtfamilyplanning = dtfamilyplanning.defaultview.totable(false, new string[] { "id", "name", "sex" });
//修改表头信息,为了使导出的excel表头为汉字
dtfamilyplanning.columns["id"].columnname = "编号";
dtfamilyplanning.columns["name"].columnname = "姓名";
dtfamilyplanning.columns["sex"].columnname = "性别";
//....表中其它信息不再细写
//新建datatabletoexcel类的对象
datatabletoexcel dttoexcel = new datatabletoexcel();
//导出数据到excel
dttoexcel.toexcel(dtfamilyplanning);
}
这个方法的实现过程很简单,直接在后台获取的是前台gridview显示的主键数据,相比前台传json数据相对简单了很多。
three
3. 除了这两种外还有更快速的方法,不需要重新查询数据库,而是直接从gridview中直接获得显示的数据,不好的地方就是如果数据多人操作,而且更新频繁,那直接从界面gridview获取数据可能就不是最新的数据。
protected void export_click(object sender, eventargs e)
{
datatable dsexport = new datatable();
//循环获取gridview的每列,获取表头
for(int i=0;i<this.gridview.columns.count-1;i++)
{
//将表头信息添加到datatable表头
dsexport.columns.add(this.gridview.columns[i].headertext);
}
//循环gridview每行,查找checkbox被选中的行
foreach (gridviewrow msgrow in this.gridview.rows)
{
//通过id获得所需要遍历的checkbox
checkbox chk = (checkbox)msgrow.findcontrol("deletethis");
//判断checkbox是否被选中
if (chk.checked){
//定义datatable新行
system.data.datarow dr = dsexport.newrow();
for (int i = 0; i < msgrow.cells.count-1; i++)
{
//获取cells数据
dr[i] =msgrow.cells[i].text.tostring();
}
//添加新行到datatable
dsexport.rows.add(dr);
}
else
{
personalfiles.web.messageshow.messagebox.show(this, "请选择需要导出的信息!");
return;
}
}
//移除datatable中不需要的列
dsexport.columns.remove("选择");
dsexport.columns.remove("详细");
dsexport.columns.remove("编辑");
personalfiles.bll.datatabletoexcel dttoexcel = new personalfiles.bll.datatabletoexcel();
//导出数据到excel
dttoexcel.toexcel(dsexport);
}
三种方法上面写的很清楚了,各有优势,根据实际项目的要求去选,学习过程必然是需要多接触各种方法的实现,之前写过关于json的博客,就是没用过,这次一个机会,学会了一个用法,感觉爽呀,反复学习,不断积累的过程,heiheihei。
首先根据用户需求,可以进行选择性导出,之前已经做了全部导出,这次新需求又来了,不过仔细想想也对,全部导出几万条数据,意义并不大,而可选择性的导出用户需要的数据才是用户需要的。有需求就有解决方法。
任何问题的解决方法都不止一个,gridview的选择性导出也一样,首先gridview绑定的是数据库的表数据,选择导出,我们也可以从数据中查询需要的数据,可以直接从前台gridview表中取得数据,问题来了,怎么判断选中了,怎么后去选中的那条信息的主键(或者获得整条信息)两个方向,到底哪个效率哪个更优?
二、解决方法
one
1. 前台获取选中行的主键信息,通过json格式,传送到后台,后台解析后,再从数据库中取得数据,通过datatable导出到excel
⑴. 导出所选操作
复制代码 代码如下:
<asp:button id="export" runat="server" cssclass="btn-lit" text="导出所选" onclientclick="return getnumberexport()" onclick="export_click"/>
⑵. 前台js,获取选中行的那条信息的主键,也就是gridview要有一列是主键,获取到所有的主键以json格式保存,然后传到服务器
复制代码 代码如下:
<script type="text/javascript">
function getnumberexport() {
if (exportcheck()) {
//通过gridview id获取元素
var gv = document.getelementbyid("ctl00_contentplaceholder1_gridview");
//获取gridview的input html
var mycheck = gv.getelementsbytagname("input");
//定义一个新数组
var fam = new array();
var hg;
var id;
//循环检测checkbox标签,获取每条数据的主键信息
for (var i = 0; i < mycheck.length; i++) {
if (mycheck[i].type == 'checkbox')//hidden
{
//如果checkbox被选中
if (mycheck[i].checked == true) {
var numid = new object();
hg = gv.rows(i + 1).cells(20).innerhtml;
//substring() 方法用于提取字符串中介于两个指定下标之间的字符。
//lastindexof()倒取字符串,从后往前取到指定的字符
hg = hg.substring(hg.lastindexof("=") + 1, hg.lastindexof("\""));
//获取一条数据的主键
id = gv.rows(i + 1).cells(1).innerhtml;
numid.number = hg;
numid.id = id;
fam.push(numid);
}
}
}
//$.ajaxsetup({
// async: false //设置为同步请求
//});
//将数组转换成json类型
var nid = json.stringify(fam);
//post方式,向服务器传送数据
$.post("list.aspx", { action: "action", numid: nid}, function (result) {
});
}
else {
return false;
}
}
</script>
⑶. 后台解析json,转换成datatable,导出到excel
复制代码 代码如下:
protected void page_load(object sender, eventargs e)
{
//判断服务器是否正确接收数据
if (request.params["action"] !=null)
{
//获取前台的json
string numid = request.params["numid"].tostring();
session["numid"] = numid;
}
}
/// <summary>
/// 选择性导出excel
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected void export_click(object sender, eventargs e)
{
familyplanningfacade familyplanningfacade = new familyplanningfacade(); //实例化计生外观层
dataset dsallfamily = new dataset();
dataset dsonefamily = new dataset();
dsallfamily = familyplanningfacade.getalllist(); //获得所有计生信息
dsallfamily.tables[0].rows.clear();
//解析json;需引入newtonsoft.json和newtonsoft.json.linq库
jarray numidget = (jarray)jsonconvert.deserializeobject(session["numid"].tostring());
//遍历json中所需要的值,在通过这个值查询数据库获取一条数据,将数据加入新行
for (int i = 0; i < numidget.count; i++)
{
jobject numberget = (jobject)numidget[i];
string num = numberget["number"].tostring();
if (num.equals(""))
{
//获取id的键值
string id = numberget["id"].tostring();
//enbasic.id = id;
//通过id的值(唯一)查询到一条数据
dsexport = famfacade.selectexport(id);
//新建行
datarow row = newdatatable.newrow();
//向新建行中添加数据
row.itemarray = dsexport.tables[0].rows[0].itemarray;
//添加此行到datatable中
newdatatable.rows.add(row);
}
}
datatable dtfamilyplanning = new datatable(); //创建计生信息数据表
dtfamilyplanning = newdatatable.tables[0];
//设置表字段
dtfamilyplanning = dtfamilyplanning.defaultview.totable(false, new string[] { "id", "name", "sex" });
//修改表头信息,为了使导出的excel表头为汉字
dtfamilyplanning.columns["id"].columnname = "编号";
dtfamilyplanning.columns["name"].columnname = "姓名";
dtfamilyplanning.columns["sex"].columnname = "性别";
//....表中其它信息不再细写
//新建datatabletoexcel类的对象
datatabletoexcel dttoexcel = new datatabletoexcel();
//导出数据到excel
dttoexcel.toexcel(dtfamilyplanning);
}
⑷. datatable导出为excel方法,很不错的方法,站在巨人肩膀上为我所用。
复制代码 代码如下:
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();
}
最后看一遍这个方法的整个实现过程:
1 通过前台获取每个选中行的主键值,
2 再将所有的键值保存到数组,数组转化成json格式,
3 在通过ajax传到后台,
4 后台接收,解析json,取得json中的值,
5 即可查询数据库获得每条选中的数据,将每行数据添加到datatable中,
6 最后导出为excel。
这个方法存在的问题:一.前台获取gridview选中行的主键值,通过innerhtml获取主键的位置,也就是说如果html中主键位置变动,获取主键代码也要变,这个影响比较大,牵一发而动全身,这样对系统的灵活性很有影响。
再看第二个方法:
two
2. 后台直接后去前台gridview表的主键集合,获取到后的实现和上一个方法类似。
⑴.导出所选操作
复制代码 代码如下:
<asp:button id="export" runat="server" cssclass="btn-lit" text="导出所选" onclick="export_click"/>
⑵. 后台button事件
复制代码 代码如下:
protected void export_click(object sender, eventargs e)
{
dataset dsallfamily = new dataset();
dataset dsonefamily = new dataset();
familyplanningfacade familyplanningfacade = new familyplanningfacade(); //实例化计生外观
dsallfamily = familyplanningfacade.getalllist(); //获得所有计生信息
dsallfamily.tables[0].rows.clear();
//循环gridview每行,查找checkbox被选中的行
foreach (gridviewrow msgrow in this.gridview.rows)
{
//通过id获得所需要遍历的checkbox
checkbox chk = (checkbox)msgrow.findcontrol("deletethis");
//判断checkbox是否被选中
if (chk.checked)
{
//获取id的键值
string id = msgrow.cells[1].text.tostring();
dsonefamily = familyplanningfacade.getlist(id);
//新建行
datarow row = dsallfaamily.tables[0].newrow();
//向新建行中添加数据
row.itemarray = dsonefamily.tables[0].rows[0].itemarray;
//添加此行到datatable中
dsallfamily.tables[0].rows.add(row);
}
}
if (dsallfamily.tables[0].rows.count == 0)
{
personalfiles.web.messageshow.messagebox.show(this, "请选择需要导出的信息!");
return;
}
datatable dtfamilyplanning = new datatable(); //创建计生信息数据表
dtfamilyplanning = dsallfamily.tables[0];
//设置表字段
dtfamilyplanning = dtfamilyplanning.defaultview.totable(false, new string[] { "id", "name", "sex" });
//修改表头信息,为了使导出的excel表头为汉字
dtfamilyplanning.columns["id"].columnname = "编号";
dtfamilyplanning.columns["name"].columnname = "姓名";
dtfamilyplanning.columns["sex"].columnname = "性别";
//....表中其它信息不再细写
//新建datatabletoexcel类的对象
datatabletoexcel dttoexcel = new datatabletoexcel();
//导出数据到excel
dttoexcel.toexcel(dtfamilyplanning);
}
这个方法的实现过程很简单,直接在后台获取的是前台gridview显示的主键数据,相比前台传json数据相对简单了很多。
three
3. 除了这两种外还有更快速的方法,不需要重新查询数据库,而是直接从gridview中直接获得显示的数据,不好的地方就是如果数据多人操作,而且更新频繁,那直接从界面gridview获取数据可能就不是最新的数据。
复制代码 代码如下:
protected void export_click(object sender, eventargs e)
{
datatable dsexport = new datatable();
//循环获取gridview的每列,获取表头
for(int i=0;i<this.gridview.columns.count-1;i++)
{
//将表头信息添加到datatable表头
dsexport.columns.add(this.gridview.columns[i].headertext);
}
//循环gridview每行,查找checkbox被选中的行
foreach (gridviewrow msgrow in this.gridview.rows)
{
//通过id获得所需要遍历的checkbox
checkbox chk = (checkbox)msgrow.findcontrol("deletethis");
//判断checkbox是否被选中
if (chk.checked){
//定义datatable新行
system.data.datarow dr = dsexport.newrow();
for (int i = 0; i < msgrow.cells.count-1; i++)
{
//获取cells数据
dr[i] =msgrow.cells[i].text.tostring();
}
//添加新行到datatable
dsexport.rows.add(dr);
}
else
{
personalfiles.web.messageshow.messagebox.show(this, "请选择需要导出的信息!");
return;
}
}
//移除datatable中不需要的列
dsexport.columns.remove("选择");
dsexport.columns.remove("详细");
dsexport.columns.remove("编辑");
personalfiles.bll.datatabletoexcel dttoexcel = new personalfiles.bll.datatabletoexcel();
//导出数据到excel
dttoexcel.toexcel(dsexport);
}
三种方法上面写的很清楚了,各有优势,根据实际项目的要求去选,学习过程必然是需要多接触各种方法的实现,之前写过关于json的博客,就是没用过,这次一个机会,学会了一个用法,感觉爽呀,反复学习,不断积累的过程,heiheihei。
上一篇: JDBC环境设置(中文详解)
下一篇: Pycharm学习教程(2) 代码风格
推荐阅读