Excel文件与DataSet之间的转化的探索与实现

.net操作Excel的支持库下载http://115.com/file/c2hkh144#NOPI.zip


以前用过依赖于office的方法对Excel文件进行操作,在自己机器上运行正常,到服务器上就不能运行。
这个问题困扰了我好久,终于找到了好的解决方法 。
使用不依赖于office的外部dll来操作Excel。。


首先,我自己建立的类,NpoiHelper,用来进行Excel与DataSet之间的转化,放于自己的类库Tools中
类的内容如下:

using System; using System.Collections.Generic; using System.Text; using System.IO; using NPOI.HSSF.UserModel; using System.Data; using System.Collections; namespace Tools { /// /// Excel文件到DataSet的转换类 /// public class NpoiHelper { #region 读取Excel文件内容转换为DataSet /// /// 读取Excel文件内容转换为DataSet,列名依次为 "c0"……c[columnlength-1] /// /// 文件绝对路径 /// 数据开始行数(1为第一行) /// 每列的数据类型 /// public static DataSet ReadExcel(string FileName, int startRow, params datatype[] ColumnDataType) { int ertime = 0; int intime = 0; DataSet ds = new DataSet("ds"); DataTable dt = new DataTable("dt"); DataRow dr; StringBuilder sb = new StringBuilder(); using (FileStream stream = new FileStream(@FileName, FileMode.Open, FileAccess.Read)) { HSSFWorkbook workbook = new HSSFWorkbook(stream); //整个Excel文件 HSSFSheet sheet = workbook.GetSheetAt(0); //得到里面第一个sheetint j; for (j = 0; j < ColumnDataType.Length; j++) dt.Columns.Add("c" + j, Type.GetType("System.String")); for (int i = startRow - 1; i <= sheet.LastRowNum; i++) { HSSFRow row = sheet.GetRow(i); //得到第i行 try { dr = dt.NewRow(); for (j = 0; j < ColumnDataType.Length; j++) dr["c" + j] = GetCellData(ColumnDataType[j], row, j).ToString(); dt.Rows.Add(dr); intime++; } catch (Exception er) { ertime++; sb.Append(string.Format("第{0}行出错:{1}\r\n", i + 1, er.Message)); continue; } } ds.Tables.Add(dt); } if (ds.Tables[0].Rows.Count == 0 && sb.ToString() != "") throw new Exception(sb.ToString()); return ds; } #endregion#region 从DataSet导出到MemoryStream流 /// /// 从DataSet导出到MemoryStream流 /// /// Excel文件中的Sheet名称 /// 存储数据的DataSet /// DataSet中的表头(数组形式) /// DataSet中的列名集合(数组形式) /// DataSet中的列名对应的数据类型(datatype枚举类)集合(数组形式) public static MemoryStream CreateExcel(string SheetName, DataSet ds, string[] columnNames, string[] HeaderNames, datatype[] datatypes) { try { HSSFWorkbook wb = new HSSFWorkbook(); HSSFSheet sheet = wb.CreateSheet(SheetName); HSSFRow row; HSSFCell cell; DataRow dr; int j; string column; object columnValue; #region 创建表头 row = sheet.CreateRow(0); //创建第i行 for (j = 0; j < columnNames.Length; j++) { column = columnNames[j]; columnValue = https://www.it610.com/article/HeaderNames[j]; try { cell = row.CreateCell(j); //创建第0行的第j列 try { cell.SetCellType(HSSFCell.CELL_TYPE_STRING); cell.SetCellValue(columnValue.ToString()); } catch { }} catch { continue; } } #endregion#region 创建每一行 for (int i = 0; i < ds.Tables[0].Rows.Count; i++) { dr = ds.Tables[0].Rows[i]; row = sheet.CreateRow(i + 1); //创建第i行 for (j = 0; j < columnNames.Length; j++) { column = columnNames[j]; columnValue = dr[column]; try { cell = row.CreateCell(j); //创建第i行的第j列 #region 插入第j列的数据 try { switch (datatypes[j]) { case datatype.String: { cell.SetCellType(HSSFCell.CELL_TYPE_STRING); cell.SetCellValue(columnValue.ToString()); } break; case datatype.Datetime: { cell.SetCellType(HSSFCell.CELL_TYPE_STRING); cell.SetCellValue(Convert.ToDateTime(columnValue)); } break; case datatype.Double: { cell.SetCellType(HSSFCell.CELL_TYPE_NUMERIC); cell.SetCellValue(Convert.ToDouble(columnValue)); } break; case datatype.Bool: { cell.SetCellType(HSSFCell.CELL_TYPE_BOOLEAN); cell.SetCellValue(Convert.ToBoolean(columnValue)); } break; case datatype.Richtext: { cell.SetCellType(HSSFCell.CELL_TYPE_FORMULA); cell.SetCellValue(columnValue.ToString()); } break; } } catch { cell.SetCellType(HSSFCell.CELL_TYPE_STRING); cell.SetCellValue(columnValue.ToString()); } #endregion} catch { continue; } } } #endregion//using (FileStream fs = new FileStream(@SaveFileName, FileMode.OpenOrCreate))//生成文件在服务器上 //{ //wb.Write(fs); //} using (MemoryStream ms = new MemoryStream()) { wb.Write(ms); return ms; } } catch (Exception er) { throw er; } } #endregion#region 得到不同数据类型单元格的数据 /// /// 得到不同数据类型单元格的数据 /// /// 数据类型 /// 数据中的一行 /// 哪列 /// public static object GetCellData(datatype datatype, HSSFRow row, int column) {switch (datatype) { case datatype.String: try { return row.GetCell(column).StringCellValue; } catch { return row.GetCell(column).NumericCellValue; } case datatype.Bool: try { return row.GetCell(column).BooleanCellValue; } catch { return row.GetCell(column).StringCellValue; } case datatype.Datetime: try { return row.GetCell(column).DateCellValue; } catch { return row.GetCell(column).StringCellValue; } case datatype.Double: try { return row.GetCell(column).NumericCellValue; } catch { return row.GetCell(column).StringCellValue; } case datatype.Richtext: try { return row.GetCell(column).RichStringCellValue; } catch { return row.GetCell(column).StringCellValue; } default: return ""; } } #endregion#region 枚举(单元格数据类型) /// /// 枚举(单元格数据类型) /// public enum datatype { /// /// String=1 /// String = 1, /// /// Bool=2 /// Bool=2, /// /// Datetime=3 /// Datetime=3, /// /// Double=4 /// Double=4, /// /// Richtext=5 /// Richtext=5 } #endregion } }




这样,就能操作Excel了,使用时只需要调用就行了。


友情提示:
使用时请注意:有些人分不清服务器对文件怎么操作的
在web应用程序里,客户端选择一个文件,就调用函数来转化为DataSet
这种情况,除非你直接在服务器的电脑上操作,否则操作不可能成功,服务器上没那个文件,你让他转化什么呢?
这个文件,肯定得在服务器上存在,可以先从客户端上传,再确定上传后的服务器路径,mappath一下,转化为全路径才可以操作


一、上面的可以将Excel导入到DataSet,操作DataSet应该不是我要说的内容问题了。呵呵
二、那么将DataSet保存到Excel,应该还要一个方法转化一下。上面的方法,只是把Excel保存为 MemoryStream内存流,方便转化成其它数据流的。
写一个方法将MemoryStream转化为Excel文件
1、asp.net网页的解决方法,保存到服务器的内存流中,再弹出给客户端下载 。

#region (asp.net网页中)二进制byte[] 导出到文件(文件要有正确的后缀) /// /// (asp.net网页中)二进制byte[] 导出到文件(文件要有正确的后缀) /// /// 页面,传 this /// 【Excel文件与DataSet之间的转化的探索与实现】文件的二进制数据 /// 导出的文件名(Excel:.xls) public static void BytesToFile(System.Web.UI.Page pg, byte[] bytes, string FileName) { pg.Response.Buffer = true; pg.Response.Clear(); pg.Response.ContentType = "application/download"; FileName = HttpUtility.UrlEncode(FileName, System.Text.Encoding.UTF8); pg.Response.AddHeader("Content-Disposition", "attachment; filename=" + FileName + "; "); pg.Response.BinaryWrite(bytes); pg.Response.Flush(); } #endregion

BytesToFile(this.Page,MemoryStream1.ToArray(),"文件1.xls");






2、winform中的解决方法直接保存:
FileStream SaveFile = new FileStream("file1.xls", FileMode.Create, FileAccess.ReadWrite); ms.WriteTo(SaveFile);




这样就保存到file1.xls中了。。





    推荐阅读