一个通用的DataGridView导出Excel扩展方法(支持列数据格式化)
假如数据库表中某个字段存放的值“1”和“0”分别代表“是”和“否”,要在DataGridView中显示“是”和“否”,一般用两种方法,一种是在sql中直接判断获取,另一种是在DataGridView的CellFormatting事件中设置。
下面介绍的是第二种情况下的处理。
举个例子,DataGridView的第4列需要在金额后面加个“元”,在第14列根据1和0显示为相应的是和否,在显示的时候可以这样设置:
private void dgData_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
{
if (e.ColumnIndex == 3)
{
if (e.Value != null)
e.Value = e.Value.ToString() + "元";
}
if (e.ColumnIndex == 13)
{
if (e.Value != null)
e.Value = e.Value.ToString() == "1" ? "是" : "否";
}
}
但是在循环行列导出Excel的时候并不会得到格式化后的数据,需要在循环列时判断是哪一列,再调用方法格式化列,如下:
private string FormatRMB(string s)
{
return s + "元";
}
private string FormatStatu(string s)
{
return s == "1" ? "已放款" : "未放款";
} private void ToExcel(int columnIndex, string fileName)
{
List<int> indexList = dgData.CheckBoxSelect(0);
if (indexList.Count == 0)
{
MessageBox.Show("请先选择!");
return;
}
using (SaveFileDialog saveFileDialog = new SaveFileDialog())
{
saveFileDialog.Title = "导出Excel文件到";
saveFileDialog.Filter = "Execl files(*.xls)|All Files(*.*)";
saveFileDialog.FileName = fileName;
saveFileDialog.AddExtension = true;
saveFileDialog.RestoreDirectory = true;
if (saveFileDialog.ShowDialog() == DialogResult.OK)
{
IWorkbook workbook = new HSSFWorkbook();
ISheet sheet = workbook.CreateSheet();
IRow rowTitle = sheet.CreateRow(0);
for (int j = columnIndex; j < dgData.Columns.Count; j++)
{
string headerText = dgData.Columns[j].HeaderText;
rowTitle.CreateCell(j - 1).SetCellValue(headerText);
}
for (int i = 0; i < indexList.Count; i++)
{
int selRowIndex = indexList[i];
IRow row = sheet.CreateRow(i + 1);
for (int j = columnIndex; j < dgData.Columns.Count; j++)
{
string val = dgData.Rows[selRowIndex].Cells[j].Value == null ? "" : dgData.Rows[selRowIndex].Cells[j].Value.ToString();
//格式化列数据
if (j == 3)
val = FormatRMB(val);
else if (j == 13)
val = FormatStatu(val); row.CreateCell(j - 1).SetCellValue(val);
}
}
FileStream outFs = new FileStream(saveFileDialog.FileName, FileMode.Create);
workbook.Write(outFs);
outFs.Close();
}
}
}
这里有一个缺点就是这个导出的方法失去了通用性,其它页面调用不了。
解决方法是在这个导出方法中再传一个字典参数,存放要格式化的列索引和委托,当循环到这一列时就执行这一个委托方法。
如下所示,现在已经是一个通用的方法,放在一个静态类中作为扩展方法,调用:
private void btnToExcel_Click(object sender, EventArgs e)
{
string fileName = string.Format("test_{0}.xls", DateTime.Now.ToString("yyyyMMddHHmmss"));
Dictionary<int, Func<string, string>> dict = new Dictionary<int, Func<string, string>>();
dict.Add(3, FormatRMB);
dict.Add(13, FormatStatu);
dgData.ExportExcel(1, fileName, dict);
}
//引用NPOI.dll
//using NPOI.SS.UserModel;
//using NPOI.HSSF.UserModel; public static class Extenstions
{
/// <summary>
/// Excel导出
/// </summary>
/// <param name="dgv">DataGridView控件ID</param>
/// <param name="columnIndex">从哪一列开始导出(因为有些列是checkbox)</param>
/// <param name="fileName">保存的文件名</param>
/// <param name="dict">存储列数据格式化的列号与方法字典</param>
public static void ExportExcel(this DataGridView dgv, int columnIndex, string fileName, Dictionary<int, Func<string, string>> dict)
{
List<int> indexList = dgv.CheckBoxSelect(0);
if (indexList.Count == 0)
{
MessageBox.Show("请先选择!");
return;
}
using (SaveFileDialog saveFileDialog = new SaveFileDialog())
{
saveFileDialog.Title = "导出Excel文件到";
saveFileDialog.Filter = "Execl files(*.xls)|All Files(*.*)";
saveFileDialog.FileName = fileName;
saveFileDialog.AddExtension = true;
saveFileDialog.RestoreDirectory = true;
if (saveFileDialog.ShowDialog() == DialogResult.OK)
{
IWorkbook workbook = new HSSFWorkbook();
ISheet sheet = workbook.CreateSheet();
IRow rowTitle = sheet.CreateRow(0);
for (int j = columnIndex; j < dgv.Columns.Count; j++)
{
string headerText = dgv.Columns[j].HeaderText;
rowTitle.CreateCell(j - 1).SetCellValue(headerText);
}
for (int i = 0; i < indexList.Count; i++)
{
int selRowIndex = indexList[i];
IRow row = sheet.CreateRow(i + 1);
for (int j = columnIndex; j < dgv.Columns.Count; j++)
{
string val = dgv.Rows[selRowIndex].Cells[j].Value == null ? "" : dgv.Rows[selRowIndex].Cells[j].Value.ToString();
//格式化列数据
if (dict.ContainsKey(j))
{
var v = dict.First(t => t.Key == j).Value;
val = v(val);
}
row.CreateCell(j - 1).SetCellValue(val);
}
}
FileStream outFs = new FileStream(saveFileDialog.FileName, FileMode.Create);
workbook.Write(outFs);
outFs.Close();
}
}
}
}
一个通用的DataGridView导出Excel扩展方法(支持列数据格式化)的更多相关文章
- asp.net中导出Excel的方法
一.asp.net中导出Excel的方法: 本文转载 在asp.net中导出Excel有两种方法,一种是将导出的文件存放在服务器某个文件夹下面,然后将文件地址输出在浏览器上:一种是将文件直接将文件输出 ...
- ASP.NET导出excel表方法汇总
asp.net里导出excel表方法汇总 1.由dataset生成 public void CreateExcel(DataSet ds,string typeid,string FileName) ...
- 懒人小工具:自动生成Model,Insert,Select,Delete以及导出Excel的方法
在开发的过程中,我们为了节约时间,往往会将大量重复机械的代码封装,考虑代码的复用性,这样我们可以节约很多时间来做别的事情.最近跳槽到一节webform开发的公司,主要是开发自己公司用的ERP.开始因为 ...
- 懒人小工具:T4自动生成Model,Insert,Select,Delete以及导出Excel的方法
之前写了篇文章,懒人小工具:[自动生成Model,Insert,Select,Delete以及导出Excel的方法](http://www.jianshu.com/p/d5b11589174a),但是 ...
- 懒人小工具:T4生成实体类Model,Insert,Select,Delete以及导出Excel的方法
由于最近公司在用webform开发ERP,用到大量重复机械的代码,之前写了篇文章,懒人小工具:自动生成Model,Insert,Select,Delete以及导出Excel的方法,但是有人觉得这种方法 ...
- 懒人小工具1:winform自动生成Model,Insert,Select,Delete以及导出Excel的方法
懒人小工具2:T4自动生成Model,Insert,Select,Delete以及导出Excel的方法 github地址:https://github.com/Jimmey-Jiang/J ...
- c# datagridview导出Excel文件 问题
今天vs2010c#开发做datagridview导出Excel文件时,发现一个问题,和大家探讨一下: 第一种方式:写流的方式 private void button_Excel_Click(obje ...
- 从DataGridView导出Excel
从DataGridView导出Excel的两种情况,不多说,直接记录代码(新建类,直接引用传入参数). using System; using System.Collections.Generic; ...
- Python学习随笔:使用xlwings设置和操作excel多行多列数据以及设置数据字体颜色填充色对齐方式的方法
☞ ░ 前往老猿Python博文目录 ░ 在前面老猿的文章中,<Python学习随笔:使用xlwings读取和操作Excel文件>.<Python学习随笔:使用xlwings读取和操 ...
随机推荐
- ubuntu下wine安装软件
安装wine 1. sudo apt-get install playonlinux playonlinux就是wine.或者在软件中心,搜索wine. 2. 在dash搜索playonlinux 安 ...
- C#中ref和out的使用与区别
C#中ref关键字和out关键字所实现的功能差不多,都是指定一个形参按照引用传递而不是实参的副本传递.但是二者适用场景还是有些区别的:out适合用在需要retrun多个返回值的地方,而ref则适合用在 ...
- 用apktool工具进行apk的编译和反编译
1.apktool下载安装 给一个2.0版的csdn地址:http://download.csdn.net/download/txj8612/7408775 下载后无需安装,直接解压缩,得到三个文件: ...
- keepalived工作原理和配置说明 腾讯云VPC内通过keepalived搭建高可用主备集群
keepalived工作原理和配置说明 腾讯云VPC内通过keepalived搭建高可用主备集群 内网路由都用mac地址 一个mac地址绑定多个ip一个网卡只能一个mac地址,而且mac地址无法改,但 ...
- XML转换为对象操作类详解
//XML转换为对象操作类 //一,XML与Object转换类 using System.IO; using System.Runtime.Serialization.Formatters.Binar ...
- 以一则LUA实例说明敏捷开发中“分离构造和使用”原则
分离构造和使用 构造含义是功能的实现, 此功能是一个定义明确的处理过程, 开放出明确的接口给调用者使用. 则使用者可以直接调用接口进行使用, 但是使用者需要搞清楚, 那些是构造, 那些是使用. 不要再 ...
- 使用pgstatspack分析PostgreSQL数据库性能
pgstatspack [root@test01 soft]# wget http://pgfoundry.org/frs/download.php/3151/pgstatspack_version_ ...
- 什么是Servlet?它有哪些特点
什么是Servlet? 它有哪些特点? Servlet是运行在JSP服务器端,用来生成Web页面的一种java程序 特点: (1)效率点 (2)功能强大 (3) Servlet之间能够共享数据 (4 ...
- IIS配置注意点
1.是否有权限 2.程序池是否为4.0集成 3.是否启用目录浏览模式:目录浏览==>启用(好像可以不用) 4.是否设置默认页面 5.其他的,百度. asp.net发布到IIS中出现错误:处理程序 ...
- mongo基本语句
批量更新 db.test.updateMany({name:'test'},{$set:{value:1}}) 单更新 db.test.update({name:'test'},{$set:{valu ...