黑马程序员技术交流社区
标题:
数据库中的数据导出到Excel文件中(NPOI)(二)
[打印本页]
作者:
吴伟
时间:
2012-12-17 18:56
标题:
数据库中的数据导出到Excel文件中(NPOI)(二)
ExportDataToExcelFile函数:
public static void ExportDataToExcelFile<T>(string strFilePath, List<T> data)
where T : class
{
Type type = typeof(T);
//获取工作表的名称
string strSheetName = "sheet1";
if (type.IsDefined(typeof(ExcelSheetAttribute), false))
{
ExcelSheetAttribute obj=(ExcelSheetAttribute)type.GetCustomAttributes(typeof(ExcelSheetAttribute),false)[0];
strSheetName = obj.SheetName;
}
PropertyInfo[] props = type.GetProperties();
//获取每个属性上的列类型特性
List<CellType> celltypes = new List<CellType>();//表示列的类型信息的list
List<string> columnnames = new List<string>();//表示列的表头信息的list
foreach (var prop in props)
{
object[] attrs = prop.GetCustomAttributes(false);
foreach (var attr in attrs)
{
ExcelColumn ec = attr as ExcelColumn;
if (ec != null)
{
celltypes.Add(ec.ColumnType);
columnnames.Add(ec.ColumnName);
}
}
}
using (Workbook work = new HSSFWorkbook()) //创建工作簿
{
using (Sheet sheet = work.CreateSheet(strSheetName)) //创建表格
{
Row header = sheet.CreateRow(0);
for (int i = 0; i < columnnames.Count; i++)
{
header.CreateCell(i).SetCellValue(columnnames
);
}
for (int i = 1; i <= data.Count; i++)
{
Row row = sheet.CreateRow(i);
for (int j = 0; j < celltypes.Count; j++) //列数由拥有特性的属性个数决定,而不是属性个数,即类中没有标志ExcelColumn特性的属性不会写到文件中
{
Cell cell = row.CreateCell(j);
cell.SetCellType(celltypes[j]);
object value = props[j].GetValue(data[i-1], null);
if (value ==null)
{
continue;
}
cell.SetCellValue(value.ToString());
}
}
FileStream fs = File.OpenWrite(strFilePath);
work.Write(fs);
fs.Close();
}
}
}
说明:
引用了NPOI程序集后需要添加的两个命名空间:
using NPOI.HSSF.UserModel;
using NPOI.SS.UserModel;
整个函数可以大致分为两个部分。
第一部分是反射类型参数T的类型信息、属性信息,所有获得工作表的名称、表中每一列的数据类型和表头名称,其中两个List(celltypes、columnnames )是一一对应的关系,在后面for循环里面创建Cell对象设置值和类型的时候用下标j获得的是相对应的值;
第二部分是根据传递进来的data创建Excel文件并写入数据。首先,创建一个HSSFWorkbook对象,它代表着一个工作簿,即一个Excel文件;紧接着使用该对象创建一个HSSFSheet 对象,它代表了一个工作表(Sheet),这里的HSSFWorkbook和HSSFSheet分别是实现了Workbook和Sheet接口两个对象;其次,创建表头信息,将显示在表格的第一行;外部的for循环负责创建表格数据行,下标由data.count决定;内循环负责创建行中的每一个单元格并为之设定类型和值,循环下标由celltypes.Count决定,表示类中没有标志ExcelColumn特性的属性不会写到文件中;最后,根据文件路径打开文件流,写入数据,关闭文件流;
客户端代码:
string sql = @"SELECT TOP 1000 [stuId]
,[stuName]
,[stuSex]
,[stuBirthdate]
,[stuStudydate]
,[stuAddress]
,[stuEmail]
,[stuPhone]
FROM [TestDataBase].[dbo].[Student]";
List<StudentSheet> students=new List<StudentSheet>();
using (SqlDataReader reader = Common.SQLHelper.ExecuteDataReader(sql))
{
while (reader.Read())
{
StudentSheet student = new StudentSheet();
student.ID = Convert.ToInt32(reader[0]);
student.Name = reader[1].ToString();
student.Sex = reader[2].ToString();
student.Birthdate = reader[3].ToString();
student.Studydate = reader[4].ToString();
student.Address = reader[5].ToString();
student.Email = reader[6].ToString();
student.Telephone = reader[7].ToString();
students.Add(student);
}
}
Common.ExcelHelper.ExportDataToExcelFile<StudentSheet>("C:\1.xls", students);
MessageBox.Show("ok");
最后结果:
clipboard.png
(35.95 KB, 下载次数: 31)
下载附件
2012-12-17 18:56 上传
缺点:
对于大数据量的文件处理会非常蛮,测试了一个6万行数据的表格,一共也就十几m用了居然十几秒的时候,所以可以考虑使用多线程,其次大数据量对内存的消耗很大,这时候就需要使用DataReader来一条一条的读取和写入了!
作者:
许庭洲
时间:
2012-12-17 21:38
值得学习ing!
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/)
黑马程序员IT技术论坛 X3.2