在上一篇(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的导入和导出的几种基本方式的更多相关文章

  1. SpringBoot中关于Excel的导入和导出

    前言   由于在最近的项目中使用Excel导入和导出较为频繁,以此篇博客作为记录,方便日后查阅.本文前台页面将使用layui,来演示对Excel文件导入和导出的效果.本文代码已上传至我的gitHub, ...

  2. excel的导入与导出---通用版

    excel的导入与导出---通用版 web项目关于导入导出的业务场景很常见,最近我就又遇到了这个业务场景.这次将最近半个月做的导入导出总结一下 使用的pom如下,主要还是阿里巴巴的easyexcel依 ...

  3. .net数据库实现Excel的导入与导出

    .net数据库实现Excel的导入与导出 参考路径:https://www.cnblogs.com/splendidme/archive/2012/01/05/2313314.html 1.defau ...

  4. 将Excel数据导入mysql数据库的几种方法

    将Excel数据导入mysql数据库的几种方法 “我的面试感悟”有奖征文大赛结果揭晓! 前几天需要将Excel表格中的数据导入到mysql数据库中,在网上查了半天,研究了半天,总结出以下几种方法,下面 ...

  5. Java中使用poi导入、导出Excel

    一.介绍 当前B/S模式已成为应用开发的主流,而在企业办公系统中,常常有客户这样子要求:你要把我们的报表直接用Excel打开(电信系统.银行系统).或者是:我们已经习惯用Excel打印.这样在我们实际 ...

  6. java 中Excel的导入导出

    部分转发原作者https://www.cnblogs.com/qdhxhz/p/8137282.html雨点的名字  的内容 java代码中的导入导出 首先在d盘创建一个xlsx文件,然后再进行一系列 ...

  7. 前端必读:如何在 JavaScript 中使用SpreadJS导入和导出 Excel 文件

    JavaScript在前端领域占据着绝对的统治地位,目前更是从浏览器到服务端,移动端,嵌入式,几乎所有的所有的应用领域都可以使用它.技术圈有一句很经典的话"凡是能用JavaScript实现的 ...

  8. 前端必读2.0:如何在React 中使用SpreadJS导入和导出 Excel 文件

    最近我们公司接到一个客户的需求,要求为正在开发的项目加个功能.项目的前端使用的是React,客户想添加具备Excel 导入/导出功能的电子表格模块. 经过几个小时的原型构建后,技术团队确认所有客户需求 ...

  9. java实现Excel的导入、导出

    一.Excel的导入 导入可采用两种方式,一种是JXL,另一种是POI,但前者不能读取高版本的Excel(07以上),后者更具兼容性.由于对两种方式都进行了尝试,就都贴出来分享(若有错误,请给予指正) ...

随机推荐

  1. 【转】Android 4.4前后版本读取图库图片和拍照完美解决方案

    http://blog.csdn.net/zbjdsbj/article/details/42387551 4.3或以下,选了图片之后,根据Uri来做处理,很多帖子都有了,我就不详细说了.主要是4.4 ...

  2. Actions 动作集

    --> 移动鼠标到指定位置(先触发onMouseOver动作)        Actions action = new Actions(driver);        WebElement th ...

  3. 解决ArcGIS Engine AE 读取shapefile中文属性乱码的一条偏方

    最近写一个程序,AE+C#,读shp字段属性,其中读到中文就乱码了 这个问题比较奇怪,用AE很多年了,怎么突然就乱码呢,用Arcmap打开,没乱码,证明不是数据问题 网上搜搜,很多人说是许可初始化的问 ...

  4. 【M8】了解各种不同意义的new和delete

    1.首先考虑new operator,new operator 可以认为做了三件事情:a.调用operator new分配一块内存:b.在这块内存上调用构造方法构造对象:返回指针. 2.operato ...

  5. Codeforces Gym 100342J Problem J. Triatrip bitset 求三元环的数量

    Problem J. TriatripTime Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/gym/100342/att ...

  6. DWRUtil is not defined

    错误:DWRUtil is not defined; 解决方法: 先检查页面中是否正确引入uitl.js <script type="text/javascript" src ...

  7. android 多语言版本开发

    最近项目中用用到语言切换功能,第一想到的就是资源文件,没错. 在资源文件中新建一个文件夹values-en,en表示英语,有一些还细化到地区,如values-en-rUS 即美国地区的英语,r是必需的 ...

  8. Shell脚本调试工具set

    可以使用set命令的x选项,显示所有命令执行及变量值的变化过程等. 具体使用方法:首先使用set -x开启调试模式,最后使用命令set +x关闭调试模式. 一个简单示例演示如何使用set命令进行脚本调 ...

  9. hdu1051 Wooden Sticks

    题目:http://acm.hdu.edu.cn/showproblem.php?pid=1051 大意:求最少升序序列的个数. #include <cstdio> #include &l ...

  10. mysql查询更新时的锁表机制分析

    为了给高并发情况下的mysql进行更好的优化,有必要了解一下mysql查询更新时的锁表机制. 一.概述 MySQL有三种锁的级别:页级.表级.行级.MyISAM和MEMORY存储引擎采用的是表级锁(t ...