c#开发数据导出为excel文件

我们经常需要将数据导出为excel文件。最常用的是导出datatable。另外就是导出list。目前一般excel操作常用NPOI开源组件,因为大家用过office com调用的都知道,其调用以及后期软件部署都要处理很多问题,相对比较麻烦。所以用NPOI来导出。

我自己在日常也用到导出,所以写了一个导出的类。exportListToExcel 是将list泛型对象导出为excel文件,但是返回的是byte[]。主要是为了方便asp.net输出。SetCellStyle函数是设置单元格样式。

另外既然是泛型,导出时需要动态获取值,经过网友比较动态DynamicMethod方法调用比直接反射取属性效率高,所以使用DynamicMethod这个类来取对象属性。后面又增加了datatable导出方法,附在后面,大同小异,datatable导出更简单。

public class ExportObjectsToExcel<T> where T : class
    {
        /// <summary>
        /// 导出列表对象到excel
        /// </summary>
        /// <param name="title">excel sheet title</param>
        /// <param name="columns">first row names to export</param>
        /// <param name="fields">property on object to export</param>
        /// <param name="list">object list to export</param>
        /// <returns>bytes content of excel file,can write out to xlsx excel file</returns>
        public byte[] exportListToExcel(string title, string[] columns, string[] fields, IList<T> list )
        {
            XSSFWorkbook workbookX = new XSSFWorkbook();
            
            ISheet sheet = workbookX.CreateSheet(title);
            ICellStyle cellStyle_14_Left = SetCellStyle(
                workbookX, 12,
                BorderStyle.Thin,
                HorizontalAlignment.Left,
                VerticalAlignment.Center
                ); //设计单元格格式

            int startRow = 0, startCol = 0;
            int fieldIndex = startCol + 0;
            IRow fieldRow = sheet.CreateRow(startRow++);
            fieldRow.Height = 400;
            for (int i = 0; i < columns.Length; i++)
            {
                string sColumnName = columns[i];
                ICell fieldCell = fieldRow.CreateCell(fieldIndex++);
                //列宽度
                sheet.SetColumnWidth(i, 13 * 256);
                if (i == columns.Length - 1)
                {
                    sheet.SetColumnWidth(i, 30 * 256);
                }
                //fieldCell.SetCellValue(sColumnName);
                //fieldCell.CellStyle = cellStyle_14_Left;
            }
            fieldRow = sheet.CreateRow(startRow++);
            fieldRow.Height = 400;
            fieldIndex = 0;
            for (int i = 0; i < columns.Length; i++)
            {
                string sColumnName = columns[i];
                ICell fieldCell = fieldRow.CreateCell(fieldIndex++);
                //列宽度
                sheet.SetColumnWidth(i, 40 * 256);
                if (i == columns.Length - 1)
                {
                    sheet.SetColumnWidth(i, 90 * 256);
                }
                fieldCell.SetCellValue(sColumnName);
                fieldCell.CellStyle = cellStyle_14_Left;
            }
            sheet.AddMergedRegion(new CellRangeAddress(0, 0, 0, columns.Length - 1));
            sheet.GetRow(0).GetCell(0).SetCellValue(title);
            sheet.GetRow(0).GetCell(0).CellStyle = cellStyle_14_Left;

            DynamicMethod<T> dynamicMethod = new DynamicMethod<T>();
            for (int i = 0; i < list.Count; i++)
            {
                IRow dataRow = sheet.CreateRow(startRow++);
                dataRow.Height = 400;
                for (int j = 0; j < fields.Length; j++)
                {
                    string fieldName = fields[j];
                    ICell newCell = dataRow.CreateCell(j);

                    object data1 = list[i];

                    object drValue = dynamicMethod.GetValue(data1, fieldName);
                    string DataType = "";
                    if (drValue!=null  )
                    {
                        DataType = drValue.GetType().ToString();
                    }
                    
                    switch (DataType)
                    {
                        case "System.String": //字符串类型
                            newCell.SetCellValue(TypeConvert.ToString(drValue));
                            newCell.CellStyle = cellStyle_14_Left; //格式化显示
                            break;
                        case "System.DateTime": //日期类型
                            DateTime dateV = TypeConvert.ToDateTime(drValue);

                            newCell.SetCellValue(dateV.ToString("yyyy-MM-dd"));

                            newCell.CellStyle = cellStyle_14_Left; //格式化显示
                            break;
                        case "System.Boolean": //布尔型
                            bool boolV = false;
                            bool.TryParse(TypeConvert.ToString(drValue), out boolV);
                            newCell.SetCellValue(boolV);
                            newCell.CellStyle = cellStyle_14_Left; //格式化显示
                            break;
                        case "System.Int16": //整型
                        case "System.Int32":
                        case "System.Int64":
                        case "System.Byte":
                            int intV = 0;
                            int.TryParse(TypeConvert.ToString(drValue), out intV);
                            TypeConvert.ToInt32(drValue);
                            newCell.SetCellValue(intV);
                            newCell.CellStyle = cellStyle_14_Left; //格式化显示
                            break;
                        case "System.Decimal": //浮点型
                        case "System.Double":
                            double doubV = 0;
                            double.TryParse(TypeConvert.ToString(drValue), out doubV);
                            newCell.SetCellValue(doubV.ToString("f6"));
                            newCell.CellStyle = cellStyle_14_Left; //格式化显示
                            break;
                        case "System.DBNull": //空值处理
                            newCell.SetCellValue("");
                            newCell.CellStyle = cellStyle_14_Left; //格式化显示
                            break;
                        default:
                            newCell.SetCellValue("");
                            newCell.CellStyle = cellStyle_14_Left; //格式化显示
                            break;
                    }
                }
            }

            MemoryStream stream = new System.IO.MemoryStream();
            workbookX.Write(stream);
            stream.Close();
            byte[] bytes=stream.ToArray();
            
            workbookX.Close();
            return bytes;
        }

private ICellStyle SetCellStyle(IWorkbook wk, int fontSize, BorderStyle borderStyle, HorizontalAlignment horAli, VerticalAlignment verAli)
        {
            ICellStyle cellStyle = wk.CreateCellStyle();
            //设置单元格上下左右边框线  
            cellStyle.BorderTop = borderStyle;
            cellStyle.BorderBottom = borderStyle;
            cellStyle.BorderLeft = borderStyle;
            cellStyle.BorderRight = borderStyle;
            //文字水平和垂直对齐方式  
            cellStyle.Alignment = horAli;
            cellStyle.VerticalAlignment = verAli;
            IFont font = wk.CreateFont();
            font.FontHeight = fontSize;
            cellStyle.SetFont(font);
            //是否换行  

            cellStyle.WrapText = true;  //自动换行
            //缩小字体填充  
            //cellStyle.ShrinkToFit = true; 
            return cellStyle;
        }
    }

    public class DynamicMethod<T>
    {
        internal static Func<object, string, object> GetValueDelegate;

        public object GetValue(object instance, string memberName)
        {
            return GetValueDelegate(instance, memberName);
        }

        static DynamicMethod()
        {
            GetValueDelegate = GenerateGetValue();
        }

        private static Func<object, string, object> GenerateGetValue()
        {
            var type = typeof(T);
            var instance = Expression.Parameter(typeof(object), "instance");
            var memberName = Expression.Parameter(typeof(string), "memberName");
            var nameHash = Expression.Variable(typeof(int), "nameHash");
            var calHash = Expression.Assign(nameHash, Expression.Call(memberName, typeof(object).GetMethod("GetHashCode")));
            var cases = new List<SwitchCase>();
            foreach (var propertyInfo in type.GetProperties())
            {
                var property = Expression.Property(Expression.Convert(instance, typeof(T)), propertyInfo.Name);
                var propertyHash = Expression.Constant(propertyInfo.Name.GetHashCode(), typeof(int));

                cases.Add(Expression.SwitchCase(Expression.Convert(property, typeof(object)), propertyHash));
            }
            var switchEx = Expression.Switch(nameHash, Expression.Constant(null), cases.ToArray());
            var methodBody = Expression.Block(typeof(object), new[] { nameHash }, calHash, switchEx);

            return Expression.Lambda<Func<object, string, object>>(methodBody, instance, memberName).Compile();
        }
    }

datatable的导出方法。

/// <summary>
        /// export datatable to excel file
        /// </summary>
        /// <param name="title">table title</param>
        /// <param name="dt">table</param>
        /// <param name="xlsFileName">export file name xlsx</param>
        public void exportDataTable(string title, DataTable dt, string xlsFileName)
        {
            string fileName = xlsFileName;
            if (fileName.ToLower().EndsWith(".xls"))
            {
                fileName = fileName + "x";
            }
            XSSFWorkbook workbookX = new XSSFWorkbook();

            FileStream stream = File.Create(fileName);
            {
                ISheet sheet = workbookX.CreateSheet(title);
                ICellStyle cellStyle_14_Left = SetCellStyle(
                    workbookX, 12,
                    BorderStyle.Thin,
                    HorizontalAlignment.Left,
                    VerticalAlignment.Center
                    ); //设计单元格格式

                int startRow = 0, startCol = 0;
                int fieldIndex = startCol + 0;
                IRow fieldRow = sheet.CreateRow(startRow++);
                fieldRow.Height = 400;
                for (int i = 0; i < dt.Columns.Count; i++)
                {
                    string sColumnName = dt.Columns[i].ColumnName;
                    ICell fieldCell = fieldRow.CreateCell(fieldIndex++);
                    //列宽度
                    sheet.SetColumnWidth(i, 13 * 256);
                    if (i == dt.Columns.Count - 1)
                    {
                        sheet.SetColumnWidth(i, 30 * 256);
                    }
                    //fieldCell.SetCellValue(sColumnName);
                    //fieldCell.CellStyle = cellStyle_14_Left;
                }
                fieldRow = sheet.CreateRow(startRow++);
                fieldRow.Height = 400;
                fieldIndex = 0;
                for (int i = 0; i < dt.Columns.Count; i++)
                {
                    string sColumnName = dt.Columns[i].ColumnName;
                    ICell fieldCell = fieldRow.CreateCell(fieldIndex++);
                    //列宽度
                    sheet.SetColumnWidth(i, 13 * 256);
                    if (i == dt.Columns.Count - 1)
                    {
                        sheet.SetColumnWidth(i, 30 * 256);
                    }
                    fieldCell.SetCellValue(sColumnName);
                    fieldCell.CellStyle = cellStyle_14_Left;
                }
                sheet.AddMergedRegion(new CellRangeAddress(0, 0, 0, dt.Columns.Count - 1));
                sheet.GetRow(0).GetCell(0).SetCellValue(title);
                sheet.GetRow(0).GetCell(0).CellStyle = cellStyle_14_Left;
                for (int i = 0; i < dt.Rows.Count; i++)
                {
                    IRow dataRow = sheet.CreateRow(startRow++);
                    dataRow.Height = 400;
                    foreach (DataColumn column in dt.Columns)
                    {
                        ICell newCell = dataRow.CreateCell(column.Ordinal);

                        DataRow row = dt.Rows[i];

                        string drValue = TypeConvert.ToString(row[column]);

                        switch (column.DataType.ToString())
                        {
                            case "System.String": //字符串类型
                                newCell.SetCellValue(drValue);
                                newCell.CellStyle = cellStyle_14_Left; //格式化显示
                                break;
                            case "System.DateTime": //日期类型
                                DateTime dateV = TypeConvert.ToDateTime(row[column]);

                                newCell.SetCellValue(dateV.ToString("yyyy-MM-dd"));

                                newCell.CellStyle = cellStyle_14_Left; //格式化显示
                                break;
                            case "System.Boolean": //布尔型
                                bool boolV = false;
                                bool.TryParse(drValue, out boolV);
                                newCell.SetCellValue(boolV);
                                newCell.CellStyle = cellStyle_14_Left; //格式化显示
                                break;
                            case "System.Int16": //整型
                            case "System.Int32":
                            case "System.Int64":
                            case "System.Byte":
                                int intV = 0;
                                int.TryParse(drValue, out intV);
                                TypeConvert.ToInt32(drValue);
                                newCell.SetCellValue(intV);
                                newCell.CellStyle = cellStyle_14_Left; //格式化显示
                                break;
                            case "System.Decimal": //浮点型
                            case "System.Double":
                                double doubV = 0;
                                double.TryParse(drValue, out doubV);
                                newCell.SetCellValue(doubV.ToString("f6"));
                                newCell.CellStyle = cellStyle_14_Left; //格式化显示
                                break;
                            case "System.DBNull": //空值处理
                                newCell.SetCellValue("");
                                newCell.CellStyle = cellStyle_14_Left; //格式化显示
                                break;
                            default:
                                newCell.SetCellValue("");
                                newCell.CellStyle = cellStyle_14_Left; //格式化显示
                                break;
                        }
                    }
                }
            }
            workbookX.Write(stream);
            stream.Close();
            workbookX.Close();
        }



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值