在上一篇(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. 关于DateTime.Now.Ticks

    DataTime.Now.Ticks 的值表示自 0001 年 1 月 1 日午夜 12:00:00 以来所经历的以 100 纳秒为间隔的间隔数,可用于较精确的计时. 1秒=1000豪秒 1毫秒=10 ...

  2. Hibernate中的session对象update方法的使用

    使一个游离对象转变为持久化对象.例如以下代码在session1中保存了一个Customer对象,然后在session2中更新这个Customer对象: Customer customer = new ...

  3. Codeforces Gym 100286B Blind Walk DFS

    Problem B. Blind WalkTime Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://acm.hust.edu.cn/vjudge/cont ...

  4. 4.Maven概念模型,maven的生命周期,Maven坐标,依赖管理(依赖范围,依赖声明),仓库管理,私服概念

     1 maven概念模型 2 maven的生命周期,项目构建过程 watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdG90b3R1enVvcXVhbg== ...

  5. Android系统启动过程全解析

    Android系统是一款基于Linux的移动操作系统,那么Android是如何启动起来的呢?本文就详细阐述Android系统的启动过程. 从内核之上,我们首先应该从文件系统的init开始,因为 ini ...

  6. Android内存优化解决 资料和总结的经验分享

    在前公司做一个图片处理的应用时, 项目交付的时候,客户的手机在运行应用的时候,一直在崩溃,而这个异常就是OutOfMemory的错误,简称为OOM, 搞得我们也是极其的崩溃,最后 ,我们是通过网上搜集 ...

  7. 探讨一个新的两个进程间的通信和编程模型 (Windows)

    本文探讨一个新的Windows上的两个UI进程间的通信和编程模型. 开门见山,下面是这个通信模型的梗概图: 这个模型的设计目标描述如下: (1)发送数据接口:RpcSend, RpcPost RpcS ...

  8. Java log code example

    Java log example Logrecord filter import java.util.logging.Filter; import java.util.logging.Level; i ...

  9. ios--uitextfield动态限制输入的字数(解决方式)

    1.定义一个事件: -(IBAction)limitLength:(UITextField *)sender { bool isChinese;//推断当前输入法是否是中文 if ([[[UIText ...

  10. 获取文件属性信息之stat、fstat和lstat

    UNIX文件系统是目录和文件组成的一种层次结构.目录(directory)是一个包含许多目录项的文件,在逻辑上,可以认为每个目录项都包含一个文件名,同时还包含说明该文件属性的信息.文件属性是指文件类型 ...