在上一篇(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. 发现一个不错的十六进制编辑器-HxD

    十六进制编辑器我觉得是个必需的工具,遥想当年用文曲星的时候,Pacmanager.Ewayeditor…… 之前都在用WinHex,好用,但是是个收费软件,老用着破解版心里还是不舒服 后来发现这个名叫 ...

  2. PI-利用SoapUI 测试web service的方法介绍

    在运用webservice调用数据的过程中,非常关键的一个步骤就是获取到webservice的地址,并测试webservice的连通情 况,webservice的连通测试主要是两个方面:1,查看web ...

  3. Educational Codeforces Round 2 B. Queries about less or equal elements 水题

    B. Queries about less or equal elements Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforc ...

  4. Codeforces Gym 100610 Problem A. Alien Communication Masterclass 构造

    Problem A. Alien Communication Masterclass Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://codefo ...

  5. iOS开发——UI篇&文字渐变效果:图层中的mask属性

    文字渐变效果:图层中的mask属性 本次文章,主要讲述的是图层中的mask属性,利用它,可以做出文字渐变效果! 一.文字渐变效果: 二.文字渐变实现思路: 1.创建一个颜色渐变层,渐变图层跟文字控件一 ...

  6. pt-online-schema-change使用说明、限制与比较

    http://seanlook.com/2016/05/27/mysql-pt-online-schema-change/ http://blog.itpub.net/22664653/viewspa ...

  7. MYSQL SQL 审核工具 (inception安装步骤)

    http://blog.csdn.net/wulantian/article/category/5825391

  8. Spark on Yarn遇到的问题及解决思路

    原文:http://www.aboutyun.com/thread-9425-1-1.html 问题导读1.Connection Refused可能原因是什么?2.如何判断内存溢出,该如何解决?扩展: ...

  9. Hive中数据的加载和导出

    原文:http://blog.javachen.com/2014/06/09/hive-data-manipulation-language.html 关于 Hive DML 语法,你可以参考 apa ...

  10. Linux解压/压缩命令——tar、gz、tar.gz、tgz、bz2、tar.bz2、Z、zip、rar、lha

    .tar 解包:tar -xvf FileName.tar 打包:tar -cvf FileName.tar DirName ——————————————— .gz 解压1:gunzip FileNa ...