A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始


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");

最后结果:



缺点:
    对于大数据量的文件处理会非常蛮,测试了一个6万行数据的表格,一共也就十几m用了居然十几秒的时候,所以可以考虑使用多线程,其次大数据量对内存的消耗很大,这时候就需要使用DataReader来一条一条的读取和写入了!

评分

参与人数 1技术分 +1 收起 理由
宋天琪 + 1

查看全部评分

1 个回复

倒序浏览
值得学习ing!
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马