• 导出数据EPPlus


    前言

      导出数据在管理系统中经常要用到,目前的Excel导出工具多种多样,如:NPOI、EPPlus等……本篇使用的是EPPlus,记录下在工作中用到的导入导出类,以便后面使用

    代码

      导出

    public class Export2Excel
        {
            /// <summary>
            /// 生成excel
            /// </summary>
            /// <param name="dtSource">数据源</param>
            /// <param name="title">标题(Sheet名)</param>
            /// <param name="showTitle">是否显示</param>
            /// <returns></returns>
            public static MemoryStream Export(DataTable dtSource, string title, bool showTitle = true)
            {
                using (ExcelPackage package = new ExcelPackage())
                {
                    ExcelWorksheet workSheet = package.Workbook.Worksheets.Add(title);
    
                    int maxColumnCount = dtSource.Columns.Count;
                    int curRowIndex = 0;
    
                    if (showTitle == true)
                    {
                        curRowIndex++;
                        //主题
                        workSheet.Cells[curRowIndex, 1, 1, maxColumnCount].Merge = true;
                        workSheet.Cells[curRowIndex, 1].Value = title;
                        var headerStyle = workSheet.Workbook.Styles.CreateNamedStyle("headerStyle");
                        headerStyle.Style.HorizontalAlignment = ExcelHorizontalAlignment.Center;
                        headerStyle.Style.Font.Bold = true;
                        headerStyle.Style.Font.Size = 20;
                        workSheet.Cells[curRowIndex, 1].StyleName = "headerStyle";
    
                        curRowIndex++;
                        //导出时间栏
                        workSheet.Cells[curRowIndex, 1, 2, maxColumnCount].Merge = true;
                        workSheet.Cells[curRowIndex, 1].Value = "导出时间:" + DateTime.Now.ToString("yyyy-MM-dd HH:mm");
                        workSheet.Cells[curRowIndex, 1].Style.HorizontalAlignment = ExcelHorizontalAlignment.Right;
                    }
    
                    curRowIndex++;
                    var titleStyle = workSheet.Workbook.Styles.CreateNamedStyle("titleStyle");
                    titleStyle.Style.HorizontalAlignment = ExcelHorizontalAlignment.Center;
                    titleStyle.Style.Font.Bold = true;
                    //标题
                    for (var i = 0; i < maxColumnCount; i++)
                    {
                        DataColumn column = dtSource.Columns[i];
                        workSheet.Cells[curRowIndex, i + 1].Value = column.ColumnName;
                        workSheet.Cells[curRowIndex, i + 1].StyleName = "titleStyle";
                    }
                    workSheet.View.FreezePanes(curRowIndex, 1);//冻结标题行
    
                    //内容
                    for (var i = 0; i < dtSource.Rows.Count; i++)
                    {
                        curRowIndex++;
                        for (var j = 0; j < maxColumnCount; j++)
                        {
                            DataColumn column = dtSource.Columns[j];
                            var row = dtSource.Rows[i];
                            object value = row[column];
                            var cell = workSheet.Cells[curRowIndex, j + 1];
                            var pType = column.DataType;
                            pType = pType.Name == "Nullable`1" ? Nullable.GetUnderlyingType(pType) : pType;
                            if (pType == typeof(DateTime))
                            {
                                cell.Style.Numberformat.Format = "yyyy-MM-dd hh:mm";
                                cell.Value = Convert.ToDateTime(value);
                            }
                            else if (pType == typeof(int))
                            {
                                cell.Value = Convert.ToInt32(value);
                            }
                            else if (pType == typeof(double) || pType == typeof(decimal))
                            {
                                cell.Value = Convert.ToDouble(value);
                            }
                            else
                            {
                                cell.Value = value == null ? "" : value.ToString();
                            }
                            workSheet.Cells[curRowIndex, j + 1].Value = row[column].ToString();
                        }
                    }
                    workSheet.Cells[workSheet.Dimension.Address].Style.Font.Name = "宋体";
                    workSheet.Cells[workSheet.Dimension.Address].AutoFitColumns();//自动填充
                    for (var i = 1; i <= workSheet.Dimension.End.Column; i++) { workSheet.Column(i).Width = workSheet.Column(i).Width + 2; }//在填充的基础上再加2
                    MemoryStream ms = new MemoryStream(package.GetAsByteArray());
                    return ms;
                }
            }
    
            /// <summary>
            /// 生成excel
            /// </summary>
            /// <typeparam name="T"></typeparam>
            /// <param name="dtSource">数据源</param>
            /// <param name="columns">导出字段表头合集</param>
            /// <param name="title">标题(Sheet名)</param>
            /// <param name="showTitle">是否显示标题</param>
            /// <returns></returns>
            public static byte[] Export<T>(IList<T> dtSource, ExportColumnCollective columns, string title, bool showTitle = true)
            {
                using (ExcelPackage package = new ExcelPackage())
                {
                    ExcelWorksheet workSheet = package.Workbook.Worksheets.Add(title);
    
                    int maxColumnCount = columns.ExportColumnList.Count;
                    int curRowIndex = 0;
    
                    //Excel标题
                    if (showTitle == true)
                    {
                        curRowIndex++;
                        workSheet.Cells[curRowIndex, 1, 1, maxColumnCount].Merge = true;
                        workSheet.Cells[curRowIndex, 1].Value = title;
                        var headerStyle = workSheet.Workbook.Styles.CreateNamedStyle("headerStyle");
                        headerStyle.Style.HorizontalAlignment = ExcelHorizontalAlignment.Center;
                        headerStyle.Style.Font.Bold = true;
                        headerStyle.Style.Font.Size = 20;
                        workSheet.Cells[curRowIndex, 1].StyleName = "headerStyle";
    
                        curRowIndex++;
                        //导出时间
                        workSheet.Cells[curRowIndex, 1, 2, maxColumnCount].Merge = true;
                        workSheet.Cells[curRowIndex, 1].Value = "导出时间:" + DateTime.Now.ToString("yyyy-MM-dd HH:mm");
                        workSheet.Cells[curRowIndex, 1].Style.HorizontalAlignment = ExcelHorizontalAlignment.Right;
                    }
    
                    //数据表格标题(列名)
                    for (int i = 0, rowCount = columns.HeaderExportColumnList.Count; i < rowCount; i++)
                    {
                        curRowIndex++;
                        workSheet.Cells[curRowIndex, 1, curRowIndex, maxColumnCount].Style.Font.Bold = true;
                        var curColSpan = 1;
                        for (int j = 0, colCount = columns.HeaderExportColumnList[i].Count; j < colCount; j++)
                        {
                            var colColumn = columns.HeaderExportColumnList[i][j];
                            var colSpan = FindSpaceCol(workSheet, curRowIndex, curColSpan);
                            if (j == 0) curColSpan = colSpan;
                            var toColSpan = colSpan + colColumn.ColSpan;
                            var cell = workSheet.Cells[curRowIndex, colSpan, colColumn.RowSpan + curRowIndex, toColSpan];
                            cell.Merge = true;
                            cell.Style.VerticalAlignment = ExcelVerticalAlignment.Center;
                            cell.Style.HorizontalAlignment = ExcelHorizontalAlignment.Center;
                            workSheet.Cells[curRowIndex, colSpan].Value = colColumn.Title;
                            curColSpan += colColumn.ColSpan;
                        }
                    }
                    workSheet.View.FreezePanes(curRowIndex + 1, 1);//冻结标题行
    
                    Type type = typeof(T);
                    PropertyInfo[] propertyInfos = type.GetProperties();
                    if (propertyInfos.Count() == 0 && dtSource.Count > 0) propertyInfos = dtSource[0].GetType().GetProperties();
    
                    //数据行
                    for (int i = 0, sourceCount = dtSource.Count(); i < sourceCount; i++)
                    {
                        curRowIndex++;
                        for (var j = 0; j < maxColumnCount; j++)
                        {
                            var column = columns.ExportColumnList[j];
                            var cell = workSheet.Cells[curRowIndex, j + 1];
                            foreach (var propertyInfo in propertyInfos)
                            {
                                if (column.Field == propertyInfo.Name)
                                {
                                    object value = propertyInfo.GetValue(dtSource[i]);
                                    var pType = propertyInfo.PropertyType;
                                    pType = pType.Name == "Nullable`1" ? Nullable.GetUnderlyingType(pType) : pType;
                                    if (pType == typeof(DateTime))
                                    {
                                        cell.Style.Numberformat.Format = "yyyy-MM-dd hh:mm";
                                        cell.Value = Convert.ToDateTime(value);
                                    }
                                    else if (pType == typeof(int))
                                    {
                                        cell.Style.Numberformat.Format = "#0";
                                        cell.Value = Convert.ToInt32(value);
                                    }
                                    else if (pType == typeof(double) || pType == typeof(decimal))
                                    {
                                        if (column.Precision != null) cell.Style.Numberformat.Format = "#,##0.00";//保留两位小数
    
                                        cell.Value = Convert.ToDouble(value);
                                    }
                                    else
                                    {
                                        cell.Value = value == null ? "" : value.ToString();
                                    }
                                }
                            }
                        }
                    }
                    workSheet.Cells[workSheet.Dimension.Address].Style.Font.Name = "宋体";
                    workSheet.Cells[workSheet.Dimension.Address].AutoFitColumns();//自动填充
                    for (var i = 1; i <= workSheet.Dimension.End.Column; i++) { workSheet.Column(i).Width = workSheet.Column(i).Width + 2; }//在填充的基础上再加2
    
                    return package.GetAsByteArray();
                }
            }
    
            private static int FindSpaceCol(ExcelWorksheet workSheet, int row, int col)
            {
                if (workSheet.Cells[row, col].Merge)
                {
                    return FindSpaceCol(workSheet, row, col + 1);
                }
                return col;
            }
        }
        public class ExportColumnCollective
        {
            /// <summary>
            /// 字段列集合
            /// </summary>
            public List<ExportColumn> ExportColumnList { get; set; }
            /// <summary>
            /// 表头或多表头集合
            /// </summary>
            public List<List<ExportColumn>> HeaderExportColumnList { get; set; }
        }
        public class ExportColumn
        {
    
            /// <summary>
            /// 标题
            /// </summary>
            [JsonProperty("title")]
            public string Title { get; set; }
            /// <summary>
            /// 字段
            /// </summary>
            [JsonProperty("field")]
            public string Field { get; set; }
            /// <summary>
            /// 精度(只对double、decimal有效)
            /// </summary>
            [JsonProperty("precision")]
            public int? Precision { get; set; }
            /// <summary>
            /// 跨列
            /// </summary>
            [JsonProperty("colSpan")]
            public int ColSpan { get; set; }
            /// <summary>
            /// 跨行
            /// </summary>
            [JsonProperty("rowSpan")]
            public int RowSpan { get; set; }
        }

      导入

    public class Import2Excel<T> where T : XlsRow, new()
        {
            private List<XlsEntity> xlsHeader = new List<XlsEntity>();
    
            #region 初始化转换形式
            public void ForMember(Expression<Func<T, object>> entityExpression, Func<string, object> func)
            {
                XlsEntity xlsEntity = new XlsEntity();
                xlsEntity.EntityName = GetPropertyName(entityExpression);
                xlsEntity.ColumnName = xlsEntity.EntityName;
                xlsEntity.ConvertFunc = func;
                xlsHeader.Add(xlsEntity);
            }
            public void ForMember(string columnName, Expression<Func<T, object>> entityExpression)
            {
                XlsEntity xlsEntity = new XlsEntity();
                xlsEntity.ColumnName = columnName;
                xlsEntity.EntityName = GetPropertyName(entityExpression);
                xlsHeader.Add(xlsEntity);
            }
            public void ForMember(string columnName, string entityName)
            {
                XlsEntity xlsEntity = new XlsEntity();
                xlsEntity.ColumnName = columnName;
                xlsEntity.EntityName = entityName;
                xlsHeader.Add(xlsEntity);
            }
            public void ForMember(string columnName, string entityName, Func<string, object> func)
            {
                XlsEntity xlsEntity = new XlsEntity();
                xlsEntity.ColumnName = columnName;
                xlsEntity.EntityName = entityName;
                xlsEntity.ConvertFunc = func;
                xlsHeader.Add(xlsEntity);
            }
            public void ForMember(string columnName, Expression<Func<T, object>> entityExpression, Func<string, object> func)
            {
                XlsEntity xlsEntity = new XlsEntity();
                xlsEntity.ColumnName = columnName;
                xlsEntity.EntityName = GetPropertyName(entityExpression);
                xlsEntity.ConvertFunc = func;
                xlsHeader.Add(xlsEntity);
            }
            #endregion
    
            /// <summary>
            /// Excel文件流加载到内存
            /// </summary>
            /// <param name="ExcelFileStream">文件流</param>
            /// <param name="SheetIndex">加载页码</param>
            /// <returns></returns>
            public List<T> LoadFromExcel(Stream ExcelFileStream, int SheetIndex = 0)
            {
                List<T> resultList = new List<T>();
    
                using (ExcelPackage package = new ExcelPackage(ExcelFileStream))
                {
                    ExcelWorksheet worksheet = package.Workbook.Worksheets[SheetIndex];//选定 指定页
    
                    int colStart = worksheet.Dimension.Start.Column;
                    int colEnd = worksheet.Dimension.End.Column;
                    int rowStart = worksheet.Dimension.Start.Row;
                    int rowEnd = worksheet.Dimension.End.Row;
    
                    PropertyInfo[] propertyInfoList = typeof(T).GetProperties();
                    XlsEntity xlsEntity;
    
                    #region 将实体和excel列标题进行对应绑定,添加到集合中
    
                    for (int i = colStart; i <= colEnd; i++)
                    {
                        string columnName = worksheet.Cells[rowStart, i].Value.ToString();
    
                        xlsEntity = xlsHeader.FirstOrDefault(e => e.ColumnName == columnName);
    
                        for (int j = 0; j < propertyInfoList.Length; j++)
                        {
                            if (xlsEntity != null && xlsEntity.ColumnName == columnName)
                            {
                                xlsEntity.ColumnIndex = i;
                                xlsHeader.Add(xlsEntity);
                            }
                            else if (propertyInfoList[j].Name == columnName)
                            {
                                xlsEntity = new XlsEntity();
                                xlsEntity.ColumnName = columnName;
                                xlsEntity.EntityName = propertyInfoList[j].Name;
                                xlsEntity.ColumnIndex = i;
                                xlsHeader.Add(xlsEntity);
                                break;
                            }
                        }
                    }
                    #endregion
    
                    #region 根据对应的实体名列名的对应绑定就行值的绑定
    
                    for (int row = rowStart + 1; row <= rowEnd; row++)
                    {
                        T result = new T();
                        foreach (PropertyInfo p in propertyInfoList)
                        {
                            var xlsRow = xlsHeader.FirstOrDefault(e => e.EntityName == p.Name);
                            if (xlsRow == null || xlsRow?.ColumnIndex == 0) continue;
    
                            ExcelRange cell = worksheet.Cells[row, xlsRow.ColumnIndex];
                            if (cell.Value == null) continue;
    
                            try
                            {
                                if (xlsRow.ConvertFunc != null)
                                {
                                    object entityValue = xlsRow.ConvertFunc(cell.Value.ToString());
                                    p.SetValue(result, entityValue);
                                }
                                else
                                {
                                    cellBindValue(result, p, cell);
                                }
                            }
                            catch (Exception ex)
                            {
                                if (result.ErrColumn == null) result.ErrColumn = new List<string>();
                                if (result.ErrMessage == null) result.ErrMessage = new List<string>();
                                if (result.ErrValue == null) result.ErrValue = new List<string>();
                                result.ErrColumn.Add(p.Name);
                                result.ErrMessage.Add(ex.Message);
                                result.ErrValue.Add(cell.Value.ToString());
                                result.IsErr = true;
                            }
                        }
                        resultList.Add(result);
                    }
                    #endregion
                }
                return resultList;
            }
    
            private static void cellBindValue(T result, PropertyInfo p, ExcelRange cell)
            {
                switch (p.PropertyType.Name.ToLower())
                {
                    case "string":
                        p.SetValue(result, cell.GetValue<String>());
                        break;
                    case "int16":
                        p.SetValue(result, cell.GetValue<Int16>());
                        break;
                    case "int32":
                        p.SetValue(result, cell.GetValue<Int32>());
                        break;
                    case "int64":
                        p.SetValue(result, cell.GetValue<Int64>());
                        break;
                    case "decimal":
                        p.SetValue(result, cell.GetValue<Decimal>());
                        break;
                    case "double":
                        p.SetValue(result, cell.GetValue<Double>());
                        break;
                    case "datetime":
                        p.SetValue(result, cell.GetValue<DateTime>());
                        break;
                    case "boolean":
                        p.SetValue(result, cell.GetValue<Boolean>());
                        break;
                    case "byte":
                        p.SetValue(result, cell.GetValue<Byte>());
                        break;
                    case "char":
                        p.SetValue(result, cell.GetValue<Char>());
                        break;
                    case "single":
                        p.SetValue(result, cell.GetValue<Single>());
                        break;
                    default:
                        p.SetValue(result, cell?.Value?.ToString());
                        break;
                }
            }
    
            private static string GetPropertyName(Expression<Func<T, object>> expression)
            {
                Expression expressionToCheck = expression;
                bool done = false;
                while (!done)
                {
                    switch (expressionToCheck.NodeType)
                    {
                        case ExpressionType.Convert:
                            expressionToCheck = ((UnaryExpression)expressionToCheck).Operand;
                            break;
                        case ExpressionType.Lambda:
                            expressionToCheck = ((LambdaExpression)expressionToCheck).Body;
                            break;
                        case ExpressionType.MemberAccess:
                            var memberExpression = ((MemberExpression)expressionToCheck);
                            string propertyName = memberExpression.Member.Name;
                            return propertyName;
                        default:
                            done = true;
                            break;
                    }
                }
                return "";
            }
    
        }
    
        public class XlsEntity
        {
            /// <summary>
            /// 实体名称
            /// </summary>
            public string EntityName { get; set; }
    
            /// <summary>
            /// 列名称
            /// </summary>
            public string ColumnName { get; set; }
    
            /// <summary>
            /// 列下标
            /// </summary>
            public int ColumnIndex { get; set; }
    
            /// <summary>
            /// 转换方法
            /// </summary>
            public Func<string, object> ConvertFunc { get; set; }
        }
    
        public class XlsRow
        {
            /// <summary>
            /// 错误信息
            /// </summary>
            public List<string> ErrMessage { get; set; }
    
            /// <summary>
            /// 错误列名
            /// </summary>
            public List<string> ErrColumn { get; set; }
    
            /// <summary>
            /// 错误内容
            /// </summary>
            public List<string> ErrValue { get; set; }
    
            /// <summary>
            /// 是否转换出错(false:未出错,true:出错)
            /// </summary>
            public bool IsErr { get; set; }
        }

    使用

      

    public async Task<byte[]> ExportExcel(Params param)
    
            {
    
                List<Entity> list = await GetDataSource(param).ToListAsync();
    
                //导出表头和字段集合
    
                ExportColumnCollective ecc = new ExportColumnCollective();
    
                //导出字段集合
    
                ecc.ExportColumnList = new List<ExportColumn>
    
                {
    
                    new ExportColumn{ Field = "UserId" },
    
                    new ExportColumn{ Field = "UserName" },
    
                };
    
                //导出表头集合
    
                ecc.HeaderExportColumnList = new List<List<ExportColumn>>
    
                {
    
                    new List<ExportColumn>
    
                    {
    
                        new ExportColumn{ Title = "用户编号" },
    
                        new ExportColumn{ Title = "姓名" }
    
                    }
    
                };
    
                byte[] result = Export2Excel.Export<BillEntity>(list, ecc, "用户", false);
    
                return result;
    
            }
    public async Task<FileResult> ExportExcel([FromQuery] BillParams pairs)
            {
                byte[] result = await _billService.ExportExcel(pairs);
                return File(result, "application/vnd.ms-excel", $"{DateTime.Now.ToString("yyMMddHHmmssfff")}.xlsx");
            }
  • 相关阅读:
    选择器
    【兼容】text
    SQL2008的数据更新跟踪测试
    拖拽文件到RichEdit的后期处理
    Web Browser 的扩展
    URL Protocol Handler
    asterisk1.6异步脚本
    CSDNER如何才能做到"最不缺的是技术"
    关于SQL语句Count的一点细节
    TG787 脚本
  • 原文地址:https://www.cnblogs.com/zousc/p/14277897.html
Copyright © 2020-2023  润新知