C#中Excel的导入和导出的几种基本方式
在上一篇(http://www.cnblogs.com/fengchengjushi/p/3369386.html)介绍过,Excel也是数据持久化的一种实现方式。在C#中。我们常常会与Excel文件打交到。那么今天就讲讲在C#程序中操作Excel的问题。这里主要是导入和导出。
在页面中常常会遇到点击按钮实现GridView等控件的展示信息的下载,那么在程序中是如何实现数据下载的呢?其实简单的办法就是将这组规整的数据以Excel的方式保存到本地文件系统。我姑且称这种方式为"程序的方式"吧。
下面看具体代码实现:
/// <summary>
/// 程序的方式
/// </summary>
/// <param name="ctl"></param>
/// <param name="fileName"></param>
public static void ExportByApplication(System.Web.UI.Control ctl, string fileName)
{
string style = @"<style> .text { mso-number-format:\@; } </script> "; HttpContext.Current.Response.Charset = "UTF-8"; HttpContext.Current.Response.ContentEncoding = System.Text.Encoding.Default; HttpContext.Current.Response.ContentType = "application/ms-excel"; HttpContext.Current.Response.AppendHeader("Content-Disposition", "attachment;filename=" + "" + HttpUtility.UrlEncode(fileName, System.Text.Encoding.Default) + ".xls"); ctl.Page.EnableViewState = false; System.IO.StringWriter tw = new System.IO.StringWriter(); System.Web.UI.HtmlTextWriter hw = new System.Web.UI.HtmlTextWriter(tw); ctl.RenderControl(hw); HttpContext.Current.Response.Write(style); HttpContext.Current.Response.Write(tw.ToString()); HttpContext.Current.Response.End(); }
当我们把这个方法在Button点击按钮下调用的时候,我们运行页面会惊奇的发现,如下场景:

看到这里你是不是”惊呆了"也。呵呵,明明我的控件Gridview是放在了具有runat=server的form表单中的呀?其实你只需要重写VerifyRenderingInServerForm事件。代码如下:
public override void VerifyRenderingInServerForm(Control control)
{
// Confirms that an HtmlForm control is rendered for
}
这里介绍一种与到类似的解决办法,无需重写上面的事件,方法如下:
/// <summary>
/// 程序的方式
/// </summary>
/// <param name="page"></param>
/// <param name="table"></param>
/// <param name="FileName"></param>
public static void ExportByApplication(System.Web.UI.Page page, System.Data.DataTable table, string FileName)//整个GRIDVIEW导出到EXCEL.xls
{
FileName = HttpUtility.UrlEncode(FileName, System.Text.Encoding.UTF8);//解决导出时文件名汉字显示乱码的问题 HttpResponse resp;
resp = page.Response;
resp.ContentEncoding = System.Text.Encoding.GetEncoding("GB2312");
resp.AppendHeader("Content-Disposition", "attachment;filename=" + FileName);
string colHeaders = "", ls_item = ""; //定义表对象与行对象,同时用DataSet对其值进行初始化
System.Data.DataRow[] myRow = table.Select();//可以类似dt.Select("id>10")之形式达到数据筛选目的
int i = ;
int cl = table.Columns.Count; //取得数据表各列标题,各标题之间以t分割,最后一个列标题后加回车符
for (i = ; i < cl; i++)
{
if (i == (cl - ))//最后一列,加n
{
colHeaders += table.Columns[i].Caption.ToString() + "\n";
}
else
{
colHeaders += table.Columns[i].Caption.ToString() + "\t";
} }
resp.Write(colHeaders);
//向HTTP输出流中写入取得的数据信息 //逐行处理数据
foreach (DataRow row in myRow)
{
//当前行数据写入HTTP输出流,并且置空ls_item以便下行数据
for (i = ; i < cl; i++)
{
if (i == (cl - ))//最后一列,加n
{
ls_item += row[i].ToString() + "\n";
}
else
{
ls_item += row[i].ToString() + "\t";
} }
resp.Write(ls_item);
ls_item = ""; }
resp.End();
}
这两个种方式(当然类似的方法很多)都是通过写入HTTP 响应输出流的方式写入到本地文件系统。
我们知道Excel本来就是小型的数据库模型,我姑且称之为"Oledb"的方式,因此我们可以考虑通过数据访问的形式来实现上面的效果。首先要引入Microsoft.Office.Interop.Excel;
/// <summary>
/// Oledb的方式
/// </summary>
/// <param name="fileName">Excel文件名</param>
/// <param name="table">要导出的DataTable</param>
/// <param name="AddHeader">是否要增加表头</param>
public static void ExporExportByOledbtExcel(string fileName, System.Data.DataTable table, bool AddHeader)
{ object missing = System.Reflection.Missing.Value;
Microsoft.Office.Interop.Excel.Application app = new Microsoft.Office.Interop.Excel.Application();
app.Application.Workbooks.Add(true);
Microsoft.Office.Interop.Excel.Workbook book = (Microsoft.Office.Interop.Excel.Workbook)app.ActiveWorkbook;
Microsoft.Office.Interop.Excel.Worksheet sheet = (Microsoft.Office.Interop.Excel.Worksheet)book.ActiveSheet; if (AddHeader)
for (int i = ; i < table.Columns.Count; i++)
sheet.Cells[, i + ] = table.Columns[i].ColumnName; for (int i = , ei = AddHeader ? : ; i < table.Rows.Count; i++, ei++)
for (int j = ; j < table.Columns.Count; j++)
sheet.Cells[ei, j + ] = table.Rows[i][j]; string path = fileName.Substring(, fileName.LastIndexOf('\\') + ).Trim('\\');
if (!System.IO.Directory.Exists(path))
System.IO.Directory.CreateDirectory(path); book.SaveCopyAs(fileName);
//关闭文件
book.Close(false, missing, missing);
//退出excel
app.Quit();
}
以上是Excl的导出。
再来看Excel的导入
/// <summary>
/// 以Oledb的方式导入
/// </summary>
/// <param name="fileName">包含excel文件的完整路径</param>
/// <param name="sheetName">工作表名</param>
/// <returns></returns>
public static System.Data.DataTable ImportByOledb(string fileName, string sheetName)
{
System.Data.DataTable dt = new System.Data.DataTable(); using (OleDbConnection con = new OleDbConnection(@"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + fileName + ";Extended Properties=Excel 8.0"))
{
OleDbCommand cmd = new OleDbCommand("select * from [" + sheetName + "$]", con); OleDbDataAdapter oda = new OleDbDataAdapter(cmd); oda.Fill(dt);
} return dt; }
这里涉及到连接字符串问题,请看:
string strConn = @"Provider=Microsoft.Jet.OleDb.4.0;" + "data source=" + filePath + ";Extended Properties='Excel 8.0; HDR=Yes; IMEX=1'"; //此连接只能操作Excel2007之前(.xls)文件
string strCon = @"Provider=Microsoft.Ace.OleDb.12.0;" + "data source=" + fileName + ";Extended Properties='Excel 12.0; HDR=Yes; IMEX=1'"
对已不同的office版本,连接字符串也不同。
主意,当我们使用程序导出,然后通过Excel "Oledb"的方式导入的时候,会出现如下问题。且看:

这是程序导出时导致的非标准的excel文件的缘故,这个是程序导出的弊端。需要加以适当的处理。在导出的时候,这里由于时间原因,先介绍到这儿。
下面是我的ExcelOperation类:
/// <summary>
/// Excelde导入和导出
/// </summary>
public class ExcelOperation
{
#region 导出到Excel
/// <summary>
/// 程序的方式
/// </summary>
/// <param name="ctl"></param>
/// <param name="fileName"></param>
public static void ExportByApplication(System.Web.UI.Control ctl, string fileName)
{
string style = @"<style> .text { mso-number-format:\@; } </script> "; HttpContext.Current.Response.Charset = "UTF-8"; HttpContext.Current.Response.ContentEncoding = System.Text.Encoding.Default; HttpContext.Current.Response.ContentType = "application/ms-excel"; HttpContext.Current.Response.AppendHeader("Content-Disposition", "attachment;filename=" + "" + HttpUtility.UrlEncode(fileName, System.Text.Encoding.Default) + ".xls"); ctl.Page.EnableViewState = false; System.IO.StringWriter tw = new System.IO.StringWriter(); System.Web.UI.HtmlTextWriter hw = new System.Web.UI.HtmlTextWriter(tw); ctl.RenderControl(hw); HttpContext.Current.Response.Write(style); HttpContext.Current.Response.Write(tw.ToString()); HttpContext.Current.Response.End(); } /// <summary>
/// 程序的方式
/// </summary>
/// <param name="page"></param>
/// <param name="table"></param>
/// <param name="FileName"></param>
public static void ExportByApplication(System.Web.UI.Page page, System.Data.DataTable table, string FileName)//整个GRIDVIEW导出到EXCEL.xls
{
FileName = HttpUtility.UrlEncode(FileName, System.Text.Encoding.UTF8);//解决导出时文件名汉字显示乱码的问题 HttpResponse resp;
resp = page.Response;
resp.ContentEncoding = System.Text.Encoding.GetEncoding("GB2312");
resp.AppendHeader("Content-Disposition", "attachment;filename=" + FileName);
string colHeaders = "", ls_item = ""; //定义表对象与行对象,同时用DataSet对其值进行初始化
System.Data.DataRow[] myRow = table.Select();//可以类似dt.Select("id>10")之形式达到数据筛选目的
int i = ;
int cl = table.Columns.Count; //取得数据表各列标题,各标题之间以t分割,最后一个列标题后加回车符
for (i = ; i < cl; i++)
{
if (i == (cl - ))//最后一列,加n
{
colHeaders += table.Columns[i].Caption.ToString() + "\n";
}
else
{
colHeaders += table.Columns[i].Caption.ToString() + "\t";
} }
resp.Write(colHeaders);
//向HTTP输出流中写入取得的数据信息 //逐行处理数据
foreach (DataRow row in myRow)
{
//当前行数据写入HTTP输出流,并且置空ls_item以便下行数据
for (i = ; i < cl; i++)
{
if (i == (cl - ))//最后一列,加n
{
ls_item += row[i].ToString() + "\n";
}
else
{
ls_item += row[i].ToString() + "\t";
} }
resp.Write(ls_item);
ls_item = ""; }
resp.End();
} //////////////////////////////////鉴于程序的方是比较多我就介绍两个,其目的最终都是将数据集导出 /// <summary>
/// Oledb的方式
/// </summary>
/// <param name="fileName">Excel文件名</param>
/// <param name="table">要导出的DataTable</param>
/// <param name="AddHeader">是否要增加表头</param>
public static void ExporExportByOledbtExcel(string fileName, System.Data.DataTable table, bool AddHeader)
{ object missing = System.Reflection.Missing.Value;
Microsoft.Office.Interop.Excel.Application app = new Microsoft.Office.Interop.Excel.Application();
app.Application.Workbooks.Add(true);
Microsoft.Office.Interop.Excel.Workbook book = (Microsoft.Office.Interop.Excel.Workbook)app.ActiveWorkbook;
Microsoft.Office.Interop.Excel.Worksheet sheet = (Microsoft.Office.Interop.Excel.Worksheet)book.ActiveSheet; if (AddHeader)
for (int i = ; i < table.Columns.Count; i++)
sheet.Cells[, i + ] = table.Columns[i].ColumnName; for (int i = , ei = AddHeader ? : ; i < table.Rows.Count; i++, ei++)
for (int j = ; j < table.Columns.Count; j++)
sheet.Cells[ei, j + ] = table.Rows[i][j]; string path = fileName.Substring(, fileName.LastIndexOf('\\') + ).Trim('\\');
if (!System.IO.Directory.Exists(path))
System.IO.Directory.CreateDirectory(path); book.SaveCopyAs(fileName);
//关闭文件
book.Close(false, missing, missing);
//退出excel
app.Quit();
} #endregion #region 从Excel导入
/// <summary>
/// 以Oledb的方式导入
/// </summary>
/// <param name="fileName">包含excel文件的完整路径</param>
/// <param name="sheetName">工作表名</param>
/// <returns></returns>
public static System.Data.DataTable ImportByOledb(string fileName, string sheetName)
{
System.Data.DataTable dt = new System.Data.DataTable(); using (OleDbConnection con = new OleDbConnection(@"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + fileName + ";Extended Properties=Excel 8.0"))
{
OleDbCommand cmd = new OleDbCommand("select * from [" + sheetName + "$]", con); OleDbDataAdapter oda = new OleDbDataAdapter(cmd); oda.Fill(dt);
} return dt; }
#endregion
}
哈哈,时间有点晚了,菜鸟的我要睡觉了。准备明天悲哀的生活了。2012.10.16晚。
C#中Excel的导入和导出的几种基本方式的更多相关文章
- SpringBoot中关于Excel的导入和导出
前言 由于在最近的项目中使用Excel导入和导出较为频繁,以此篇博客作为记录,方便日后查阅.本文前台页面将使用layui,来演示对Excel文件导入和导出的效果.本文代码已上传至我的gitHub, ...
- excel的导入与导出---通用版
excel的导入与导出---通用版 web项目关于导入导出的业务场景很常见,最近我就又遇到了这个业务场景.这次将最近半个月做的导入导出总结一下 使用的pom如下,主要还是阿里巴巴的easyexcel依 ...
- .net数据库实现Excel的导入与导出
.net数据库实现Excel的导入与导出 参考路径:https://www.cnblogs.com/splendidme/archive/2012/01/05/2313314.html 1.defau ...
- 将Excel数据导入mysql数据库的几种方法
将Excel数据导入mysql数据库的几种方法 “我的面试感悟”有奖征文大赛结果揭晓! 前几天需要将Excel表格中的数据导入到mysql数据库中,在网上查了半天,研究了半天,总结出以下几种方法,下面 ...
- Java中使用poi导入、导出Excel
一.介绍 当前B/S模式已成为应用开发的主流,而在企业办公系统中,常常有客户这样子要求:你要把我们的报表直接用Excel打开(电信系统.银行系统).或者是:我们已经习惯用Excel打印.这样在我们实际 ...
- java 中Excel的导入导出
部分转发原作者https://www.cnblogs.com/qdhxhz/p/8137282.html雨点的名字 的内容 java代码中的导入导出 首先在d盘创建一个xlsx文件,然后再进行一系列 ...
- 前端必读:如何在 JavaScript 中使用SpreadJS导入和导出 Excel 文件
JavaScript在前端领域占据着绝对的统治地位,目前更是从浏览器到服务端,移动端,嵌入式,几乎所有的所有的应用领域都可以使用它.技术圈有一句很经典的话"凡是能用JavaScript实现的 ...
- 前端必读2.0:如何在React 中使用SpreadJS导入和导出 Excel 文件
最近我们公司接到一个客户的需求,要求为正在开发的项目加个功能.项目的前端使用的是React,客户想添加具备Excel 导入/导出功能的电子表格模块. 经过几个小时的原型构建后,技术团队确认所有客户需求 ...
- java实现Excel的导入、导出
一.Excel的导入 导入可采用两种方式,一种是JXL,另一种是POI,但前者不能读取高版本的Excel(07以上),后者更具兼容性.由于对两种方式都进行了尝试,就都贴出来分享(若有错误,请给予指正) ...
随机推荐
- 分析代码的利器 - ctags
比方我们在分析代码的时候,须要看某一个方法或类的定义,我们须要临时跳转过去看一下,然后还能非常方便的回来.这时候ctags就派上用场了. 比方你有一个src目录,先用ctags对其生成索引: ctag ...
- delphi 05 图片和超链接
超链接 /取消超链接 插入/取消 书签 插入图片 粘贴图上CTRL+v 截图 插入表情GIF WEB背景色 WEB背景图片 WebBrowser1.OleObject.document.ge ...
- js中substr与substring的差别
Js的substring和C#的Substring的作用都是从一个字符串中截取出一个子字符串,但它们的用法却有非常大的不同,下边我们来比較看看: Js的substring 语法: 程序代码 S ...
- [Ext JS 4] 实战之 带week(星期)的日期选择控件(三)
前言 在 [Ext JS 4] 实战之 带week(星期)的日期选择控件(二) 的最后,有提到一个解决方案. 不过这方案有一个条件 ==> “2. 每年的周数从(1-52), 如果超过52 周 ...
- mysql 5.1 到 mysql 5.2的出现的索引BTREE问题 use near 'USING BTREE
转自:http://hi.baidu.com/our_poll/item/669c5ce885b33ff1e0a5d4fc 我本机测试是安装的 mysql 5.1 , 但服务器上确是使用的 mysql ...
- 华为 真机当作测试机 打开log开关
拨号界面输入*#*#2846579#*#*进入测试模式,点击"pyojectmeu"-点击第三个-"后台设置"-进入了之后-点击第2个-"log设置& ...
- 分享一个jQuery动态网格布局插件:Masonry(转)
在线演示 Masonry是 一款非常强大的jQuery动态网格布局插件,可以帮助开发人员快速开发类似剪贴画的界面效果.和CSS中float的效果不太一样的地方在 于,float先水平排列,然后再垂直排 ...
- c++中的强制转换static_cast、dynamic_cast、reinterpret_cast的不同用法儿
c++中的强制转换static_cast.dynamic_cast.reinterpret_cast的不同用法儿 虽然const_cast是用来去除变量的const限定,但是static_cast ...
- mysql索引详解,摘自《MySQL 5权威指南》
本文介绍了数据库索引,及其优.缺点.针对MySQL索引的特点.应用进行了详细的描述.分析了如何避免MySQL无法使用,如何使用EXPLAIN分析查询语句,如何优化MySQL索引的应用.本文摘自< ...
- Wireshark抓包工具使用教程以及常用抓包规则
转载:http://fangxin.blog.51cto.com/1125131/735178 Wireshark是一个非常好用的抓包工具,当我们遇到一些和网络相关的问题时,可以通过这个工具进行分析, ...