using Microsoft.AspNetCore.Http;
using NPOI.HPSF;
using NPOI.HSSF.UserModel;
using NPOI.HSSF.Util;
using NPOI.SS.UserModel;
using NPOI.SS.Util;
using NPOI.XSSF.UserModel;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;

namespace Admin.Core.Common
{
    /// <summary>
    /// Npoi之Excel数据导出帮助类
    /// 创建Excel表格行列,设置行高,设置字体样式,单元格边框样式,单元格背景颜色和样式,单元格内容对齐方式等常用属性和样式封装
    /// </summary>
    public class ExcelHelper
    {
        public static ExcelHelper _exceltHelper
        {
            get => _exceltHelper ??= new ExcelHelper();
            set => _exceltHelper = value;
        }

        /// <summary>
        /// DataTable导出到Excel文件
        /// </summary>
        /// <param name="dt">源DataTable</param>
        /// <param name="strFileName">保存位置</param>
        public static string ExportTableExecl(DataTable dt, string strFileName)
        {
            //文件夹相对路径
            var fileRoot = FileHelper.GetFileRoot(FileActionType.Dow);
            //文件夹绝对路径
            var webRootPath = FileHelper.GetProgramPath() + fileRoot;
            strFileName = webRootPath + strFileName;
            using (MemoryStream ms = Exprot(dt))
            {
                using (FileStream fs = new FileStream(strFileName, FileMode.Create, FileAccess.Write))
                {
                    byte[] data = ms.ToArray();
                    fs.Write(data, 0, data.Length);
                    fs.Flush();
                }
            }
            return strFileName;
        }

        /// <summary>
        /// 将泛型的list 集合导出Execl 
        /// </summary>
        /// <typeparam name="T">实体对象</typeparam>
        /// <param name="list">集合</param>
        /// <param name="strFileName">文件名字</param>

        public static string ExportToList<T>(List<T> list, string strFileName)
        {
            //文件夹相对路径
            var fileRoot = FileHelper.GetFileRoot(FileActionType.Dow);
            //文件夹绝对路径
            var webRootPath = FileHelper.GetProgramPath() + fileRoot;
            strFileName = webRootPath + strFileName;
            using (MemoryStream ms = ExprotToList<T>(list))
            {
                using (FileStream fs = new FileStream(strFileName, FileMode.Create, FileAccess.Write))
                {
                    byte[] data = ms.ToArray();
                    fs.Write(data, 0, data.Length);
                    fs.Flush();
                }
            }
            return strFileName;
        }

        /// <summary>
        /// DataTable导出到Excel的MemoryStream
        /// </summary>
        /// <param name="dt">数据源DataTable</param>
        /// <returns></returns>
        public static MemoryStream Exprot(DataTable dt)
        {
            HSSFWorkbook workBook = new HSSFWorkbook();

            ISheet sheet = workBook.CreateSheet();

            #region 右键属性
            {
                DocumentSummaryInformation dsi = PropertySetFactory.CreateDocumentSummaryInformation();
                dsi.Company = "NPOI";
                workBook.DocumentSummaryInformation = dsi;

                SummaryInformation si = PropertySetFactory.CreateSummaryInformation();
                si.Author = "文件作者信息";
                si.ApplicationName = "创建程序信息";
                si.LastAuthor = "最后保存者信息";
                si.Comments = "作者信息";
                si.Title = "标题信息";
                si.Subject = "主题信息";
                si.CreateDateTime = DateTime.Now;
                workBook.SummaryInformation = si;
            }
            #endregion

            ICellStyle dateStyle = workBook.CreateCellStyle();
            IDataFormat dateFormat = workBook.CreateDataFormat();
            dateStyle.DataFormat = dateFormat.GetFormat("yyyy-MM-dd");

            //获取列宽
            int[] arrCollWidth = new int[dt.Columns.Count];

            foreach (DataColumn item in dt.Columns)
            {
                arrCollWidth[item.Ordinal] = Encoding.GetEncoding(936).GetBytes(item.ColumnName.ToString()).Length;
            }

            for (int i = 0; i < dt.Rows.Count; i++)
            {
                for (int j = 0; j < dt.Columns.Count; j++)
                {
                    int intTemp = Encoding.GetEncoding(936).GetBytes(dt.Rows[i][j].ToString()).Length;

                    if (intTemp > arrCollWidth[j])
                    {
                        arrCollWidth[j] = intTemp;
                    }

                }
            }

            int rowIndex = 0;

            foreach (DataRow item in dt.Rows)
            {
                #region  新建表 填充表头 列头 样式
                {
                    if (rowIndex == 65535 || rowIndex == 0)
                    {
                        if (rowIndex != 0)
                        {
                            sheet = workBook.CreateSheet();
                        }

                        #region 列头及样式
                        {
                            IRow headRow = sheet.CreateRow(1);
                            ICellStyle headerStyle = workBook.CreateCellStyle();
                            headerStyle.Alignment = NPOI.SS.UserModel.HorizontalAlignment.Center;

                            IFont font = workBook.CreateFont();
                            font.FontHeightInPoints = 10;
                            font.Boldweight = 700;
                            headerStyle.SetFont(font);

                            foreach (DataColumn cl in dt.Columns)
                            {
                                headRow.CreateCell(cl.Ordinal).SetCellValue(cl.ColumnName);
                                headRow.GetCell(cl.Ordinal).CellStyle = headerStyle;

                                //设置列宽
                                sheet.SetColumnWidth(cl.Ordinal, (arrCollWidth[cl.Ordinal] + 1) * 256);
                            }
                        }
                        #endregion

                        rowIndex = 2;
                    }
                }
                #endregion


                #region 填充内容
                {


                    IRow row = sheet.CreateRow(rowIndex);
                    foreach (DataColumn column in dt.Columns)
                    {
                        ICell cell = row.CreateCell(column.Ordinal);

                        string drValue = item[column].ToString();

                        switch (column.DataType.ToString())
                        {
                            case "System.String":
                                cell.SetCellValue(drValue);
                                break;

                            case "System.DateTime":
                                DateTime dateV;
                                DateTime.TryParse(drValue, out dateV);
                                cell.SetCellValue(dateV);

                                cell.CellStyle = dateStyle;
                                break;

                            case "System.Boolean":
                                bool boolV;
                                bool.TryParse(drValue, out boolV);
                                cell.SetCellValue(boolV);
                                break;

                            case "System.Int16":
                            case "System.Int32":
                            case "System.Int64":
                            case "System.Byte":
                                int intV = 0;
                                int.TryParse(drValue, out intV);
                                cell.SetCellValue(intV);
                                break;

                            case "System.Decimal":
                            case "System.Double":
                                double doubleV = 0;
                                double.TryParse(drValue, out doubleV);
                                cell.SetCellValue(doubleV);
                                break;

                            case "System.DBNull":
                                cell.SetCellValue("");
                                break;
                            default:
                                cell.SetCellValue("");
                                break;
                        }
                    }


                }
                #endregion

                rowIndex++;
            }

            using (MemoryStream ms = new MemoryStream())
            {
                workBook.Write(ms);
                ms.Flush();
                ms.Position = 0;
                //sheet.Dispose();
                //workBook.Dispose();
                return ms;
            }

        }

        /// <summary>
        /// 将list 集合导处 Execl
        /// </summary>
        /// <param name="list">泛型集合</param>
        /// <returns></returns>
        public static MemoryStream ExprotToList<T>(List<T> list)
        {

            HSSFWorkbook workbook = new HSSFWorkbook();
            ISheet sheet = workbook.CreateSheet();

            //创建样式

            ICellStyle cellStyle = workbook.CreateCellStyle();
            IDataFormat dataFormat = workbook.CreateDataFormat();
            cellStyle.DataFormat = dataFormat.GetFormat("yyyy-MM-dd");

            //表头样式
            IRow headerRow = sheet.CreateRow(0);
            headerRow.HeightInPoints = 25;

            ICellStyle headerStyle = workbook.CreateCellStyle();
            headerStyle.Alignment = NPOI.SS.UserModel.HorizontalAlignment.Center;
            IFont font = workbook.CreateFont();
            font.FontHeightInPoints = 20;
            font.Boldweight = 700;
            headerStyle.SetFont(font);

            headerRow.GetCell(0).CellStyle = headerStyle;
            sheet.AddMergedRegion(new CellRangeAddress(0, 0, 0, list[0].GetType().GetProperties().Length - 1));

            IRow rows = sheet.CreateRow(1);

            //获取list属性值
            PropertyInfo[] propertyInfo = list[0].GetType().GetProperties();

            #region 获取实体的属性值  
            {

                for (int i = 0; i < propertyInfo.Length; i++)
                {
                    rows.CreateCell(i).SetCellValue(propertyInfo[i].Name.ToString());
                }
            }
            #endregion

            //填充内容
            int propertyIndex = 2;

            foreach (var item in list)
            {
                IRow row = sheet.CreateRow(propertyIndex);

                for (int i = 0; i < propertyInfo.Length; i++)
                {
                    var obj = propertyInfo[i].GetValue(item, null);

                    row.CreateCell(i).SetCellValue(obj.ToString());
                }

                propertyIndex++;
            }

            //宽度自适应
            for (int i = 0; i < list.Count; i++)
            {
                sheet.AutoSizeColumn(i);
            }

            using (MemoryStream ms = new MemoryStream())
            {
                workbook.Write(ms);
                ms.Flush();
                ms.Position = 0;
                return ms;
            }

        }

        /// <summary>
        /// T 实体类必须指定DisplayName,根据DisplayName 生成列名
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="filePath"></param>
        /// <param name="data"></param>
        /// <returns></returns>
        public static string CreateExcel<T>(string strFileName, List<T> data) where T : class
        {
            try
            {
                //文件夹相对路径
                var fileRoot = FileHelper.GetFileRoot(FileActionType.Dow);
                //文件夹绝对路径
                var webRootPath = FileHelper.GetProgramPath() + fileRoot;
                strFileName = webRootPath + strFileName;
                XSSFWorkbook workbook = new XSSFWorkbook();
                ISheet sheet1 = workbook.CreateSheet("Sheet1");

                IRow headerRow = sheet1.CreateRow(0);
                //列名
                PropertyInfo[] columnsPropertyInfo = data.FirstOrDefault().GetType().GetProperties();
                int cellCount = 0;
                foreach (var column in columnsPropertyInfo)
                {
                    //根据实体类中DisplayName 生成列名
                    headerRow.CreateCell(cellCount).SetCellValue(column.GetCustomAttribute<DisplayNameAttribute>().DisplayName);
                    cellCount++;
                }
                //item
                int rowCount = 1;
                foreach (T item in data)
                {
                    IRow row = sheet1.CreateRow(rowCount);
                    int count = 0;
                    foreach (PropertyInfo propertyInfo in item.GetType().GetProperties())
                    {
                        row.CreateCell(count).SetCellValue(propertyInfo.GetValue(item, null).ToString());
                        count++;
                    }
                    rowCount++;
                }

                using (var f = File.Create(strFileName))
                {
                    workbook.Write(f);
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
            return strFileName;
        }

        /// <summary>
        /// T 实体类必须指定DisplayName,根据DisplayName 生成列名
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="filePath"></param>
        /// <param name="data"></param>
        /// <returns></returns>
        public static string CreateExcelToDW<T>(string strFileName, List<T> data, List<PJTypeView> typeViews, string title) where T : class
        {
            string newfilePath = string.Empty;
            try
            {
                //文件夹相对路径
                var fileRoot = FileHelper.GetFileRoot(FileActionType.Dow);
                //文件夹绝对路径
                var webRootPath = FileHelper.GetProgramPath() + fileRoot;
                if (!Directory.Exists(webRootPath))
                {
                    Directory.CreateDirectory(webRootPath);
                }
                newfilePath = fileRoot + strFileName;
                strFileName = webRootPath + strFileName;
                XSSFWorkbook workbook = new XSSFWorkbook();
                ISheet sheet1 = workbook.CreateSheet("Sheet1");

                /* 设置样式-内容 */
                ICellStyle notesStyle = workbook.CreateCellStyle();
                //设置换行这个要先设置
                notesStyle.WrapText = true;
                //下边框线
                notesStyle.BorderBottom = BorderStyle.Thin;
                //左边框线
                notesStyle.BorderLeft = BorderStyle.Thin;
                //右边框线
                notesStyle.BorderRight = BorderStyle.Thin;
                //上边框线
                notesStyle.BorderTop = BorderStyle.Thin;
                //垂直居中
                notesStyle.VerticalAlignment = VerticalAlignment.Center;
                //左对齐
                notesStyle.Alignment = HorizontalAlignment.Left;

                /* 设置样式-列 */
                ICellStyle titleStyle = workbook.CreateCellStyle();
                //设置换行这个要先设置
                titleStyle.WrapText = true;
                //下边框线
                titleStyle.BorderBottom = BorderStyle.Thin;
                //左边框线
                titleStyle.BorderLeft = BorderStyle.Thin;
                //右边框线
                titleStyle.BorderRight = BorderStyle.Thin;
                //上边框线
                titleStyle.BorderTop = BorderStyle.Thin;
                //垂直居中
                titleStyle.VerticalAlignment = VerticalAlignment.Center;
                //左对齐
                titleStyle.Alignment = HorizontalAlignment.Center;
                //设置字体加粗
                var font = workbook.CreateFont();
                font.Boldweight = (short)FontBoldWeight.Bold;
                titleStyle.SetFont(font);

                /* 设置样式-项目类型 */
                ICellStyle typeStyle = workbook.CreateCellStyle();
                //设置换行这个要先设置
                typeStyle.WrapText = true;
                //下边框线
                //typeStyle.BorderBottom = BorderStyle.Thin;
                //左边框线
                //typeStyle.BorderLeft = BorderStyle.Thin;
                //右边框线
                //typeStyle.BorderRight = BorderStyle.Thin;
                //上边框线
                //typeStyle.BorderTop = BorderStyle.Thin;
                //垂直居中
                typeStyle.VerticalAlignment = VerticalAlignment.Center;
                //左对齐
                typeStyle.Alignment = HorizontalAlignment.Left;
                //设置字体加粗
                var typeFont = workbook.CreateFont();
                typeFont.Boldweight = (short)FontBoldWeight.Bold;
                typeFont.FontHeightInPoints = 14;
                typeStyle.SetFont(typeFont);

                /* 设置样式-标题 */
                ICellStyle mainStyle = workbook.CreateCellStyle();
                //设置换行这个要先设置
                mainStyle.WrapText = true;
                //下边框线
                //typeStyle.BorderBottom = BorderStyle.Thin;
                //左边框线
                //typeStyle.BorderLeft = BorderStyle.Thin;
                //右边框线
                //typeStyle.BorderRight = BorderStyle.Thin;
                //上边框线
                //typeStyle.BorderTop = BorderStyle.Thin;
                //垂直居中
                mainStyle.VerticalAlignment = VerticalAlignment.Center;
                //左对齐
                mainStyle.Alignment = HorizontalAlignment.Center;
                //设置字体加粗
                var mainFont = workbook.CreateFont();
                mainFont.Boldweight = (short)FontBoldWeight.Bold;
                mainFont.FontHeightInPoints = 16;
                mainStyle.SetFont(mainFont);

                //设置单元格宽度
                sheet1.SetColumnWidth(0, 4 * 200);
                sheet1.SetColumnWidth(1, 15 * 200);
                sheet1.SetColumnWidth(2, 12 * 200);
                sheet1.SetColumnWidth(3, 40 * 200);
                sheet1.SetColumnWidth(4, 20 * 200);
                sheet1.SetColumnWidth(5, 6 * 200);
                sheet1.SetColumnWidth(6, 15 * 200);
                sheet1.SetColumnWidth(7, 3 * 200);
                sheet1.SetColumnWidth(8, 3 * 200);
                sheet1.SetColumnWidth(9, 3 * 200);
                sheet1.SetColumnWidth(10, 3 * 200);
                sheet1.SetColumnWidth(11, 3 * 200);
                sheet1.SetColumnWidth(12, 3 * 200);
                sheet1.SetColumnWidth(13, 6 * 200);
                sheet1.SetColumnWidth(14, 6 * 200);
                sheet1.SetColumnWidth(15, 6 * 200);
                sheet1.SetColumnWidth(16, 3 * 200);
                sheet1.SetColumnWidth(17, 9 * 200);
                sheet1.SetColumnWidth(18, 6 * 200);

                //创建标题
                sheet1.CreateRow(0);
                sheet1.CreateRow(1);
                sheet1.CreateRow(2);
                sheet1.CreateRow(3);
                PropertyInfo[] columnsPropertyInfo = data.FirstOrDefault().GetType().GetProperties();
                int cellCount = 0;
                foreach (var column in columnsPropertyInfo)
                {
                    sheet1.GetRow(0).CreateCell(cellCount);
                    //sheet1.GetRow(0).GetCell(cellCount).CellStyle = titleStyle;
                    sheet1.GetRow(1).CreateCell(cellCount);
                    //sheet1.GetRow(1).GetCell(cellCount).CellStyle = titleStyle;
                    sheet1.GetRow(2).CreateCell(cellCount);
                    sheet1.GetRow(2).GetCell(cellCount).CellStyle = titleStyle;
                    sheet1.GetRow(3).CreateCell(cellCount);
                    sheet1.GetRow(3).GetCell(cellCount).CellStyle = titleStyle;
                    if (cellCount < 7 || cellCount > 16)
                    {
                        sheet1.AddMergedRegion(new CellRangeAddress(2, 3, cellCount, cellCount));
                    }
                    cellCount++;
                }

                sheet1.AddMergedRegion(new CellRangeAddress(0, 0, 0, 18));
                sheet1.GetRow(0).GetCell(0).SetCellValue(title);
                sheet1.GetRow(0).GetCell(0).CellStyle = mainStyle;

                sheet1.AddMergedRegion(new CellRangeAddress(1, 1, 0, 18));
                var value = NumStr(0) + "、" + typeViews[0].Name + "类  ( " + typeViews[0].Num.ToString() + "个 ) ";
                sheet1.GetRow(1).GetCell(0).SetCellValue(value);
                sheet1.GetRow(1).GetCell(0).CellStyle = typeStyle;
                sheet1.AddMergedRegion(new CellRangeAddress(2, 2, 7, 16));

                int titleCount = 0;
                foreach (var column in columnsPropertyInfo)
                {
                    if (titleCount < 7 || titleCount > 16)
                    {
                        //根据实体类中DisplayName 生成列名
                        sheet1.GetRow(2).GetCell(titleCount).SetCellValue(column.GetCustomAttribute<DisplayNameAttribute>().DisplayName);
                    }
                    else
                    {
                        //根据实体类中DisplayName 生成列名
                        sheet1.GetRow(3).GetCell(titleCount).SetCellValue(column.GetCustomAttribute<DisplayNameAttribute>().DisplayName);
                    }
                    //设置换行
                    sheet1.GetRow(2).GetCell(titleCount).CellStyle = titleStyle;
                    titleCount++;
                }
                sheet1.GetRow(0).Height = 8 * 180;
                sheet1.GetRow(1).Height = 3 * 180;
                sheet1.GetRow(2).Height = 6 * 180;

                sheet1.GetRow(2).GetCell(7).SetCellValue("主要手续办理情况\n(✔ 为已完成,▲ 为正在办理,\n— 为无需办理,⭕ 为未办理)");

                //创建行
                int rowCount = 4;
                foreach (T item in data)
                {
                    IRow row = sheet1.CreateRow(rowCount);
                    int count = 0;
                    foreach (PropertyInfo propertyInfo in item.GetType().GetProperties())
                    {
                        var content = row.CreateCell(count);
                        content.SetCellValue(propertyInfo.GetValue(item, null).ToString());
                        //设置换行
                        content.CellStyle = notesStyle;
                        count++;
                    }
                    rowCount++;
                }

                //插入项目类型
                var rowIndex = 1;
                //var LastRowNum = data.Count + 1;
                for (int i = 1; i < typeViews.Count; i++)
                {
                    var type = typeViews[i];
                    cellCount = 0;
                    rowIndex += typeViews[i - 1].Num + 3;
                    //LastRowNum += 3;
                    sheet1.ShiftRows(rowIndex, sheet1.LastRowNum, 3);
                    //创建行
                    sheet1.CreateRow(rowIndex);
                    sheet1.CreateRow(rowIndex + 1);
                    sheet1.CreateRow(rowIndex + 2);
                    foreach (var column in columnsPropertyInfo)
                    {
                        //创建单元格
                        sheet1.GetRow(rowIndex).CreateCell(cellCount);
                        //创建单元格样式
                        //sheet1.GetRow(rowIndex).GetCell(cellCount).CellStyle = titleStyle;
                        sheet1.GetRow(rowIndex + 1).CreateCell(cellCount);
                        sheet1.GetRow(rowIndex + 1).GetCell(cellCount).CellStyle = titleStyle;
                        sheet1.GetRow(rowIndex + 2).CreateCell(cellCount);
                        sheet1.GetRow(rowIndex + 2).GetCell(cellCount).CellStyle = titleStyle;

                        if (cellCount < 7 || cellCount > 16)
                        {
                            sheet1.AddMergedRegion(new CellRangeAddress(rowIndex + 1, rowIndex + 2, cellCount, cellCount));
                        }
                        cellCount++;
                    }
                    //手续办理合并单元格
                    sheet1.AddMergedRegion(new CellRangeAddress(rowIndex + 1, rowIndex + 1, 7, 16));
                    //项目类型行合并单元格并赋值
                    sheet1.AddMergedRegion(new CellRangeAddress(rowIndex, rowIndex, 0, 18));
                    value = NumStr(i) + "、" + type.Name + "类  ( " + type.Num.ToString() + "个 ) ";
                    sheet1.GetRow(rowIndex).GetCell(0).SetCellValue(value);
                    sheet1.GetRow(rowIndex).GetCell(0).CellStyle = typeStyle;
                    sheet1.GetRow(rowIndex).Height = 3 * 180;

                    //单元格标题赋值
                    titleCount = 0;
                    foreach (var column in columnsPropertyInfo)
                    {
                        if (titleCount < 7 || titleCount > 16)
                        {
                            //根据实体类中DisplayName 生成列名
                            sheet1.GetRow(rowIndex + 1).GetCell(titleCount).SetCellValue(column.GetCustomAttribute<DisplayNameAttribute>().DisplayName);
                        }
                        else
                        {
                            //根据实体类中DisplayName 生成列名
                            sheet1.GetRow(rowIndex + 2).GetCell(titleCount).SetCellValue(column.GetCustomAttribute<DisplayNameAttribute>().DisplayName);
                        }
                        //设置换行
                        sheet1.GetRow(rowIndex + 1).GetCell(titleCount).CellStyle = titleStyle;
                        titleCount++;
                    }
                    //设置单元格高度
                    sheet1.GetRow(rowIndex + 1).Height = 6 * 180;
                    sheet1.GetRow(rowIndex + 1).GetCell(7).SetCellValue("主要手续办理情况\n(✔ 为已完成,▲ 为正在办理,\n— 为无需办理,⭕ 为未办理)");
                }

                using (var f = File.Create(strFileName))
                {
                    workbook.Write(f);
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
            return newfilePath;
        }

        /// <summary>
        /// 数字转中文
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public static string NumStr(int key)
        {
            switch (key)
            {
                case 0:
                    return "一";
                case 1:
                    return "二";
                case 2:
                    return "三";
                case 3:
                    return "四";
                case 4:
                    return "五";
                case 5:
                    return "六";
                case 6:
                    return "七";
                case 7:
                    return "八";
                default: return "";
            }
        }

        /// <summary>
        /// 读取Execl 表格
        /// </summary>
        /// <param name="fileName">文件路径</param>
        /// <returns></returns>
        public static DataTable GetReaderExecl(string fileName)
        {
            //文件夹绝对路径
            var webRootPath = FileHelper.GetProgramPath();
            fileName = webRootPath + fileName;

            DataTable dt = new DataTable();

            HSSFWorkbook workBook;

            using (FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.Read))
            {
                workBook = new HSSFWorkbook(fs);
            }

            ISheet sheet = workBook.GetSheetAt(0);
            System.Collections.IEnumerator rows = sheet.GetRowEnumerator();

            IRow headerRow = sheet.GetRow(0);
            int cellCount = headerRow.LastCellNum;

            for (int i = 0; i < cellCount; i++)
            {
                ICell cell = headerRow.GetCell(i);
                dt.Columns.Add(cell.ToString());
            }

            for (int j = (sheet.FirstRowNum + 1); j <= sheet.LastRowNum; j++)
            {
                IRow row = sheet.GetRow(j);

                DataRow dr = dt.NewRow();

                for (int i = row.FirstCellNum; i <= cellCount; i++)
                {
                    if (row.GetCell(i) != null)
                    {
                        dr[i] = row.GetCell(i).ToString();
                    }
                }

                dt.Rows.Add(dr);
            }

            return dt;
        }

        /// <summary>
        /// TODO:先创建行,然后在创建对应的列
        /// 创建Excel中指定的行
        /// </summary>
        /// <param name="sheet">Excel工作表对象</param>
        /// <param name="rowNum">创建第几行(从0开始)</param>
        /// <param name="rowHeight">行高</param>
        public HSSFRow CreateRow(ISheet sheet, int rowNum, float rowHeight)
        {
            HSSFRow row = (HSSFRow)sheet.CreateRow(rowNum); //创建行
            row.HeightInPoints = rowHeight; //设置列头行高
            return row;
        }

        /// <summary>
        /// 创建行内指定的单元格
        /// </summary>
        /// <param name="row">需要创建单元格的行</param>
        /// <param name="cellStyle">单元格样式</param>
        /// <param name="cellNum">创建第几个单元格(从0开始)</param>
        /// <param name="cellValue">给单元格赋值</param>
        /// <returns></returns>
        public HSSFCell CreateCells(HSSFRow row, HSSFCellStyle cellStyle, int cellNum, string cellValue)
        {
            HSSFCell cell = (HSSFCell)row.CreateCell(cellNum); //创建单元格
            cell.CellStyle = cellStyle; //将样式绑定到单元格
            if (!string.IsNullOrWhiteSpace(cellValue))
            {
                //单元格赋值
                cell.SetCellValue(cellValue);
            }

            return cell;
        }

        /// <summary>
        /// 行内单元格常用样式设置
        /// </summary>
        /// <param name="workbook">Excel文件对象</param>
        /// <param name="hAlignment">水平布局方式</param>
        /// <param name="vAlignment">垂直布局方式</param>
        /// <param name="fontHeightInPoints">字体大小</param>
        /// <param name="isAddBorder">是否需要边框</param>
        /// <param name="boldWeight">字体加粗 (None = 0,Normal = 400,Bold = 700</param>
        /// <param name="fontName">字体(仿宋,楷体,宋体,微软雅黑...与Excel主题字体相对应)</param>
        /// <param name="isAddBorderColor">是否增加边框颜色</param>
        /// <param name="isItalic">是否将文字变为斜体</param>
        /// <param name="isLineFeed">是否自动换行</param>
        /// <param name="isAddCellBackground">是否增加单元格背景颜色</param>
        /// <param name="fillPattern">填充图案样式(FineDots 细点,SolidForeground立体前景,isAddFillPattern=true时存在)</param>
        /// <param name="cellBackgroundColor">单元格背景颜色(当isAddCellBackground=true时存在)</param>
        /// <param name="fontColor">字体颜色</param>
        /// <param name="underlineStyle">下划线样式(无下划线[None],单下划线[Single],双下划线[Double],会计用单下划线[SingleAccounting],会计用双下划线[DoubleAccounting])</param>
        /// <param name="typeOffset">字体上标下标(普通默认值[None],上标[Sub],下标[Super]),即字体在单元格内的上下偏移量</param>
        /// <param name="isStrikeout">是否显示删除线</param>
        /// <returns></returns>
        public HSSFCellStyle CreateStyle(HSSFWorkbook workbook, HorizontalAlignment hAlignment, VerticalAlignment vAlignment, short fontHeightInPoints,
            bool isAddBorder, short boldWeight, string fontName = "宋体", bool isAddBorderColor = true, bool isItalic = false, bool isLineFeed = false,
            bool isAddCellBackground = false, FillPattern fillPattern = FillPattern.NoFill, short cellBackgroundColor = HSSFColor.Yellow.Index,
            short fontColor = HSSFColor.Black.Index, FontUnderlineType underlineStyle = FontUnderlineType.None,
            FontSuperScript typeOffset = FontSuperScript.None, bool isStrikeout = false)
        {
            HSSFCellStyle cellStyle = (HSSFCellStyle)workbook.CreateCellStyle(); //创建列头单元格实例样式
            cellStyle.Alignment = hAlignment; //水平居中
            cellStyle.VerticalAlignment = vAlignment; //垂直居中
            cellStyle.WrapText = isLineFeed;//自动换行

            //背景颜色,边框颜色,字体颜色都是使用 HSSFColor属性中的对应调色板索引,关于 HSSFColor 颜色索引对照表,详情参考:https://www.cnblogs.com/Brainpan/p/5804167.html

            //TODO:引用了NPOI后可通过ICellStyle 接口的 FillForegroundColor 属性实现 Excel 单元格的背景色设置,FillPattern 为单元格背景色的填充样式

            //TODO:十分注意,要设置单元格背景色必须是FillForegroundColor和FillPattern两个属性同时设置,否则是不会显示背景颜色
            if (isAddCellBackground)
            {
                cellStyle.FillForegroundColor = cellBackgroundColor;//单元格背景颜色
                cellStyle.FillPattern = fillPattern;//填充图案样式(FineDots 细点,SolidForeground立体前景)
            }


            //是否增加边框
            if (isAddBorder)
            {
                //常用的边框样式 None(没有),Thin(细边框,瘦的),Medium(中等),Dashed(虚线),Dotted(星罗棋布的),Thick(厚的),Double(双倍),Hair(头发)[上右下左顺序设置]
                cellStyle.BorderBottom = BorderStyle.Thin;
                cellStyle.BorderRight = BorderStyle.Thin;
                cellStyle.BorderTop = BorderStyle.Thin;
                cellStyle.BorderLeft = BorderStyle.Thin;
            }

            //是否设置边框颜色
            if (isAddBorderColor)
            {
                //边框颜色[上右下左顺序设置]
                cellStyle.TopBorderColor = HSSFColor.DarkGreen.Index;//DarkGreen(黑绿色)
                cellStyle.RightBorderColor = HSSFColor.DarkGreen.Index;
                cellStyle.BottomBorderColor = HSSFColor.DarkGreen.Index;
                cellStyle.LeftBorderColor = HSSFColor.DarkGreen.Index;
            }

            /**
             * 设置相关字体样式
             */
            var cellStyleFont = (HSSFFont)workbook.CreateFont(); //创建字体

            //假如字体大小只需要是粗体的话直接使用下面该属性即可
            //cellStyleFont.IsBold = true;

            cellStyleFont.Boldweight = boldWeight; //字体加粗
            cellStyleFont.FontHeightInPoints = fontHeightInPoints; //字体大小
            cellStyleFont.FontName = fontName;//字体(仿宋,楷体,宋体 )
            cellStyleFont.Color = fontColor;//设置字体颜色
            cellStyleFont.IsItalic = isItalic;//是否将文字变为斜体
            cellStyleFont.Underline = underlineStyle;//字体下划线
            cellStyleFont.TypeOffset = typeOffset;//字体上标下标
            cellStyleFont.IsStrikeout = isStrikeout;//是否有删除线

            cellStyle.SetFont(cellStyleFont); //将字体绑定到样式
            return cellStyle;
        }


    }
}