.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);//得到里面第一个sheet
int 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 = 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:.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);