【C#】【Demo】 创建Excel帮助XSSFWorkbookCreateHelper。//用于浏览器导出Excel

//用于浏览器导出Excel,即return File(bytes, "application/vnd.ms-excel", titleName + ".xlsx");

using NPOI.SS.UserModel;
using NPOI.SS.Util;
using NPOI.XSSF.UserModel;
using System;
using System.Collections.Generic;
using System.IO;

namespace CommonUtil
{
    /// <summary>
    /// 创建Excel帮助类
    /// </summary>
    public class XSSFWorkbookCreateHelper
    {
        //创建Excel文件的对象
        public XSSFWorkbook book;

        /// <summary>
        /// sheet数组
        /// </summary>
        public List<ISheet> sheetList = new List<ISheet>();
        /// <summary>
        /// 当前操作sheet的下标
        /// </summary>
        public int thisSheetIndex = 0;

        //默认单元格宽度
        int CellWidth;

        //默认单元格高度
        short CellHeight;

        Dictionary<int, int> dicWidth;
        Dictionary<int, short> dicHeight;

        /// <summary>
        /// 
        /// </summary>
        /// <param name="cellWidth">单元格宽</param>
        /// <param name="cellHeight">单元格高</param>
        public XSSFWorkbookCreateHelper(int cellWidth, short cellHeight, VerticalAlignment? center = null, string sheetName = "Sheet")
        {
            CellWidth = cellWidth;
            CellHeight = cellHeight;

            dicWidth = new Dictionary<int, int>();
            dicHeight = new Dictionary<int, short>();

            //创建Excel文件的对象
            book = new XSSFWorkbook();
            //NPOI.HSSF.UserModel.HSSFWorkbook book = new NPOI.HSSF.UserModel.HSSFWorkbook();

            //添加一个sheet
            if (!string.IsNullOrWhiteSpace(sheetName))
            {
                sheetList.Add(book.CreateSheet(sheetName));
            }

            //样式
            ICellStyle style = book.CreateCellStyle();//设置垂直居中格式
            style.VerticalAlignment = center == null ? VerticalAlignment.Center : center.Value;// VerticalAlignment.Center;垂直居中       
        }

        /// <summary>
        /// 添加单元格
        /// </summary>
        public void AddCell(CellModel model)
        {
            ISheet sheet1 = sheetList[thisSheetIndex];
            try
            {


                int cellWidth = CellWidth;
                short cellHeight = CellHeight;


                if (model.Width != null)
                {
                    cellWidth = model.Width.Value;

                    //第一个宽不被覆盖
                    if (!dicWidth.ContainsKey(model.C))
                    {
                        dicWidth.Add(model.C, model.Width.Value);
                    }

                }
                else if (dicWidth.ContainsKey(model.C))
                {
                    cellWidth = dicWidth[model.C];
                }


                if (model.Height != null)
                {
                    cellHeight = model.Height.Value;

                    //第一个不被覆盖
                    if (!dicHeight.ContainsKey(model.R))
                    {
                        dicHeight.Add(model.R, model.Height.Value);
                    }
                }
                else if (dicHeight.ContainsKey(model.R))
                {
                    cellHeight = dicHeight[model.R];
                }


                IRow row = sheet1.GetRow(model.R);
                if (row == null)
                {
                    row = sheet1.CreateRow(model.R);
                    row.Height = cellHeight;
                }
                var cell = row.GetCell(model.C);
                if (cell == null)
                {
                    sheet1.SetColumnWidth(model.C, cellWidth);
                    cell = row.CreateCell(model.C);
                }

                if (model.Type == 1)
                {
                    //设置下拉框验证
                    CellRangeAddressList cr = new CellRangeAddressList(model.R, model.R, model.C, model.C);
                    XSSFDataValidationHelper h = new XSSFDataValidationHelper((XSSFSheet)sheet1);
                    var dc = h.CreateExplicitListConstraint(model.SelectCheckList);
                    var dv = h.CreateValidation(dc, cr);
                    sheet1.AddValidationData(dv);

                    //写入下拉框默认值
                    cell.SetCellValue(model.Value);
                }
                else if (model.Type == 2)
                {
                    //公式
                    cell.CellFormula = model.Value;
                }
                else
                {
                    cell.SetCellValue(model.Value);
                }
                //合并
                if (model.REnd > model.R || model.CEnd > model.C)
                {
                    for (int r = model.R; r <= model.REnd; r++)
                    {
                        var rowr = sheet1.GetRow(r);
                        if (rowr == null)
                        {
                            rowr = sheet1.CreateRow(r);
                            rowr.Height = cellHeight;
                        }
                        for (int c = model.C + 1; c <= model.CEnd; c++)
                        {
                            var cellc = rowr.GetCell(c);
                            if (cellc == null)
                            {
                                sheet1.SetColumnWidth(c, cellWidth);
                                cellc = rowr.CreateCell(c);
                            }
                        }
                    }

                    // 合并单元格  
                    CellRangeAddress cra = new CellRangeAddress(model.R, model.REnd, model.C, model.CEnd); // 起始行, 终止行, 起始列, 终止列  
                    sheet1.AddMergedRegion(cra);
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        /// <summary>
        /// 切换到下一个Sheet。
        /// 按样例的话就重置单元格偏移变量,后续不变:
        ///  bookHelper.NextSheet(batchNumber + sheetKey);
        ///  cells = new List<CellModel>();
        ///  r = 0; c = 0;
        /// </summary>
        public void NextSheet(string sheetName)
        {
            sheetList.Add(book.CreateSheet(sheetName));
            thisSheetIndex = sheetList.Count - 1;
        }

        public static void test() 
        {
            XSSFWorkbookCreateHelper bookHelper = new XSSFWorkbookCreateHelper(1800, 400, NPOI.SS.UserModel.VerticalAlignment.Center);
            int r = 0, c = 0;

            //表头
            bookHelper.AddCell(new CellModel(r, c++, "A1"));
            bookHelper.AddCell(new CellModel(r, c++, "B1"));
            bookHelper.AddCell(new CellModel(r, c++, "C1"));

            //换行
            r++;
            c = 0;
            bookHelper.AddCell(new CellModel(r, c++, "A2"));
            bookHelper.AddCell(new CellModel(r, c++, "A2"));
            //公式
            bookHelper.AddCell(new CellModel(r, c++, string.Format("IF(EXACT(A{0},B{0})=TRUE,\"相同\",\"并不相同\")", r+1), type: 2));
            bookHelper.AddCell(new CellModel(r, c++, "D2"));
            bookHelper.AddCell(new CellModel(r, c++, "E2"));
            //公式
            bookHelper.AddCell(new CellModel(r, c++, string.Format("IF(EXACT(D{0},E{0})=TRUE,\"相同\",\"并不相同\")", r+1), type: 2));
            //下拉框
            bookHelper.AddCell(new CellModel(r, c++, new string[] { "G2A", "G2B" }, "G2下拉框"));

            //换行
            r++;
            c = 0;
            bookHelper.AddCell(new CellModel(r, c++, "A3"));
            //合并cw个单元格的列
            int cw = 2;
            bookHelper.AddCell(new CellModel(r, c, "B3合并行" + cw, cend: c + (cw - 1)));
            c += cw;
            bookHelper.AddCell(new CellModel(r, c++, "D3"));

            //换行
            r++;
            c = 0;
            bookHelper.AddCell(new CellModel(r, c++, "A4"));
            //合并rw个单元格的行
            int rw = 3;
            
            bookHelper.AddCell(new CellModel(r, c, "B4合并列"+rw, rend: r + (rw - 1)));
            //合并列后的第一列
            int oldR = r;//每列开始
            c++;
            bookHelper.AddCell(new CellModel(r++, c, "C4.1"));
            bookHelper.AddCell(new CellModel(r++, c, "C4.2"));
            bookHelper.AddCell(new CellModel(r, c, "C4.3"));//最后一次行不加加
            //合并列后的第二列
            r = oldR;//每列开始
            c++;
            bookHelper.AddCell(new CellModel(r++, c, "D4.1"));
            bookHelper.AddCell(new CellModel(r++, c, "D4.2"));
            bookHelper.AddCell(new CellModel(r, c, "D4.3"));//最后一次行不加加

            //换行
            r++;
            c = 0;
            bookHelper.AddCell(new CellModel(r, c++, "A" + (r + 1)));

            //保存流
            //重写的禁止自动关闭的流对象FileUtilMemoryStream
            using (FileUtilMemoryStream ms = new FileUtilMemoryStream(false))
            {
                bookHelper.book.Write(ms);

                //流会被关闭,所以转byte[],需要用MemoryStream.ToArray()
                var bt = FileHelper.StreamToBytes(ms);

                //关闭流
                ms.CloseIgnoreAllow();

                //return File(bt, "application/vnd.ms-excel", titleName + ".xlsx");
            }

            ////保存文件
            //string path = AppDomain.CurrentDomain.BaseDirectory + "/template/excel";
            //if (!System.IO.Directory.Exists(path))
            //{
            //    System.IO.Directory.CreateDirectory(path);
            //}
            //path += "/test.xlsx";
            //using (FileStream ms = new FileStream(path, FileMode.Create))
            //{
            //    bookHelper.book.Write(ms);
            //}
        }

    }

    /// <summary>
    /// 单元格对象
    /// </summary>
    public class CellModel
    {
        #region 重载构造
        private CellModel() { }
        public CellModel(int r, int c, bool value, int? rend = null, int? cend = null, int? width = null, short? height = null)
        {
            init(r, c, value, rend, cend, width, height);
        }
        /// <summary>
        /// 字符串或公式
        /// </summary>
        /// <param name="r"></param>
        /// <param name="c"></param>
        /// <param name="value"></param>
        /// <param name="rend"></param>
        /// <param name="cend"></param>
        /// <param name="width"></param>
        /// <param name="height"></param>
        /// <param name="type">特别类型,0默认,2公式CellFormula(是一个字符串,公式前不需要加=号)</param>
        public CellModel(int r, int c, string value, int? rend = null, int? cend = null, int? width = null, short? height = null, int type = 0)
        {
            init(r, c, value, rend, cend, width, height, type);
        }
        public CellModel(int r, int c, IRichTextString value, int? rend = null, int? cend = null, int? width = null, short? height = null)
        {
            init(r, c, value, rend, cend, width, height);
        }
        public CellModel(int r, int c, DateTime value, int? rend = null, int? cend = null, int? width = null, short? height = null)
        {
            init(r, c, value, rend, cend, width, height);
        }
        public CellModel(int r, int c, double value, int? rend = null, int? cend = null, int? width = null, short? height = null)
        {
            init(r, c, value, rend, cend, width, height);
        }
        /// <summary>
        /// 值字符串类型,并增加下拉框限制
        /// </summary>
        /// <param name="r"></param>
        /// <param name="c"></param>
        /// <param name="selectCheckList"></param>
        /// <param name="value"></param>
        /// <param name="rend"></param>
        /// <param name="cend"></param>
        /// <param name="width"></param>
        /// <param name="height"></param>
        public CellModel(int r, int c, string[] selectCheckList, string value, int? rend = null, int? cend = null, int? width = null, short? height = null)
        {
            init(r, c, value, rend, cend, width, height, 1);
            this.SelectCheckList = selectCheckList;
        }
        #endregion

        private void init(int r, int c, dynamic value, int? rend = null, int? cend = null, int? width = null, short? height = null, int type = 0)
        {
            R = r;
            C = c;
            if (value == null) { value = ""; }
            Value = value;
            if (rend == null) { rend = r; }
            if (cend == null) { cend = c; }
            REnd = rend.Value;
            CEnd = cend.Value;
            Width = width;
            Height = height;
            Type = type;
        }

        internal int R;//行坐标
        internal int C;//列坐标
        internal int REnd;//单元格宽结束坐标,用于占多行(合并单元格)
        internal int CEnd;//单元格列结束坐标,用于占多列(合并单元格)

        internal dynamic Value;//单元格值,类型可选:bool、string、IRichTextString、DateTime、double

        internal int? Width;
        internal short? Height;

        /// <summary>
        /// 特别类型,0默认,1下拉框IDataValidation,2公式CellFormula(是一个字符串,公式前不需要加=号)
        /// </summary>
        internal int Type;

        /// <summary>
        /// 下拉框候选值列表
        /// </summary>
        internal string[] SelectCheckList;
    }

}
View Code

 

调用例:

/// <summary>
        /// 导出分销会员数据
        /// </summary>
        /// <param name="searchJson"></param>
        /// <returns></returns>
        public ActionResult CreateExcelToRetailMember(string searchJson)
        {
            Search_ViewMemberJoinSale se = JsonHelp<Search_ViewMemberJoinSale>.FromJsonString(searchJson);
            var st = OperateContext.Current.BLLSession.IRetail_SaleBLL.CreateExcelToRetailMember(se);

            if (st != null)
            { 
                string titleName = "分销会员数据";
                if (se != null)
                {
                    if (se.RegisterTimeST.HasValue)
                    {
                        titleName += se.RegisterTimeST.Value.ToString("yyyyMMdd");
                    }
                    if (se.RegisterTimeET.HasValue)
                    {
                        titleName += se.RegisterTimeET.Value.ToString("~yyyyMMdd");
                    }
                }
                
                //重写的禁止自动关闭的流对象FileUtilMemoryStream
                using (FileUtilMemoryStream ms = new FileUtilMemoryStream(false))
                {
                    st.book.Write(ms);

                    //流会被关闭,所以转byte[]
                    var bt = FileHelper.StreamToBytes(ms);

                    //关闭流
                    ms.CloseIgnoreAllow();

                    return File(bt, "application/vnd.ms-excel", titleName + ".xlsx");
                }
            }
            else
            {
                return Content("导出分销会员数据失败");
            }
        }
        
        /// <summary>
        /// 创建分销用户的导出excel,返回XSSF帮助类
        /// </summary>
        public XSSFWorkbookCreateHelper CreateExcelToRetailMember(Search_ViewMemberJoinSale se)
        {
            try
            {
                //数据源
                se.PageIndex = 0;
                se.PageSize = 0;
                var page = GetPageView_MemberJoinSale(se);
                if (page == null || page.Data == null || !page.Data.Any())
                {
                    throw new GeneralException(1, "未找到导出数据");
                }

                var dataList = page.Data;


                //数据源
                var memberIds = dataList.Select(x => x.MemberId).Distinct().ToList();

                //地址列表
                var addressList = DBSession.IUser_ShippingAddressDAL.GetListBy(x => memberIds.Contains(x.MemberId));

                //充值记录//用户导出数据里要看的是充值(包括取消充值)的情况,不要余额(消费)的变动情况。
                int[] balanceRecirdTypes = new int[]
                {
                    (int)EnumMemberBalanceType.账户充值,
                    (int)EnumMemberBalanceType.线下扣款,
                    (int)EnumMemberBalanceType.小程序销售充值,
                    (int)EnumMemberBalanceType.活动充值,
                };
                var balanceRecordList = DBSession.IMember_BalanceRecordDAL.GetListBy(x => memberIds.Contains(x.MemberId)
                && balanceRecirdTypes.Contains(x.Type)
                //&& x.RechargeAmount >= 0 && x.GiveAmount >= 0
                );

                //充值记录操作人
                var linkIds = balanceRecordList.Select(x => x.LinkId).Where(x => x != null).Distinct().ToList();
                var accList = DBSession.ISys_AccountDAL.GetListBy(x => linkIds.Contains(x.AccountId));
                var accMembers = DBSession.IMember_BasicInfoDAL.GetListBy(x => linkIds.Contains(x.MemberId));

                //绑定宠物信息
                var petList = DBSession.IMember_PetDAL.GetListBy(x => memberIds.Contains(x.MemberId));
                var classIds = petList.Select(x => x.ClassId).Distinct().ToList();
                var classList = DBSession.IProduct_ClassDAL.GetListBy(x => classIds.Contains(x.ClassId));

                //用户订单,得到最近一次消费时间。之后手动按每月导出,不需要处理订单量太大问题。
                var orderList = DBSession.IOrder_MainDAL.GetListBy(x => memberIds.Contains(x.MemberId));
                var orderIds = orderList.Select(x => x.OrderId).ToList();

                var orderProductList = DBSession.IOrder_ProductDAL.GetListBy(x => orderIds.Contains(x.OrderId) && x.ParentOrderProductId != Guid.Empty);

                //优惠券
                var couponList = DBSession.IMember_CouponDAL.GetListBy(x => memberIds.Contains(x.MemberId));

                //兑换券
                var itemCouponList = DBSession.IMember_TestItemCouponDAL.GetListBy(x => memberIds.Contains(x.MemberId));

                Guid catid = ConvertHelper.ToGuid(ConfigurationHelper.AppSetting("CatId"));

                var enumMemberCoupons = EnumberHelper.EnumToList<EnumMemberCoupon>();
                var enumMemberTestItemCouponStates = EnumberHelper.EnumToList<EnumMemberTestItemCouponState>();

                //创建表格帮助类
                int width = 4500;
                short height = 400;
                XSSFWorkbookCreateHelper bookHelper = new XSSFWorkbookCreateHelper(width, height);
                List<CellModel> cells = new List<CellModel>();

                //当前行
                int r = 0;

                //当前列
                int c = 0;

                //表头
                #region 表头
                cells.Add(new CellModel(r, c++, "id", 1));
                cells.Add(new CellModel(r, c++, "用户昵称", 1));
                cells.Add(new CellModel(r, c++, "手机号", 1));
                cells.Add(new CellModel(r, c++, "注册时间", 1));
                cells.Add(new CellModel(r, c++, "最近一次消费时间", 1));
                cells.Add(new CellModel(r, c++, "年龄", 1));
                cells.Add(new CellModel(r, c++, "性别", 1));
                cells.Add(new CellModel(r, c++, "累计充值金额", 1));

                List<CellModel> reLogs = new List<CellModel>()
                {
                    new CellModel(r+1, c++, "时间"),
                    new CellModel(r+1, c++, "余额"),
                    new CellModel(r+1, c++, "宠知因币"),
                    new CellModel(r+1, c++, "操作人"),
                    new CellModel(r+1, c++, "充值说明"),
                };
                cells.Add(new CellModel(r, c - reLogs.Count(), "充值记录", null, c - 1));
                cells.AddRange(reLogs);


                cells.Add(new CellModel(r+1, c++, "账户余额", 1));
                cells.Add(new CellModel(r+1, c++, "宠知因币", 1));
                cells.Add(new CellModel(r+1, c++, "绑定宠物数量", 1));

                var petCels = new List<CellModel>() 
                {
                    new CellModel(r+1, c++, "昵称"),
                    new CellModel(r+1, c++, "宠物编号"),
                    new CellModel(r+1, c++, "品系"),
                    new CellModel(r+1, c++, "品种")
                };

                cells.Add(new CellModel(r, c-petCels.Count(), "绑定宠物信息", null, c - 1));
                cells.AddRange(petCels);

                cells.Add(new CellModel(r, c++, "检测项目数量", 1));
                cells.Add(new CellModel(r, c++, "订单数量", 1));
                cells.Add(new CellModel(r, c++, "优惠券数量", 1));

                var couponCels = new List<CellModel>()
                {
                    new CellModel(r+1, c++, "优惠券名字"),
                    new CellModel(r+1, c++, "获得时间"),
                    new CellModel(r+1, c++, "是否使用"),
                };

                cells.Add(new CellModel(r, c - couponCels.Count(), "优惠券明细", null, c - 1));
                cells.AddRange(couponCels);

                cells.Add(new CellModel(r, c++, "兑换券数量", 1));
                


                var testCouCels = new List<CellModel>()
                {
                    new CellModel(r+1, c++, "兑换券名字"),
                    new CellModel(r+1, c++, "兑换券项目"),
                    new CellModel(r+1, c++, "获得时间"),
                    new CellModel(r+1, c++, "是否使用"),
                };

                cells.Add(new CellModel(r, c - testCouCels.Count(), "兑换券明细", null, c - 1));
                cells.AddRange(testCouCels);

                cells.Add(new CellModel(r, c++, "推荐人",1));
                cells.Add(new CellModel(r, c++, "推荐人手机号",1));
                cells.Add(new CellModel(r, c++, "绑定销售",1));
                #endregion
                //表头占两行
                r = 1;

                //插入数据
                int radd = 0;
                var time = new DateTime(1750, 1, 1);
                foreach (var item in dataList)
                {
                    r++;
                    c = 0;
                    #region 此用户数据
                    var addresses = addressList.Where(x => x.MemberId == item.MemberId).ToList();
                    int addressCount = addresses.Count();
                    var blanceRecords = balanceRecordList.Where(x => x.MemberId == item.MemberId).ToList();
                    int blanceCount = blanceRecords.Count();
                    var pets = petList.Where(x => x.MemberId == item.MemberId).ToList();
                    int petCount = pets.Count();
                    var coupons = couponList.Where(x => x.MemberId == item.MemberId).ToList();
                    int couponCount = coupons.Count();
                    var itemCoupons = itemCouponList.Where(x => x.MemberId == item.MemberId).ToList();
                    int itemCouponCount = itemCoupons.Count();

                    radd = blanceCount - 1;
                    if (radd < petCount - 1)
                    {
                        radd = petCount - 1;
                    }
                    if (radd < addressCount - 1)
                    {
                        radd = addressCount - 1;
                    }
                    if (radd < couponCount - 1)
                    {
                        radd = couponCount - 1;
                    }
                    if (radd < itemCouponCount - 1)
                    {
                        radd = itemCouponCount - 1;
                    }
                    if (radd < 0)
                    {
                        radd = 0;
                    }

                    var orders = orderList.Where(x => x.MemberId == item.MemberId).ToList();
                    int orderCount = orders.Count();
                    #endregion

                    bookHelper.AddCell(new CellModel(r, c++, item.MemberId.ToString(), r + radd));
                    bookHelper.AddCell(new CellModel(r, c++, item.NickName, r + radd));
                    bookHelper.AddCell(new CellModel(r, c++, item.Mobile, r + radd));
                    bookHelper.AddCell(new CellModel(r, c++, item.CreateTime.ToString("yyyy-MM-dd HH:mm"), r + radd));

                    //最近一次消费时间,含充值
                    bookHelper.AddCell(new CellModel(r, c++, item.LostPayTimeStr, r + radd));

                    //年龄
                    bookHelper.AddCell(new CellModel(r, c++, "", r + radd));

                    var sex = item.Sex == 1 ? "" : (item.Sex == 2 ? "" : "未知");
                    bookHelper.AddCell(new CellModel(r, c++, sex, r + radd));

                    //累计充值金额
                    if (blanceCount > 0)
                    {
                        //累计充值金额
                        var sumBlance = blanceRecords.Sum(x => x.RechargeAmount);
                        bookHelper.AddCell(new CellModel(r, c, sumBlance.ToString("f2"), r + radd));

                        c++;

                        for (int i = 0; i < blanceCount; i++)
                        {
                            var blance = blanceRecords[i];
                            bookHelper.AddCell(new CellModel(r + i, c + 0, blance.Createtime.ToString("yyyy-MM-dd HH:mm")));
                            bookHelper.AddCell(new CellModel(r + i, c + 1, blance.RechargeAmount.ToString("f2")));
                            bookHelper.AddCell(new CellModel(r + i, c + 2, blance.GiveAmount.ToString("f2")));

                            string accName = "系统执行";
                            if (blance.LinkId != Guid.Empty)
                            {
                                var acc = accList.FirstOrDefault(x => x.AccountId == blance.LinkId);
                                if (acc != null)
                                {
                                    accName = acc.Name;
                                }
                                else
                                {
                                    var accM = accMembers.FirstOrDefault(x => x.MemberId == blance.LinkId);
                                    if (accM != null)
                                    {
                                        accName = accM.Mobile;
                                    }
                                }
                            }
                            bookHelper.AddCell(new CellModel(r + i, c + 3, accName));//操作人
                            bookHelper.AddCell(new CellModel(r + i, c + 4, blance.ReMark));
                        }
                    }
                    else
                    {
                        //累计充值金额占列
                        c++;
                    }
                    c += reLogs.Count();

                    bookHelper.AddCell(new CellModel(r, c++, item.Cash.ToString("f2"), r + radd));
                    bookHelper.AddCell(new CellModel(r, c++, item.CZYCoin.ToString("f2"), r + radd));

                    //绑定宠物数量
                    bookHelper.AddCell(new CellModel(r, c++, petCount, r + radd));
                    if (petCount > 0)
                    {
                        for (int i = 0; i < petCount; i++)
                        {
                            var pet = pets[i];
                            bookHelper.AddCell(new CellModel(r + i, c + 0, pet.PetCNName));
                            bookHelper.AddCell(new CellModel(r + i, c + 1, pet.PetNumber));

                            string className = "";
                            if (classList.Any(x => x.ClassId == pet.ClassId))
                            {
                                className = classList.First(x => x.ClassId == pet.ClassId).ClassName;
                            }
                            bookHelper.AddCell(new CellModel(r + i, c + 2, className));
                            bookHelper.AddCell(new CellModel(r + i, c + 3, StaticModel.SpecieNameCn(pet.SpeciesId)));
                        }
                    }
                    c += petCels.Count();



                    var thisOrderIds = orders.Select(x => x.OrderId).ToList();
                    var productCount = orderProductList.Count(x => thisOrderIds.Contains(x.OrderId));
                    //检测项目数量
                    bookHelper.AddCell(new CellModel(r, c++, productCount, r + radd));

                    //订单数量
                    bookHelper.AddCell(new CellModel(r, c++, orderCount, r + radd));
                    //优惠券数量
                    bookHelper.AddCell(new CellModel(r, c++, couponCount, r + radd));

                    //优惠券明细//优惠券明细 和 兑换券明细 指的是获得的优惠券名字  获得时间  是否使用。
                    if (couponCount > 0)
                    {
                        for (int i = 0; i < couponCount; i++)
                        {
                            var coupon = coupons[i];
                            bookHelper.AddCell(new CellModel(r + i, c + 0, coupon.CouponName));
                            bookHelper.AddCell(new CellModel(r + i, c + 1, coupon.CreateTime));
                            var state = enumMemberCoupons.FirstOrDefault(x => x.EnumValue == coupon.State);
                            if (state != null)
                            {
                                bookHelper.AddCell(new CellModel(r + i, c + 2, state.EnumName));
                            }
                        }
                    }
                    c += couponCels.Count();

                    //兑换券数量
                    bookHelper.AddCell(new CellModel(r, c++, itemCouponCount, r + radd));

                    //兑换券明细
                    if (itemCouponCount > 0)
                    {
                        for (int i = 0; i < itemCouponCount; i++)
                        {
                            var itemCoupon = itemCoupons[i];
                            string pNames = "";
                            if (itemCoupon.ProductList != null && itemCoupon.ProductList.Any())
                            {
                                foreach (var p in itemCoupon.ProductList)
                                {
                                    if (p != null)
                                    {
                                        pNames += "-" + p.ProductName;
                                    }
                                }
                            }
                            pNames = pNames.Trim('-');

                            bookHelper.AddCell(new CellModel(r + i, c + 0, itemCoupon.Remark));
                            bookHelper.AddCell(new CellModel(r + i, c + 1, pNames));
                            bookHelper.AddCell(new CellModel(r + i, c + 2, itemCoupon.CreateTime.ToString("yyyy-MM-dd HH:mm")));

                            var state = enumMemberTestItemCouponStates.FirstOrDefault(x => x.EnumValue == itemCoupon.IsUse);
                            if (state != null)
                            {
                                bookHelper.AddCell(new CellModel(r + i, c + 3, state.EnumName));
                            }
                        }
                    }
                    c += testCouCels.Count();

                    //推荐人
                    bookHelper.AddCell(new CellModel(r, c++, item.Channel_Contacts, r + radd));

                    bookHelper.AddCell(new CellModel(r, c++, item.Channel_Phone, r + radd));

                    bookHelper.AddCell(new CellModel(r, c++, item.SaleName, r + radd));

                    r += radd;
                }

                foreach (var item in cells)
                {
                    bookHelper.AddCell(item);
                }
                return bookHelper;

            }
            catch (Exception ex)
            {

                Common.LogHelper.Instance.Error("导出分销会员数据出错", ex);
                return null;
            }
        }
        
View Code

 

 
            //导出excel详细
            scope.ExportDetail = function () {
                if (scope.rowCount > 10000) {
                    alert("本次导出数据较多,成功导出后将自动下载,请勿频繁操作!如果失败请筛选减少数量。")
                }
                if (scope.rowCount > 0) {
                    window.open("CreateExcelToRetailMember?searchJson=" + JSON.stringify(scope.SearchInfo));
                }

            }

 

using NPOI.SS.UserModel;using NPOI.SS.Util;using NPOI.XSSF.UserModel;using System;using System.Collections.Generic;using System.IO;
namespace CommonUtil{    /// <summary>    /// 创建Excel帮助类    /// </summary>    public class XSSFWorkbookCreateHelper    {        //创建Excel文件的对象        public XSSFWorkbook book;
        /// <summary>        /// sheet数组        /// </summary>        public List<ISheet> sheetList = new List<ISheet>();        /// <summary>        /// 当前操作sheet的下标        /// </summary>        public int thisSheetIndex = 0;
        //默认单元格宽度        int CellWidth;
        //默认单元格高度        short CellHeight;
        Dictionary<int, int> dicWidth;        Dictionary<int, short> dicHeight;
        /// <summary>        ///         /// </summary>        /// <param name="cellWidth">单元格宽</param>        /// <param name="cellHeight">单元格高</param>        public XSSFWorkbookCreateHelper(int cellWidth, short cellHeight, VerticalAlignment? center = null, string sheetName = "Sheet")        {            CellWidth = cellWidth;            CellHeight = cellHeight;
            dicWidth = new Dictionary<int, int>();            dicHeight = new Dictionary<int, short>();
            //创建Excel文件的对象            book = new XSSFWorkbook();            //NPOI.HSSF.UserModel.HSSFWorkbook book = new NPOI.HSSF.UserModel.HSSFWorkbook();
            //添加一个sheet            if (!string.IsNullOrWhiteSpace(sheetName))            {                sheetList.Add(book.CreateSheet(sheetName));            }
            //样式            ICellStyle style = book.CreateCellStyle();//设置垂直居中格式            style.VerticalAlignment = center == null ? VerticalAlignment.Center : center.Value;// VerticalAlignment.Center;垂直居中               }
        /// <summary>        /// 添加单元格        /// </summary>        public void AddCell(CellModel model)        {            ISheet sheet1 = sheetList[thisSheetIndex];            try            {

                int cellWidth = CellWidth;                short cellHeight = CellHeight;

                if (model.Width != null)                {                    cellWidth = model.Width.Value;
                    //第一个宽不被覆盖                    if (!dicWidth.ContainsKey(model.C))                    {                        dicWidth.Add(model.C, model.Width.Value);                    }
                }                else if (dicWidth.ContainsKey(model.C))                {                    cellWidth = dicWidth[model.C];                }

                if (model.Height != null)                {                    cellHeight = model.Height.Value;
                    //第一个不被覆盖                    if (!dicHeight.ContainsKey(model.R))                    {                        dicHeight.Add(model.R, model.Height.Value);                    }                }                else if (dicHeight.ContainsKey(model.R))                {                    cellHeight = dicHeight[model.R];                }

                IRow row = sheet1.GetRow(model.R);                if (row == null)                {                    row = sheet1.CreateRow(model.R);                    row.Height = cellHeight;                }                var cell = row.GetCell(model.C);                if (cell == null)                {                    sheet1.SetColumnWidth(model.C, cellWidth);                    cell = row.CreateCell(model.C);                }
                if (model.Type == 1)                {                    //设置下拉框验证                    CellRangeAddressList cr = new CellRangeAddressList(model.R, model.R, model.C, model.C);                    XSSFDataValidationHelper h = new XSSFDataValidationHelper((XSSFSheet)sheet1);                    var dc = h.CreateExplicitListConstraint(model.SelectCheckList);                    var dv = h.CreateValidation(dc, cr);                    sheet1.AddValidationData(dv);
                    //写入下拉框默认值                    cell.SetCellValue(model.Value);                }                else if (model.Type == 2)                {                    //公式                    cell.CellFormula = model.Value;                }                else                {                    cell.SetCellValue(model.Value);                }                //合并                if (model.REnd > model.R || model.CEnd > model.C)                {                    for (int r = model.R; r <= model.REnd; r++)                    {                        var rowr = sheet1.GetRow(r);                        if (rowr == null)                        {                            rowr = sheet1.CreateRow(r);                            rowr.Height = cellHeight;                        }                        for (int c = model.C + 1; c <= model.CEnd; c++)                        {                            var cellc = rowr.GetCell(c);                            if (cellc == null)                            {                                sheet1.SetColumnWidth(c, cellWidth);                                cellc = rowr.CreateCell(c);                            }                        }                    }
                    // 合并单元格                      CellRangeAddress cra = new CellRangeAddress(model.R, model.REnd, model.C, model.CEnd); // 起始行, 终止行, 起始列, 终止列                      sheet1.AddMergedRegion(cra);                }            }            catch (Exception ex)            {                throw ex;            }        }
        /// <summary>        /// 切换到下一个Sheet。        /// 按样例的话就重置单元格偏移变量,后续不变:        ///  bookHelper.NextSheet(batchNumber + sheetKey);        ///  cells = new List<CellModel>();        ///  r = 0; c = 0;        /// </summary>        public void NextSheet(string sheetName)        {            sheetList.Add(book.CreateSheet(sheetName));            thisSheetIndex = sheetList.Count - 1;        }
        public static void test()         {            XSSFWorkbookCreateHelper bookHelper = new XSSFWorkbookCreateHelper(1800, 400, NPOI.SS.UserModel.VerticalAlignment.Center);            int r = 0, c = 0;
            //表头            bookHelper.AddCell(new CellModel(r, c++, "A1"));            bookHelper.AddCell(new CellModel(r, c++, "B1"));            bookHelper.AddCell(new CellModel(r, c++, "C1"));
            //换行            r++;            c = 0;            bookHelper.AddCell(new CellModel(r, c++, "A2"));            bookHelper.AddCell(new CellModel(r, c++, "A2"));            //公式            bookHelper.AddCell(new CellModel(r, c++, string.Format("IF(EXACT(A{0},B{0})=TRUE,\"相同\",\"并不相同\")", r+1), type: 2));            bookHelper.AddCell(new CellModel(r, c++, "D2"));            bookHelper.AddCell(new CellModel(r, c++, "E2"));            //公式            bookHelper.AddCell(new CellModel(r, c++, string.Format("IF(EXACT(D{0},E{0})=TRUE,\"相同\",\"并不相同\")", r+1), type: 2));            //下拉框            bookHelper.AddCell(new CellModel(r, c++, new string[] { "G2A", "G2B" }, "G2下拉框"));
            //换行            r++;            c = 0;            bookHelper.AddCell(new CellModel(r, c++, "A3"));            //合并cw个单元格的列            int cw = 2;            bookHelper.AddCell(new CellModel(r, c, "B3合并行" + cw, cend: c + (cw - 1)));            c += cw;            bookHelper.AddCell(new CellModel(r, c++, "D3"));
            //换行            r++;            c = 0;            bookHelper.AddCell(new CellModel(r, c++, "A4"));            //合并rw个单元格的行            int rw = 3;                        bookHelper.AddCell(new CellModel(r, c, "B4合并列"+rw, rend: r + (rw - 1)));            //合并列后的第一列            int oldR = r;//每列开始            c++;            bookHelper.AddCell(new CellModel(r++, c, "C4.1"));            bookHelper.AddCell(new CellModel(r++, c, "C4.2"));            bookHelper.AddCell(new CellModel(r, c, "C4.3"));//最后一次行不加加            //合并列后的第二列            r = oldR;//每列开始            c++;            bookHelper.AddCell(new CellModel(r++, c, "D4.1"));            bookHelper.AddCell(new CellModel(r++, c, "D4.2"));            bookHelper.AddCell(new CellModel(r, c, "D4.3"));//最后一次行不加加
            //换行            r++;            c = 0;            bookHelper.AddCell(new CellModel(r, c++, "A" + (r + 1)));
            //保存流            //重写的禁止自动关闭的流对象FileUtilMemoryStream            using (FileUtilMemoryStream ms = new FileUtilMemoryStream(false))            {                bookHelper.book.Write(ms);
                //流会被关闭,所以转byte[],需要用MemoryStream.ToArray()                var bt = FileHelper.StreamToBytes(ms);
                //关闭流                ms.CloseIgnoreAllow();
                //return File(bt, "application/vnd.ms-excel", titleName + ".xlsx");            }
            ////保存文件            //string path = AppDomain.CurrentDomain.BaseDirectory + "/template/excel";            //if (!System.IO.Directory.Exists(path))            //{            //    System.IO.Directory.CreateDirectory(path);            //}            //path += "/test.xlsx";            //using (FileStream ms = new FileStream(path, FileMode.Create))            //{            //    bookHelper.book.Write(ms);            //}        }
    }
    /// <summary>    /// 单元格对象    /// </summary>    public class CellModel    {        #region 重载构造        private CellModel() { }        public CellModel(int r, int c, bool value, int? rend = null, int? cend = null, int? width = null, short? height = null)        {            init(r, c, value, rend, cend, width, height);        }        /// <summary>        /// 字符串或公式        /// </summary>        /// <param name="r"></param>        /// <param name="c"></param>        /// <param name="value"></param>        /// <param name="rend"></param>        /// <param name="cend"></param>        /// <param name="width"></param>        /// <param name="height"></param>        /// <param name="type">特别类型,0默认,2公式CellFormula(是一个字符串,公式前不需要加=号)</param>        public CellModel(int r, int c, string value, int? rend = null, int? cend = null, int? width = null, short? height = null, int type = 0)        {            init(r, c, value, rend, cend, width, height, type);        }        public CellModel(int r, int c, IRichTextString value, int? rend = null, int? cend = null, int? width = null, short? height = null)        {            init(r, c, value, rend, cend, width, height);        }        public CellModel(int r, int c, DateTime value, int? rend = null, int? cend = null, int? width = null, short? height = null)        {            init(r, c, value, rend, cend, width, height);        }        public CellModel(int r, int c, double value, int? rend = null, int? cend = null, int? width = null, short? height = null)        {            init(r, c, value, rend, cend, width, height);        }        /// <summary>        /// 值字符串类型,并增加下拉框限制        /// </summary>        /// <param name="r"></param>        /// <param name="c"></param>        /// <param name="selectCheckList"></param>        /// <param name="value"></param>        /// <param name="rend"></param>        /// <param name="cend"></param>        /// <param name="width"></param>        /// <param name="height"></param>        public CellModel(int r, int c, string[] selectCheckList, string value, int? rend = null, int? cend = null, int? width = null, short? height = null)        {            init(r, c, value, rend, cend, width, height, 1);            this.SelectCheckList = selectCheckList;        }        #endregion
        private void init(int r, int c, dynamic value, int? rend = null, int? cend = null, int? width = null, short? height = null, int type = 0)        {            R = r;            C = c;            if (value == null) { value = ""; }            Value = value;            if (rend == null) { rend = r; }            if (cend == null) { cend = c; }            REnd = rend.Value;            CEnd = cend.Value;            Width = width;            Height = height;            Type = type;        }
        internal int R;//行坐标        internal int C;//列坐标        internal int REnd;//单元格宽结束坐标,用于占多行(合并单元格)        internal int CEnd;//单元格列结束坐标,用于占多列(合并单元格)
        internal dynamic Value;//单元格值,类型可选:bool、string、IRichTextString、DateTime、double
        internal int? Width;        internal short? Height;
        /// <summary>        /// 特别类型,0默认,1下拉框IDataValidation,2公式CellFormula(是一个字符串,公式前不需要加=号)        /// </summary>        internal int Type;
        /// <summary>        /// 下拉框候选值列表        /// </summary>        internal string[] SelectCheckList;    }
    /* 例:     *        /// <summary>        /// 导出分销会员数据        /// </summary>        /// <param name="searchJson"></param>        /// <returns></returns>        public ActionResult CreateExcelToRetailMember(string searchJson)        {            Search_ViewMemberJoinSale se = JsonHelp<Search_ViewMemberJoinSale>.FromJsonString(searchJson);            var st = OperateContext.Current.BLLSession.IRetail_SaleBLL.CreateExcelToRetailMember(se);
            if (st != null)            {                 string titleName = "分销会员数据";                if (se != null)                {                    if (se.RegisterTimeST.HasValue)                    {                        titleName += se.RegisterTimeST.Value.ToString("yyyyMMdd");                    }                    if (se.RegisterTimeET.HasValue)                    {                        titleName += se.RegisterTimeET.Value.ToString("~yyyyMMdd");                    }                }                                //重写的禁止自动关闭的流对象FileUtilMemoryStream                using (FileUtilMemoryStream ms = new FileUtilMemoryStream(false))                {                    st.book.Write(ms);
                    //流会被关闭,所以转byte[]                    var bt = FileHelper.StreamToBytes(ms);
                    //关闭流                    ms.CloseIgnoreAllow();
                    return File(bt, "application/vnd.ms-excel", titleName + ".xlsx");                }            }            else            {                return Content("导出分销会员数据失败");            }        }                /// <summary>        /// 创建分销用户的导出excel,返回XSSF帮助类        /// </summary>        public XSSFWorkbookCreateHelper CreateExcelToRetailMember(Search_ViewMemberJoinSale se)        {            try            {                //数据源                se.PageIndex = 0;                se.PageSize = 0;                var page = GetPageView_MemberJoinSale(se);                if (page == null || page.Data == null || !page.Data.Any())                {                    throw new GeneralException(1, "未找到导出数据");                }
                var dataList = page.Data;

                //数据源                var memberIds = dataList.Select(x => x.MemberId).Distinct().ToList();
                //地址列表                var addressList = DBSession.IUser_ShippingAddressDAL.GetListBy(x => memberIds.Contains(x.MemberId));
                //充值记录//用户导出数据里要看的是充值(包括取消充值)的情况,不要余额(消费)的变动情况。                int[] balanceRecirdTypes = new int[]                {                    (int)EnumMemberBalanceType.账户充值,                    (int)EnumMemberBalanceType.线下扣款,                    (int)EnumMemberBalanceType.小程序销售充值,                    (int)EnumMemberBalanceType.活动充值,                };                var balanceRecordList = DBSession.IMember_BalanceRecordDAL.GetListBy(x => memberIds.Contains(x.MemberId)                && balanceRecirdTypes.Contains(x.Type)                //&& x.RechargeAmount >= 0 && x.GiveAmount >= 0                );
                //充值记录操作人                var linkIds = balanceRecordList.Select(x => x.LinkId).Where(x => x != null).Distinct().ToList();                var accList = DBSession.ISys_AccountDAL.GetListBy(x => linkIds.Contains(x.AccountId));                var accMembers = DBSession.IMember_BasicInfoDAL.GetListBy(x => linkIds.Contains(x.MemberId));
                //绑定宠物信息                var petList = DBSession.IMember_PetDAL.GetListBy(x => memberIds.Contains(x.MemberId));                var classIds = petList.Select(x => x.ClassId).Distinct().ToList();                var classList = DBSession.IProduct_ClassDAL.GetListBy(x => classIds.Contains(x.ClassId));
                //用户订单,得到最近一次消费时间。之后手动按每月导出,不需要处理订单量太大问题。                var orderList = DBSession.IOrder_MainDAL.GetListBy(x => memberIds.Contains(x.MemberId));                var orderIds = orderList.Select(x => x.OrderId).ToList();
                var orderProductList = DBSession.IOrder_ProductDAL.GetListBy(x => orderIds.Contains(x.OrderId) && x.ParentOrderProductId != Guid.Empty);
                //优惠券                var couponList = DBSession.IMember_CouponDAL.GetListBy(x => memberIds.Contains(x.MemberId));
                //兑换券                var itemCouponList = DBSession.IMember_TestItemCouponDAL.GetListBy(x => memberIds.Contains(x.MemberId));
                Guid catid = ConvertHelper.ToGuid(ConfigurationHelper.AppSetting("CatId"));
                var enumMemberCoupons = EnumberHelper.EnumToList<EnumMemberCoupon>();                var enumMemberTestItemCouponStates = EnumberHelper.EnumToList<EnumMemberTestItemCouponState>();
                //创建表格帮助类                int width = 4500;                short height = 400;                XSSFWorkbookCreateHelper bookHelper = new XSSFWorkbookCreateHelper(width, height);                List<CellModel> cells = new List<CellModel>();
                //当前行                int r = 0;
                //当前列                int c = 0;
                //表头                #region 表头                cells.Add(new CellModel(r, c++, "id", 1));                cells.Add(new CellModel(r, c++, "用户昵称", 1));                cells.Add(new CellModel(r, c++, "手机号", 1));                cells.Add(new CellModel(r, c++, "注册时间", 1));                cells.Add(new CellModel(r, c++, "最近一次消费时间", 1));                cells.Add(new CellModel(r, c++, "年龄", 1));                cells.Add(new CellModel(r, c++, "性别", 1));                cells.Add(new CellModel(r, c++, "累计充值金额", 1));
                List<CellModel> reLogs = new List<CellModel>()                {                    new CellModel(r+1, c++, "时间"),                    new CellModel(r+1, c++, "余额"),                    new CellModel(r+1, c++, "宠知因币"),                    new CellModel(r+1, c++, "操作人"),                    new CellModel(r+1, c++, "充值说明"),                };                cells.Add(new CellModel(r, c - reLogs.Count(), "充值记录", null, c - 1));                cells.AddRange(reLogs);

                cells.Add(new CellModel(r+1, c++, "账户余额", 1));                cells.Add(new CellModel(r+1, c++, "宠知因币", 1));                cells.Add(new CellModel(r+1, c++, "绑定宠物数量", 1));
                var petCels = new List<CellModel>()                 {                    new CellModel(r+1, c++, "昵称"),                    new CellModel(r+1, c++, "宠物编号"),                    new CellModel(r+1, c++, "品系"),                    new CellModel(r+1, c++, "品种")                };
                cells.Add(new CellModel(r, c-petCels.Count(), "绑定宠物信息", null, c - 1));                cells.AddRange(petCels);
                cells.Add(new CellModel(r, c++, "检测项目数量", 1));                cells.Add(new CellModel(r, c++, "订单数量", 1));                cells.Add(new CellModel(r, c++, "优惠券数量", 1));
                var couponCels = new List<CellModel>()                {                    new CellModel(r+1, c++, "优惠券名字"),                    new CellModel(r+1, c++, "获得时间"),                    new CellModel(r+1, c++, "是否使用"),                };
                cells.Add(new CellModel(r, c - couponCels.Count(), "优惠券明细", null, c - 1));                cells.AddRange(couponCels);
                cells.Add(new CellModel(r, c++, "兑换券数量", 1));                

                var testCouCels = new List<CellModel>()                {                    new CellModel(r+1, c++, "兑换券名字"),                    new CellModel(r+1, c++, "兑换券项目"),                    new CellModel(r+1, c++, "获得时间"),                    new CellModel(r+1, c++, "是否使用"),                };
                cells.Add(new CellModel(r, c - testCouCels.Count(), "兑换券明细", null, c - 1));                cells.AddRange(testCouCels);
                cells.Add(new CellModel(r, c++, "推荐人",1));                cells.Add(new CellModel(r, c++, "推荐人手机号",1));                cells.Add(new CellModel(r, c++, "绑定销售",1));                #endregion                //表头占两行                r = 1;
                //插入数据                int radd = 0;                var time = new DateTime(1750, 1, 1);                foreach (var item in dataList)                {                    r++;                    c = 0;                    #region 此用户数据                    var addresses = addressList.Where(x => x.MemberId == item.MemberId).ToList();                    int addressCount = addresses.Count();                    var blanceRecords = balanceRecordList.Where(x => x.MemberId == item.MemberId).ToList();                    int blanceCount = blanceRecords.Count();                    var pets = petList.Where(x => x.MemberId == item.MemberId).ToList();                    int petCount = pets.Count();                    var coupons = couponList.Where(x => x.MemberId == item.MemberId).ToList();                    int couponCount = coupons.Count();                    var itemCoupons = itemCouponList.Where(x => x.MemberId == item.MemberId).ToList();                    int itemCouponCount = itemCoupons.Count();
                    radd = blanceCount - 1;                    if (radd < petCount - 1)                    {                        radd = petCount - 1;                    }                    if (radd < addressCount - 1)                    {                        radd = addressCount - 1;                    }                    if (radd < couponCount - 1)                    {                        radd = couponCount - 1;                    }                    if (radd < itemCouponCount - 1)                    {                        radd = itemCouponCount - 1;                    }                    if (radd < 0)                    {                        radd = 0;                    }
                    var orders = orderList.Where(x => x.MemberId == item.MemberId).ToList();                    int orderCount = orders.Count();                    #endregion
                    bookHelper.AddCell(new CellModel(r, c++, item.MemberId.ToString(), r + radd));                    bookHelper.AddCell(new CellModel(r, c++, item.NickName, r + radd));                    bookHelper.AddCell(new CellModel(r, c++, item.Mobile, r + radd));                    bookHelper.AddCell(new CellModel(r, c++, item.CreateTime.ToString("yyyy-MM-dd HH:mm"), r + radd));
                    //最近一次消费时间,含充值                    bookHelper.AddCell(new CellModel(r, c++, item.LostPayTimeStr, r + radd));
                    //年龄                    bookHelper.AddCell(new CellModel(r, c++, "", r + radd));
                    var sex = item.Sex == 1 ? "男" : (item.Sex == 2 ? "女" : "未知");                    bookHelper.AddCell(new CellModel(r, c++, sex, r + radd));
                    //累计充值金额                    if (blanceCount > 0)                    {                        //累计充值金额                        var sumBlance = blanceRecords.Sum(x => x.RechargeAmount);                        bookHelper.AddCell(new CellModel(r, c, sumBlance.ToString("f2"), r + radd));
                        c++;
                        for (int i = 0; i < blanceCount; i++)                        {                            var blance = blanceRecords[i];                            bookHelper.AddCell(new CellModel(r + i, c + 0, blance.Createtime.ToString("yyyy-MM-dd HH:mm")));                            bookHelper.AddCell(new CellModel(r + i, c + 1, blance.RechargeAmount.ToString("f2")));                            bookHelper.AddCell(new CellModel(r + i, c + 2, blance.GiveAmount.ToString("f2")));
                            string accName = "系统执行";                            if (blance.LinkId != Guid.Empty)                            {                                var acc = accList.FirstOrDefault(x => x.AccountId == blance.LinkId);                                if (acc != null)                                {                                    accName = acc.Name;                                }                                else                                {                                    var accM = accMembers.FirstOrDefault(x => x.MemberId == blance.LinkId);                                    if (accM != null)                                    {                                        accName = accM.Mobile;                                    }                                }                            }                            bookHelper.AddCell(new CellModel(r + i, c + 3, accName));//操作人                            bookHelper.AddCell(new CellModel(r + i, c + 4, blance.ReMark));                        }                    }                    else                    {                        //累计充值金额占列                        c++;                    }                    c += reLogs.Count();
                    bookHelper.AddCell(new CellModel(r, c++, item.Cash.ToString("f2"), r + radd));                    bookHelper.AddCell(new CellModel(r, c++, item.CZYCoin.ToString("f2"), r + radd));
                    //绑定宠物数量                    bookHelper.AddCell(new CellModel(r, c++, petCount, r + radd));                    if (petCount > 0)                    {                        for (int i = 0; i < petCount; i++)                        {                            var pet = pets[i];                            bookHelper.AddCell(new CellModel(r + i, c + 0, pet.PetCNName));                            bookHelper.AddCell(new CellModel(r + i, c + 1, pet.PetNumber));
                            string className = "";                            if (classList.Any(x => x.ClassId == pet.ClassId))                            {                                className = classList.First(x => x.ClassId == pet.ClassId).ClassName;                            }                            bookHelper.AddCell(new CellModel(r + i, c + 2, className));                            bookHelper.AddCell(new CellModel(r + i, c + 3, StaticModel.SpecieNameCn(pet.SpeciesId)));                        }                    }                    c += petCels.Count();


                    var thisOrderIds = orders.Select(x => x.OrderId).ToList();                    var productCount = orderProductList.Count(x => thisOrderIds.Contains(x.OrderId));                    //检测项目数量                    bookHelper.AddCell(new CellModel(r, c++, productCount, r + radd));
                    //订单数量                    bookHelper.AddCell(new CellModel(r, c++, orderCount, r + radd));                    //优惠券数量                    bookHelper.AddCell(new CellModel(r, c++, couponCount, r + radd));
                    //优惠券明细//优惠券明细 和 兑换券明细 指的是获得的优惠券名字  获得时间  是否使用。                    if (couponCount > 0)                    {                        for (int i = 0; i < couponCount; i++)                        {                            var coupon = coupons[i];                            bookHelper.AddCell(new CellModel(r + i, c + 0, coupon.CouponName));                            bookHelper.AddCell(new CellModel(r + i, c + 1, coupon.CreateTime));                            var state = enumMemberCoupons.FirstOrDefault(x => x.EnumValue == coupon.State);                            if (state != null)                            {                                bookHelper.AddCell(new CellModel(r + i, c + 2, state.EnumName));                            }                        }                    }                    c += couponCels.Count();
                    //兑换券数量                    bookHelper.AddCell(new CellModel(r, c++, itemCouponCount, r + radd));
                    //兑换券明细                    if (itemCouponCount > 0)                    {                        for (int i = 0; i < itemCouponCount; i++)                        {                            var itemCoupon = itemCoupons[i];                            string pNames = "";                            if (itemCoupon.ProductList != null && itemCoupon.ProductList.Any())                            {                                foreach (var p in itemCoupon.ProductList)                                {                                    if (p != null)                                    {                                        pNames += "-" + p.ProductName;                                    }                                }                            }                            pNames = pNames.Trim('-');
                            bookHelper.AddCell(new CellModel(r + i, c + 0, itemCoupon.Remark));                            bookHelper.AddCell(new CellModel(r + i, c + 1, pNames));                            bookHelper.AddCell(new CellModel(r + i, c + 2, itemCoupon.CreateTime.ToString("yyyy-MM-dd HH:mm")));
                            var state = enumMemberTestItemCouponStates.FirstOrDefault(x => x.EnumValue == itemCoupon.IsUse);                            if (state != null)                            {                                bookHelper.AddCell(new CellModel(r + i, c + 3, state.EnumName));                            }                        }                    }                    c += testCouCels.Count();
                    //推荐人                    bookHelper.AddCell(new CellModel(r, c++, item.Channel_Contacts, r + radd));
                    bookHelper.AddCell(new CellModel(r, c++, item.Channel_Phone, r + radd));
                    bookHelper.AddCell(new CellModel(r, c++, item.SaleName, r + radd));
                    r += radd;                }
                foreach (var item in cells)                {                    bookHelper.AddCell(item);                }                return bookHelper;
            }            catch (Exception ex)            {
                Common.LogHelper.Instance.Error("导出分销会员数据出错", ex);                return null;            }        }        
        */
    /* 例js部分                    //导出excel详细            scope.ExportDetail = function () {                if (scope.rowCount > 10000) {                    alert("本次导出数据较多,成功导出后将自动下载,请勿频繁操作!如果失败请筛选减少数量。")                }                if (scope.rowCount > 0) {                    window.open("CreateExcelToRetailMember?searchJson=" + JSON.stringify(scope.SearchInfo));                }
            }     */}
posted @ 2020-10-24 13:35  lanofsky  阅读(557)  评论(0编辑  收藏  举报