久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

C#_.Net Core 3.1 WebAPI_Excel數(shù)據(jù)讀取與寫入_自定義解析封裝類_支持設(shè)置標(biāo)題行位置&使用excel表達(dá)式收集數(shù)據(jù)&單元格映射&amp

 怡紅公子0526 2020-04-21

  本篇博客園是被任務(wù)所逼,,而已有的使用nopi技術(shù)的文檔技術(shù)經(jīng)驗(yàn)又不支持我需要的應(yīng)對(duì)各種復(fù)雜需求的苛刻要求,,只能自己造輪子封裝了,由于需要應(yīng)對(duì)很多總類型的數(shù)據(jù)采集需求,,因此有了本篇博客的代碼封裝,,下面一點(diǎn)點(diǎn)介紹吧:

  項(xiàng)目框架:.net Core 3.1   

  Nuget包:DotNetCore.NPOI 1.2.2

 

  收集excel你有沒有遇到過一下痛點(diǎn):

  1-需要收集指定行標(biāo)題位置的數(shù)據(jù),我的標(biāo)題行不一定在第一行,。  這個(gè)和我的csv的文檔需求是一致的

  2-需要采集指定單元格位置的數(shù)據(jù)生成一個(gè)對(duì)象,,而不是一個(gè)列表。   這里我的方案是制定一個(gè)單元格映射類解決問題,。  單元格映射類,,支持表達(dá)式數(shù)據(jù)采集(我可能需要一個(gè)單元格的數(shù)據(jù)+另一個(gè)單元格的數(shù)據(jù)作為一個(gè)屬性等等)

  3-應(yīng)對(duì)不規(guī)范標(biāo)題無法轉(zhuǎn)出字符串進(jìn)行映射時(shí),能不能通過制定標(biāo)題的列下標(biāo)建立對(duì)應(yīng)關(guān)系,,進(jìn)行列表數(shù)據(jù)采集呢,?   本博客同時(shí)支持標(biāo)題字符串?dāng)?shù)據(jù)采集和標(biāo)題下標(biāo)數(shù)據(jù)采集,這個(gè)就牛逼了,。

  4-存儲(chǔ)含有表達(dá)式的數(shù)據(jù),,這個(gè)并不是難點(diǎn),由于很重要,,就在這里列一下

  5-應(yīng)對(duì)Excel模板文件的數(shù)據(jù)指定位置填入數(shù)據(jù),,該位置可能會(huì)變動(dòng)的解決方案。本文為了應(yīng)對(duì)該情況,,借助了單元格映射關(guān)系,,添加了模板參數(shù)名的屬性處理,可以應(yīng)對(duì)模板文件調(diào)整時(shí)的位置變動(dòng)問題,。

  6-一個(gè)能同時(shí)處理excel新老版本(.xls和.xlsx),,一個(gè)指定excel位置保存數(shù)據(jù),保存含有表達(dá)式的數(shù)據(jù),,一個(gè)可以將多個(gè)不同的數(shù)據(jù)組合存放到一個(gè)excel中的需求都可以滿足,。   

 

  痛點(diǎn)大概就是上面這些了,下面寫主要代碼吧,,供大家參考,,不過封裝的類方法有點(diǎn)多:

  

  本文借助了NPOI程序包做了業(yè)務(wù)封裝:  

 

  1-主要封裝類-ExcelHelper:

  該類包含很多輔助功能:比如自動(dòng)幫助尋找含有指定標(biāo)題名所在的位置,、表達(dá)式元素A1,B2對(duì)應(yīng)單元格位置的解析等等:

 

/// <summary>
    /// EXCEL幫助類
    /// </summary>
    /// <typeparam name="T">泛型類</typeparam>
    /// <typeparam name="TCollection">泛型類集合</typeparam>
    public class ExcelHelper
    {
        public ILogger Logger { get; set; }
        public ExcelHelper(ILogger<ExcelHelper> logger)
        {
            this.Logger = logger;
        }

        #region 創(chuàng)建工作表

        /// <summary>
        /// 將列表數(shù)據(jù)生成工作表
        /// </summary>
        /// <param name="tList">要導(dǎo)出的數(shù)據(jù)集</param>
        /// <param name="fieldNameAndShowNameDic">鍵值對(duì)集合(鍵:字段名,值:顯示名稱)</param>
        /// <param name="workbook">更新時(shí)添加:要更新的工作表</param>
        /// <param name="sheetName">指定要?jiǎng)?chuàng)建的sheet名稱時(shí)添加</param>
        /// <param name="excelFileDescription">讀取或插入定制需求時(shí)添加</param>
        /// <returns></returns>
        public IWorkbook CreateOrUpdateWorkbook<T>(List<T> tList, Dictionary<string, string> fieldNameAndShowNameDic, IWorkbook workbook = null, string sheetName = "sheet1", ExcelFileDescription excelFileDescription = null) where T : new()
        {
            List<ExcelTitleFieldMapper> titleMapperList = ExcelTitleFieldMapper.GetModelFieldMapper<T>(fieldNameAndShowNameDic);

            workbook = this.CreateOrUpdateWorkbook<T>(tList, titleMapperList, workbook, sheetName, excelFileDescription);
            return workbook;
        }
        /// <summary>
        /// 將列表數(shù)據(jù)生成工作表(T的屬性需要添加:屬性名列名映射關(guān)系)
        /// </summary>
        /// <param name="tList">要導(dǎo)出的數(shù)據(jù)集</param>
        /// <param name="workbook">更新時(shí)添加:要更新的工作表</param>
        /// <param name="sheetName">指定要?jiǎng)?chuàng)建的sheet名稱時(shí)添加</param>
        /// <param name="excelFileDescription">讀取或插入定制需求時(shí)添加</param>
        /// <returns></returns>
        public IWorkbook CreateOrUpdateWorkbook<T>(List<T> tList, IWorkbook workbook = null, string sheetName = "sheet1", ExcelFileDescription excelFileDescription = null) where T : new()
        {
            List<ExcelTitleFieldMapper> titleMapperList = ExcelTitleFieldMapper.GetModelFieldMapper<T>();

            workbook = this.CreateOrUpdateWorkbook<T>(tList, titleMapperList, workbook, sheetName, excelFileDescription);
            return workbook;
        }

        private IWorkbook CreateOrUpdateWorkbook<T>(List<T> tList, List<ExcelTitleFieldMapper> titleMapperList, IWorkbook workbook, string sheetName, ExcelFileDescription excelFileDescription = null)
        {
            //xls文件格式屬于老版本文件,,一個(gè)sheet最多保存65536行,;而xlsx屬于新版文件類型;
            //Excel 07 - 2003一個(gè)工作表最多可有65536行,,行用數(shù)字1—65536表示; 最多可有256列,,列用英文字母A—Z,AA—AZ,,BA—BZ,,……,IA—IV表示,;一個(gè)工作簿中最多含有255個(gè)工作表,,默認(rèn)情況下是三個(gè)工作表;
            //Excel 2007及以后版本,,一個(gè)工作表最多可有1048576行,,16384列;
            if (workbook == null)
            {
                workbook = new XSSFWorkbook();
                //workbook = new HSSFWorkbook();
            }
            ISheet worksheet = null;
            if (workbook.GetSheetIndex(sheetName) >= 0)
            {
                worksheet = workbook.GetSheet(sheetName);
            }
            else
            {
                worksheet = workbook.CreateSheet(sheetName);
            }

            IRow row1 = null;
            ICell cell = null;

            int defaultBeginTitleIndex = 0;
            if (excelFileDescription != null)
            {
                defaultBeginTitleIndex = excelFileDescription.TitleRowIndex;
            }

            PropertyInfo propertyInfo = null;
            T t = default(T);

            int tCount = tList.Count;
            int currentRowIndex = 0;
            int dataIndex = 0;
            do
            {
                row1 = worksheet.GetRow(currentRowIndex);
                if (row1 == null)
                {
                    row1 = worksheet.CreateRow(currentRowIndex);
                }

                if (currentRowIndex >= defaultBeginTitleIndex)
                {
                    //到達(dá)標(biāo)題行
                    if (currentRowIndex == defaultBeginTitleIndex)
                    {
                        int cellIndex = 0;
                        foreach (var titleMapper in titleMapperList)
                        {
                            cell = row1.GetCell(cellIndex);

                            if (cell == null)
                            {
                                cell = row1.CreateCell(cellIndex);
                            }
                            this.SetCellValue(cell, titleMapper.ExcelTitle, outputFormat: null);
                            cellIndex++;
                        }
                    }
                    //到達(dá)內(nèi)容行
                    else
                    {
                        dataIndex = currentRowIndex - defaultBeginTitleIndex - 1;
                        if (dataIndex <= tCount - 1)
                        {
                            t = tList[dataIndex];

                            int cellIndex = 0;
                            foreach (var titleMapper in titleMapperList)
                            {
                                propertyInfo = titleMapper.PropertyInfo;

                                cell = row1.GetCell(cellIndex);
                                if (cell == null)
                                {
                                    cell = row1.CreateCell(cellIndex);
                                }

                                this.SetCellValue<T>(cell, t, titleMapper);

                                cellIndex++;
                            }

                            //重要:設(shè)置行寬度自適應(yīng)(大批量添加數(shù)據(jù)時(shí),,該行代碼需要注釋,,否則會(huì)極大減緩Excel添加行的速度!)
                            //worksheet.AutoSizeColumn(i, true);
                        }
                    }
                }

                currentRowIndex++;

            } while (dataIndex < tCount - 1);

            //設(shè)置表達(dá)式重算(如果不添加該代碼,,表達(dá)式更新不出結(jié)果值)
            worksheet.ForceFormulaRecalculation = true;

            return workbook;
        }

        /// <summary>
        /// 將單元格數(shù)據(jù)列表生成工作表
        /// </summary>
        /// <param name="commonCellList">所有的單元格數(shù)據(jù)列表</param>
        /// <param name="workbook">更新時(shí)添加:要更新的工作表</param>
        /// <param name="sheetName">指定要?jiǎng)?chuàng)建的sheet名稱時(shí)添加</param>
        /// <returns></returns>
        public IWorkbook CreateOrUpdateWorkbook(CommonCellModelColl commonCellList, IWorkbook workbook = null, string sheetName = "sheet1")
        {
            //xls文件格式屬于老版本文件,,一個(gè)sheet最多保存65536行;而xlsx屬于新版文件類型,;
            //Excel 07 - 2003一個(gè)工作表最多可有65536行,,行用數(shù)字1—65536表示; 最多可有256列,列用英文字母A—Z,,AA—AZ,,BA—BZ,……,,IA—IV表示,;一個(gè)工作簿中最多含有255個(gè)工作表,,默認(rèn)情況下是三個(gè)工作表,;
            //Excel 2007及以后版本,一個(gè)工作表最多可有1048576行,,16384列,;
            if (workbook == null)
            {
                workbook = new XSSFWorkbook();
                //workbook = new HSSFWorkbook();
            }
            ISheet worksheet = null;
            if (workbook.GetSheetIndex(sheetName) >= 0)
            {
                worksheet = workbook.GetSheet(sheetName);
            }
            else
            {
                worksheet = workbook.CreateSheet(sheetName);
            }

            //設(shè)置首列顯示
            IRow row1 = null;
            int rowIndex = 0;
            int maxRowIndex = commonCellList.Max(m => m.ColumnIndex);
            int columnIndex = 0;
            int maxColumnIndex = 0;
            Dictionary<int, CommonCellModel> rowColumnIndexCellDIC = null;
            ICell cell = null;
            object cellValue = null;

            do
            {
                rowColumnIndexCellDIC = commonCellList.GetRawCellList(rowIndex).ToDictionary(m => m.ColumnIndex);
                maxColumnIndex = rowColumnIndexCellDIC.Count > 0 ? rowColumnIndexCellDIC.Keys.Max() : 0;

                if (rowColumnIndexCellDIC != null && rowColumnIndexCellDIC.Count > 0)
                {
                    row1 = worksheet.GetRow(rowIndex);
                    if (row1 == null)
                    {
                        row1 = worksheet.CreateRow(rowIndex);
                    }
                    columnIndex = 0;
                    do
                    {
                        cell = row1.GetCell(columnIndex);
                        if (cell == null)
                        {
                            cell = row1.CreateCell(columnIndex);
                        }

                        if (rowColumnIndexCellDIC.ContainsKey(columnIndex))
                        {
                            cellValue = rowColumnIndexCellDIC[columnIndex].CellValue;

                            this.SetCellValue(cell, cellValue, outputFormat: null, rowColumnIndexCellDIC[columnIndex].IsCellFormula);
                        }
                        columnIndex++;
                    } while (columnIndex <= maxColumnIndex);
                }
                rowIndex++;
            } while (rowIndex <= maxRowIndex);

            //設(shè)置表達(dá)式重算(如果不添加該代碼,表達(dá)式更新不出結(jié)果值)
            worksheet.ForceFormulaRecalculation = true;

            return workbook;
        }

        /// <summary>
        /// 更新模板文件數(shù)據(jù):將使用單元格映射的數(shù)據(jù)T存入模板文件中
        /// </summary>
        /// <param name="filePath">所有的單元格數(shù)據(jù)列表</param>
        /// <param name="t">添加了單元格參數(shù)映射的數(shù)據(jù)對(duì)象</param>
        /// <returns></returns>
        public IWorkbook CreateOrUpdateWorkbook<T>(string filePath, T t)
        {
            //該方法默認(rèn)替換模板數(shù)據(jù)在首個(gè)sheet里

            IWorkbook workbook = null;
            CommonCellModelColl commonCellColl = this._ReadCellList(filePath, out workbook);

            ISheet worksheet = workbook.GetSheetAt(0);

            //獲取t的單元格映射列表
            Dictionary<string, ExcelCellFieldMapper> tParamMapperDic = ExcelCellFieldMapper.GetModelFieldMapper<T>().ToDictionary(m => m.CellParamName);

            var rows = worksheet.GetRowEnumerator();
            IRow row;
            ICell cell;
            string cellValue;
            ExcelCellFieldMapper cellMapper;
            while (rows.MoveNext())
            {
                row = (XSSFRow)rows.Current;
                int cellCount = row.Cells.Count;

                for (int i = 0; i < cellCount; i++)
                {
                    cell = row.Cells[i];
                    cellValue = cell.ToString();
                    if (tParamMapperDic.ContainsKey(cellValue))
                    {
                        cellMapper = tParamMapperDic[cellValue];
                        this.SetCellValue<T>(cell, t, cellMapper);
                    }
                }

            }

            if (tParamMapperDic.Count > 0)
            {
                //循環(huán)所有單元格數(shù)據(jù)替換指定變量數(shù)據(jù)
                foreach (var cellItem in commonCellColl)
                {
                    cellValue = cellItem.CellValue.ToString();

                    if (tParamMapperDic.ContainsKey(cellValue))
                    {
                        cellItem.CellValue = tParamMapperDic[cellValue].PropertyInfo.GetValue(t);
                    }
                }
            }

            //設(shè)置表達(dá)式重算(如果不添加該代碼,,表達(dá)式更新不出結(jié)果值)
            worksheet.ForceFormulaRecalculation = true;

            return workbook;
        }

        #endregion

        #region 保存工作表到文件

        /// <summary>
        /// 保存Workbook數(shù)據(jù)為文件
        /// </summary>
        /// <param name="workbook"></param>
        /// <param name="fileDirectoryPath"></param>
        /// <param name="fileName"></param>
        public void SaveWorkbookToFile(IWorkbook workbook, string filePath)
        {
            //xls文件格式屬于老版本文件,,一個(gè)sheet最多保存65536行,;而xlsx屬于新版文件類型;
            //Excel 07 - 2003一個(gè)工作表最多可有65536行,,行用數(shù)字1—65536表示; 最多可有256列,,列用英文字母A—Z,AA—AZ,,BA—BZ,,……,IA—IV表示,;一個(gè)工作簿中最多含有255個(gè)工作表,,默認(rèn)情況下是三個(gè)工作表;
            //Excel 2007及以后版本,,一個(gè)工作表最多可有1048576行,,16384列;

            MemoryStream ms = new MemoryStream();
            //這句代碼非常重要,,如果不加,,會(huì)報(bào):打開的EXCEL格式與擴(kuò)展名指定的格式不一致
            ms.Seek(0, SeekOrigin.Begin);
            workbook.Write(ms);
            byte[] myByteArray = ms.GetBuffer();

            string fileDirectoryPath = filePath.Split('\\')[0];
            if (!Directory.Exists(fileDirectoryPath))
            {
                Directory.CreateDirectory(fileDirectoryPath);
            }
            string fileName = filePath.Replace(fileDirectoryPath, "");

            if (File.Exists(filePath))
            {
                File.Delete(filePath);
            }
            File.WriteAllBytes(filePath, myByteArray);
        }

        /// <summary>
        /// 保存workbook到字節(jié)流中(提供給API接口使用)
        /// </summary>
        /// <param name="workbook"></param>
        /// <returns></returns>
        public byte[] SaveWorkbookToByte(IWorkbook workbook)
        {
            MemoryStream stream = new MemoryStream();
            stream.Seek(0, SeekOrigin.Begin);
            workbook.Write(stream);

            byte[] byteArray = stream.GetBuffer();
            return byteArray;
        }

        #endregion

        #region 讀取Excel數(shù)據(jù)

        /// <summary>
        /// 讀取Excel數(shù)據(jù)1_手動(dòng)提供屬性信息和標(biāo)題對(duì)應(yīng)關(guān)系
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="filePath"></param>
        /// <param name="fieldNameAndShowNameDic"></param>
        /// <param name="excelFileDescription"></param>
        /// <returns></returns>
        public List<T> ReadTitleDataList<T>(string filePath, Dictionary<string, string> fieldNameAndShowNameDic, ExcelFileDescription excelFileDescription) where T : new()
        {
            //標(biāo)題屬性字典列表
            List<ExcelTitleFieldMapper> titleMapperList = ExcelTitleFieldMapper.GetModelFieldMapper<T>(fieldNameAndShowNameDic);

            List<T> tList = this._GetTList<T>(filePath, titleMapperList, excelFileDescription);
            return tList ?? new List<T>(0);
        }

        /// <summary>
        /// 讀取Excel數(shù)據(jù)2_使用Excel標(biāo)記特性和文件描述自動(dòng)創(chuàng)建關(guān)系
        /// </summary>
        /// <param name="filePath"></param>
        /// <param name="excelFileDescription"></param>
        /// <returns></returns>
        public List<T> ReadTitleDataList<T>(string filePath, ExcelFileDescription excelFileDescription) where T : new()
        {
            //標(biāo)題屬性字典列表
            List<ExcelTitleFieldMapper> titleMapperList = ExcelTitleFieldMapper.GetModelFieldMapper<T>();

            List<T> tList = this._GetTList<T>(filePath, titleMapperList, excelFileDescription);
            return tList ?? new List<T>(0);
        }

        private List<T> _GetTList<T>(string filePath, List<ExcelTitleFieldMapper> titleMapperList, ExcelFileDescription excelFileDescription) where T : new()
        {
            List<T> tList = new List<T>(500 * 10000);
            T t = default(T);

            using (FileStream fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read))
            {
                IWorkbook workbook = null;
                IFormulaEvaluator formulaEvaluator = null;

                try
                {
                    workbook = new XSSFWorkbook(fileStream);
                    formulaEvaluator = new XSSFFormulaEvaluator(workbook);
                }
                catch (Exception)
                {
                    workbook = new HSSFWorkbook(fileStream);
                    formulaEvaluator = new HSSFFormulaEvaluator(workbook);
                }

                int sheetCount = workbook.NumberOfSheets;

                int currentSheetIndex = 0;
                int currentSheetRowTitleIndex = -1;
                do
                {
                    var sheet = workbook.GetSheetAt(currentSheetIndex);

                    //標(biāo)題下標(biāo)屬性字典
                    Dictionary<int, ExcelTitleFieldMapper> sheetTitleIndexPropertyDic = new Dictionary<int, ExcelTitleFieldMapper>(0);

                    //如果沒有設(shè)置標(biāo)題行,則通過自動(dòng)查找方法獲取
                    if (excelFileDescription.TitleRowIndex < 0)
                    {
                        string[] titleArray = titleMapperList.Select(m => m.ExcelTitle).ToArray();
                        currentSheetRowTitleIndex = this.GetSheetTitleIndex(sheet, titleArray);
                    }
                    else
                    {
                        currentSheetRowTitleIndex = excelFileDescription.TitleRowIndex;
                    }

                    var rows = sheet.GetRowEnumerator();

                    bool isHaveTitleIndex = false;
                    //含有Excel行下標(biāo)
                    if (titleMapperList.Count > 0 && titleMapperList[0].ExcelTitleIndex >= 0)
                    {
                        isHaveTitleIndex = true;

                        foreach (var titleMapper in titleMapperList)
                        {
                            sheetTitleIndexPropertyDic.Add(titleMapper.ExcelTitleIndex, titleMapper);
                        }
                    }

                    PropertyInfo propertyInfo = null;
                    int currentRowIndex = 0;

                    while (rows.MoveNext())
                    {
                        IRow row = (IRow)rows.Current;
                        currentRowIndex = row.RowNum;

                        //到達(dá)標(biāo)題行
                        if (isHaveTitleIndex == false && currentRowIndex == currentSheetRowTitleIndex)
                        {
                            ICell cell = null;
                            string cellValue = null;
                            Dictionary<string, ExcelTitleFieldMapper> titleMapperDic = titleMapperList.ToDictionary(m => m.ExcelTitle);
                            for (int i = 0; i < row.Cells.Count; i++)
                            {
                                cell = row.Cells[i];
                                cellValue = cell.StringCellValue;
                                if (titleMapperDic.ContainsKey(cellValue))
                                {
                                    sheetTitleIndexPropertyDic.Add(i, titleMapperDic[cellValue]);
                                }
                            }
                        }

                        //到達(dá)內(nèi)容行
                        if (currentRowIndex > currentSheetRowTitleIndex)
                        {
                            t = new T();
                            ExcelTitleFieldMapper excelTitleFieldMapper = null;
                            foreach (var titleIndexItem in sheetTitleIndexPropertyDic)
                            {
                                ICell cell = row.GetCell(titleIndexItem.Key);

                                excelTitleFieldMapper = titleIndexItem.Value;

                                //沒有數(shù)據(jù)的單元格默認(rèn)為null
                                string cellValue = cell?.ToString() ?? "";
                                propertyInfo = excelTitleFieldMapper.PropertyInfo;
                                try
                                {
                                    if (excelTitleFieldMapper.IsCheckContentEmpty)
                                    {
                                        if (string.IsNullOrEmpty(cellValue))
                                        {
                                            t = default(T);
                                            break;
                                        }
                                    }

                                    if (excelTitleFieldMapper.IsCoordinateExpress || cell.CellType == CellType.Formula)
                                    {
                                        //讀取含有表達(dá)式的單元格值
                                        cellValue = formulaEvaluator.Evaluate(cell).StringValue;
                                        propertyInfo.SetValue(t, Convert.ChangeType(cellValue, propertyInfo.PropertyType));
                                    }
                                    else if (propertyInfo.PropertyType.IsEnum)
                                    {
                                        object enumObj = propertyInfo.PropertyType.InvokeMember(cellValue, BindingFlags.GetField, null, null, null);
                                        propertyInfo.SetValue(t, Convert.ChangeType(enumObj, propertyInfo.PropertyType));
                                    }
                                    else
                                    {
                                        propertyInfo.SetValue(t, Convert.ChangeType(cellValue, propertyInfo.PropertyType));
                                    }
                                }
                                catch (Exception e)
                                {
                                    this.Logger.LogError($"文件_{filePath}讀取{currentRowIndex + 1}行內(nèi)容失??!");
                                    t = default(T);
                                    break;
                                }
                            }
                            if (t != null)
                            {
                                tList.Add(t);
                            }
                        }
                    }

                    currentSheetIndex++;

                } while (currentSheetIndex + 1 <= sheetCount);
            }
            return tList ?? new List<T>(0);
        }

        /// <summary>
        /// 讀取文件的所有單元格數(shù)據(jù)
        /// </summary>
        /// <param name="filePath">文件路徑</param>
        /// <returns></returns>
        public CommonCellModelColl ReadCellList(string filePath)
        {
            IWorkbook workbook = null;

            CommonCellModelColl commonCellColl = this._ReadCellList(filePath, out workbook);
            return commonCellColl;
        }

        /// <summary>
        /// 讀取文件的所有單元格數(shù)據(jù)
        /// </summary>
        /// <param name="filePath">文件路徑</param>
        /// <returns></returns>
        public CommonCellModelColl ReadCellList(string filePath, out IWorkbook workbook)
        {
            CommonCellModelColl commonCellColl = this._ReadCellList(filePath, out workbook);
            return commonCellColl;
        }

        private CommonCellModelColl _ReadCellList(string filePath, out IWorkbook workbook)
        {
            CommonCellModelColl commonCellColl = new CommonCellModelColl(10000);
            CommonCellModel cellModel = null;
            workbook = null;

            using (FileStream fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read))
            {
                try
                {
                    workbook = new XSSFWorkbook(fileStream);
                }
                catch (Exception)
                {
                    workbook = new HSSFWorkbook(fileStream);
                }
                var sheet = workbook.GetSheetAt(0);

                var rows = sheet.GetRowEnumerator();
                List<ICell> cellList = null;
                ICell cell = null;

                //從第1行數(shù)據(jù)開始獲取
                while (rows.MoveNext())
                {
                    IRow row = (IRow)rows.Current;

                    cellList = row.Cells;
                    int cellCount = cellList.Count;

                    for (int i = 0; i < cellCount; i++)
                    {
                        cell = cellList[i];
                        cellModel = new CommonCellModel
                        {
                            RowIndex = row.RowNum,
                            ColumnIndex = i,
                            CellValue = cell.ToString(),
                            IsCellFormula = cell.CellType == CellType.Formula ? true : false
                        };
                        commonCellColl.Add(cellModel);
                    }
                }
            }
            return commonCellColl;
        }

        /// <summary>
        /// 獲取文件單元格數(shù)據(jù)對(duì)象
        /// </summary>
        /// <typeparam name="T">T的屬性必須標(biāo)記了ExcelCellAttribute</typeparam>
        /// <param name="filePath">文建路徑</param>
        /// <returns></returns>
        public T ReadCellData<T>(string filePath) where T : new()
        {
            T t = new T();

            this.Logger.LogInformation($"開始讀取{filePath}的數(shù)據(jù)...");

            CommonCellModelColl commonCellColl = this.ReadCellList(filePath);

            Dictionary<PropertyInfo, ExcelCellFieldMapper> propertyMapperDic = ExcelCellFieldMapper.GetModelFieldMapper<T>().ToDictionary(m => m.PropertyInfo);
            string cellExpress = null;
            string pValue = null;
            PropertyInfo propertyInfo = null;
            foreach (var item in propertyMapperDic)
            {
                cellExpress = item.Value.CellCoordinateExpress;
                propertyInfo = item.Key;
                pValue = this.GetVByExpress(cellExpress, propertyInfo, commonCellColl).ToString();
                if (!string.IsNullOrEmpty(pValue))
                {
                    propertyInfo.SetValue(t, Convert.ChangeType(pValue, propertyInfo.PropertyType));
                }
            }
            return t;
        }

        /// <summary>
        /// 獲取文件首個(gè)sheet的標(biāo)題位置
        /// </summary>
        /// <typeparam name="T">T必須做了標(biāo)題映射</typeparam>
        /// <param name="filePath"></param>
        /// <returns></returns>
        public int FileFirstSheetTitleIndex<T>(string filePath)
        {
            int titleIndex = 0;

            if (File.Exists(filePath))
            {
                using (FileStream fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read))
                {
                    IWorkbook workbook = null;
                    try
                    {
                        workbook = new XSSFWorkbook(fileStream);
                    }
                    catch (Exception)
                    {
                        workbook = new HSSFWorkbook(fileStream);
                    }

                    string[] titleArray = ExcelTitleFieldMapper.GetModelFieldMapper<T>().Select(m => m.ExcelTitle).ToArray();

                    ISheet sheet = workbook.GetSheetAt(0);
                    titleIndex = this.GetSheetTitleIndex(sheet, titleArray);
                }
            }

            return titleIndex;
        }

        /// <summary>
        /// 獲取文件首個(gè)sheet的標(biāo)題位置
        /// </summary>
        /// <param name="filePath"></param>
        /// <param name="titleNames"></param>
        /// <returns></returns>
        public int FileFirstSheetTitleIndex(string filePath, params string[] titleNames)
        {
            int titleIndex = 0;

            if (File.Exists(filePath))
            {
                using (FileStream fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read))
                {
                    IWorkbook workbook = null;
                    try
                    {
                        workbook = new XSSFWorkbook(fileStream);
                    }
                    catch (Exception)
                    {
                        workbook = new HSSFWorkbook(fileStream);
                    }
                    ISheet sheet = workbook.GetSheetAt(0);
                    titleIndex = this.GetSheetTitleIndex(sheet, titleNames);
                }
            }

            return titleIndex;
        }

        #endregion

        #region 輔助方法

        /// <summary>
        /// 返回單元格坐標(biāo)橫坐標(biāo)
        /// </summary>
        /// <param name="cellPoint">單元格坐標(biāo)(A1,B15...)</param>
        /// <param name="columnIndex">帶回:縱坐標(biāo)</param>
        /// <returns></returns>
        private int GetValueByZM(string cellPoint, out int columnIndex)
        {
            int rowIndex = 0;
            columnIndex = 0;

            Regex columnIndexRegex = new Regex("[a-zA-Z]+", RegexOptions.IgnoreCase);
            string columnZM = columnIndexRegex.Match(cellPoint).Value;

            rowIndex = Convert.ToInt32(cellPoint.Replace(columnZM, "")) - 1;

            int zmLen = 0;
            if (!string.IsNullOrEmpty(columnZM))
            {
                zmLen = columnZM.Length;
            }
            for (int i = zmLen - 1; i > -1; i--)
            {
                columnIndex += (int)Math.Pow((int)columnZM[i] - 64, (zmLen - i));
            }
            columnIndex = columnIndex - 1;
            return rowIndex;
        }

        /// <summary>
        /// 根據(jù)單元格表達(dá)式和單元格數(shù)據(jù)集獲取數(shù)據(jù)
        /// </summary>
        /// <param name="cellExpress">單元格表達(dá)式</param>
        /// <param name="commonCellColl">單元格數(shù)據(jù)集</param>
        /// <returns></returns>
        private object GetVByExpress(string cellExpress, PropertyInfo propertyInfo, CommonCellModelColl commonCellColl)
        {
            object value = null;

            //含有單元格表達(dá)式的取表達(dá)式值,沒有表達(dá)式的取單元格字符串
            if (!string.IsNullOrEmpty(cellExpress))
            {
                MatchCollection matchCollection = Regex.Matches(cellExpress, "\\w+");

                string point = null;

                int rowIndex = 0;
                int columnIndex = 0;

                string cellValue = null;
                System.Data.DataTable dt = new System.Data.DataTable();

                foreach (var item in matchCollection)
                {
                    point = item.ToString();
                    rowIndex = this.GetValueByZM(point, out columnIndex);

                    cellValue = commonCellColl[rowIndex, columnIndex]?.CellValue?.ToString() ?? "";

                    if (propertyInfo.PropertyType == typeof(decimal) || propertyInfo.PropertyType == typeof(double) || propertyInfo.PropertyType == typeof(int))
                    {
                        if (!string.IsNullOrEmpty(cellValue))
                        {
                            cellValue = cellValue.Replace(",", "");
                        }
                        else
                        {
                            cellValue = "0";
                        }
                    }
                    else
                    {
                        cellValue = $"'{cellValue}'";
                    }
                    cellExpress = cellExpress.Replace(item.ToString(), cellValue);
                }

                //執(zhí)行字符和數(shù)字的表達(dá)式計(jì)算(字符需要使用單引號(hào)包裹,,數(shù)字需要移除逗號(hào))
                value = dt.Compute(cellExpress, "");
            }

            return value ?? "";

        }

        /// <summary>
        /// 將數(shù)據(jù)放入單元格中
        /// </summary>
        /// <typeparam name="T">泛型類</typeparam>
        /// <param name="cell">單元格對(duì)象</param>
        /// <param name="t">泛型類數(shù)據(jù)</param>
        /// <param name="cellFieldMapper">單元格映射信息</param>
        private void SetCellValue<T>(ICell cell, T t, ExcelCellFieldMapper cellFieldMapper)
        {
            object cellValue = cellFieldMapper.PropertyInfo.GetValue(t);

            this.SetCellValue(cell, cellValue, cellFieldMapper?.OutputFormat);
        }
        /// <summary>
        /// 將數(shù)據(jù)放入單元格中
        /// </summary>
        /// <typeparam name="T">泛型類</typeparam>
        /// <param name="cell">單元格對(duì)象</param>
        /// <param name="t">泛型類數(shù)據(jù)</param>
        /// <param name="cellFieldMapper">單元格映射信息</param>
        private void SetCellValue<T>(ICell cell, T t, ExcelTitleFieldMapper cellFieldMapper)
        {
            object cellValue = cellFieldMapper.PropertyInfo.GetValue(t);

            this.SetCellValue(cell, cellValue, cellFieldMapper?.OutputFormat, cellFieldMapper?.IsCoordinateExpress ?? false);
        }

        /// <summary>
        /// 將數(shù)據(jù)放入單元格中
        /// </summary>
        /// <param name="cell">單元格對(duì)象</param>
        /// <param name="cellValue">數(shù)據(jù)</param>
        /// <param name="outputFormat">格式化字符串</param>
        /// <param name="isCoordinateExpress">是否是表達(dá)式數(shù)據(jù)</param>
        private void SetCellValue(ICell cell, object cellValue, string outputFormat, bool isCoordinateExpress = false)
        {
            if (cell != null)
            {
                if (isCoordinateExpress)
                {
                    cell.SetCellFormula(cellValue.ToString());
                }
                else
                {
                    if (!string.IsNullOrEmpty(outputFormat))
                    {
                        string formatValue = null;
                        IFormatProvider formatProvider = null;
                        if (cellValue is DateTime)
                        {
                            formatProvider = new DateTimeFormatInfo();
                            ((DateTimeFormatInfo)formatProvider).ShortDatePattern = outputFormat;
                        }
                        formatValue = ((IFormattable)cellValue).ToString(outputFormat, formatProvider);

                        cell.SetCellValue(formatValue);
                    }
                    else
                    {
                        if (cellValue is decimal || cellValue is double || cellValue is int)
                        {
                            cell.SetCellValue(Convert.ToDouble(cellValue));
                        }
                        else if (cellValue is DateTime)
                        {
                            cell.SetCellValue((DateTime)cellValue);
                        }
                        else if (cellValue is bool)
                        {
                            cell.SetCellValue((bool)cellValue);
                        }
                        else
                        {
                            cell.SetCellValue(cellValue.ToString());
                        }
                    }
                }
            }

        }

        /// <summary>
        /// 根據(jù)標(biāo)題名稱獲取標(biāo)題行下標(biāo)位置
        /// </summary>
        /// <param name="sheet">要查找的sheet</param>
        /// <param name="titleNames">標(biāo)題名稱</param>
        /// <returns></returns>
        private int GetSheetTitleIndex(ISheet sheet, params string[] titleNames)
        {
            int titleIndex = -1;

            if (sheet != null && titleNames != null && titleNames.Length > 0)
            {
                var rows = sheet.GetRowEnumerator();
                List<ICell> cellList = null;
                List<string> rowValueList = null;

                //從第1行數(shù)據(jù)開始獲取
                while (rows.MoveNext())
                {
                    IRow row = (IRow)rows.Current;

                    cellList = row.Cells;
                    rowValueList = new List<string>(cellList.Count);
                    foreach (var cell in cellList)
                    {
                        rowValueList.Add(cell.ToString());
                    }

                    bool isTitle = true;
                    foreach (var title in titleNames)
                    {
                        if (!rowValueList.Contains(title))
                        {
                            isTitle = false;
                            break;
                        }
                    }
                    if (isTitle)
                    {
                        titleIndex = row.RowNum;
                        break;
                    }
                }
            }
            return titleIndex;
        }

        #endregion

    }
View Code

 

  2-自定義單元格類:

  

public class CommonCellModel
    {
        public CommonCellModel() { }

        public CommonCellModel(int rowIndex, int columnIndex, object cellValue, bool isCellFormula = false)
        {
            this.RowIndex = rowIndex;
            this.ColumnIndex = columnIndex;
            this.CellValue = cellValue;
            this.IsCellFormula = isCellFormula;
        }

        public int RowIndex { get; set; }
        public int ColumnIndex { get; set; }
        public object CellValue { get; set; }

        /// <summary>
        /// 是否是單元格公式
        /// </summary>
        public bool IsCellFormula { get; set; }

    }

    public class CommonCellModelColl : List<CommonCellModel>, IList<CommonCellModel>
    {
        public CommonCellModelColl() { }
        public CommonCellModelColl(int capacity) : base(capacity)
        {

        }

        /// <summary>
        /// 根據(jù)行下標(biāo),,列下標(biāo)獲取單元格數(shù)據(jù)
        /// </summary>
        /// <param name="rowIndex"></param>
        /// <param name="columnIndex"></param>
        /// <returns></returns>
        public CommonCellModel this[int rowIndex, int columnIndex]
        {
            get
            {
                CommonCellModel cell = this.FirstOrDefault(m => m.RowIndex == rowIndex && m.ColumnIndex == columnIndex);
                return cell;
            }
            set
            {
                CommonCellModel cell = this.FirstOrDefault(m => m.RowIndex == rowIndex && m.ColumnIndex == columnIndex);
                if (cell != null)
                {
                    cell.CellValue = value.CellValue;
                }
            }
        }

        /// <summary>
        /// 所有一行所有的單元格數(shù)據(jù)
        /// </summary>
        /// <param name="rowIndex">行下標(biāo)</param>
        /// <returns></returns>
        public List<CommonCellModel> GetRawCellList(int rowIndex)
        {
            List<CommonCellModel> cellList = null;
            cellList = this.FindAll(m => m.RowIndex == rowIndex);

            return cellList ?? new List<CommonCellModel>(0);
        }

        /// <summary>
        /// 所有一列所有的單元格數(shù)據(jù)
        /// </summary>
        /// <param name="columnIndex">列下標(biāo)</param>
        /// <returns></returns>
        public List<CommonCellModel> GetColumnCellList(int columnIndex)
        {
            List<CommonCellModel> cellList = null;
            cellList = this.FindAll(m => m.ColumnIndex == columnIndex);

            return cellList ?? new List<CommonCellModel>(0);
        }

    }
View Code

 

  3-單元格特性類:

  

/// <summary>
    /// Excel單元格標(biāo)記特性
    /// </summary>
    [System.AttributeUsage(System.AttributeTargets.Field | System.AttributeTargets.Property, AllowMultiple = false)]
    public class ExcelCellAttribute : System.Attribute
    {
        /// <summary>
        /// 該參數(shù)用于收集數(shù)據(jù)存于固定位置的單元格數(shù)據(jù)(單元格坐標(biāo)表達(dá)式(如:A1,B2,C1+C2...橫坐標(biāo)使用26進(jìn)制字母,縱坐標(biāo)使用十進(jìn)制數(shù)字))
        /// </summary>
        public string CellCoordinateExpress { get; set; }

        /// <summary>
        /// 該參數(shù)用于替換模板文件的預(yù)定義變量使用({A} {B})
        /// </summary>
        public string CellParamName { get; set; }

        /// <summary>
        /// 字符輸出格式(數(shù)字和日期類型需要)
        /// </summary>
        public string OutputFormat { get; set; }

        public ExcelCellAttribute(string cellCoordinateExpress = null, string cellParamName = null)
        {
            CellCoordinateExpress = cellCoordinateExpress;
            CellParamName = cellParamName;
        }

        public ExcelCellAttribute(string cellCoordinateExpress, string cellParamName, string outputFormat) : this(cellCoordinateExpress, cellParamName)
        {
            OutputFormat = outputFormat;
        }
    }
View Code

 

  4-單元格屬性映射幫助類:

  

/// <summary>
    /// 單元格字段映射類
    /// </summary>
    internal class ExcelCellFieldMapper
    {
        /// <summary>
        /// 屬性信息
        /// </summary>
        public PropertyInfo PropertyInfo { get; set; }

        /// <summary>
        /// 該參數(shù)用于收集數(shù)據(jù)存于固定位置的單元格數(shù)據(jù)(單元格坐標(biāo)表達(dá)式(如:A1,B2,C1+C2...橫坐標(biāo)使用26進(jìn)制字母,,縱坐標(biāo)使用十進(jìn)制數(shù)字))
        /// </summary>
        public string CellCoordinateExpress { get; set; }

        /// <summary>
        /// 該參數(shù)用于替換模板文件的預(yù)定義變量使用({A} {B})
        /// </summary>
        public string CellParamName { get; set; }

        /// <summary>
        /// 字符輸出格式(數(shù)字和日期類型需要)
        /// </summary>
        public string OutputFormat { get; set; }

        /// <summary>
        /// 獲取對(duì)應(yīng)關(guān)系_T屬性添加了單元格映射關(guān)系
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public static List<ExcelCellFieldMapper> GetModelFieldMapper<T>()
        {
            List<ExcelCellFieldMapper> fieldMapperList = new List<ExcelCellFieldMapper>(100);

            List<PropertyInfo> tPropertyInfoList = typeof(T).GetProperties().ToList();
            ExcelCellAttribute cellExpress = null;

            foreach (var item in tPropertyInfoList)
            {
                cellExpress = item.GetCustomAttribute<ExcelCellAttribute>();
                if (cellExpress != null)
                {
                    fieldMapperList.Add(new ExcelCellFieldMapper
                    {
                        CellCoordinateExpress = cellExpress.CellCoordinateExpress,
                        CellParamName = cellExpress.CellParamName,
                        OutputFormat = cellExpress.OutputFormat,
                        PropertyInfo = item
                    });
                }
            }

            return fieldMapperList;
        }
    }
View Code

 

  5-Excel文件描述類:

 

public class ExcelFileDescription
    {
        /// <summary>
        /// 默認(rèn)從第1行數(shù)據(jù)開始讀取標(biāo)題數(shù)據(jù)
        /// </summary>
        public ExcelFileDescription() : this(0)
        {
        }

        public ExcelFileDescription(int titleRowIndex)
        {
            this.TitleRowIndex = titleRowIndex;
        }

        /// <summary>
        /// 標(biāo)題所在行位置(默認(rèn)為0,,沒有標(biāo)題填-1)
        /// </summary>
        public int TitleRowIndex { get; set; }

    }
View Code

 

  6-Excel標(biāo)題特性類:

 

/// <summary>
    /// Excel標(biāo)題標(biāo)記特性
    /// </summary>
    [System.AttributeUsage(System.AttributeTargets.Field | System.AttributeTargets.Property, AllowMultiple = false)]
    public class ExcelTitleAttribute : System.Attribute
    {
        /// <summary>
        /// Excel行標(biāo)題(標(biāo)題和下標(biāo)選擇一個(gè)即可)
        /// </summary>
        public string RowTitle { get; set; }
        /// <summary>
        /// Excel行下標(biāo)(標(biāo)題和下標(biāo)選擇一個(gè)即可,默認(rèn)值-1)
        /// </summary>
        public int RowTitleIndex { get; set; }

        /// <summary>
        /// 單元格是否要檢查空數(shù)據(jù)(true為檢查,為空的行數(shù)據(jù)不添加)
        /// </summary>
        public bool IsCheckContentEmpty { get; set; }

        /// <summary>
        /// 字符輸出格式(數(shù)字和日期類型需要)
        /// </summary>
        public string OutputFormat { get; set; }

        /// <summary>
        /// 是否是公式列
        /// </summary>
        public bool IsCoordinateExpress { get; set; }

        /// <summary>
        /// 標(biāo)題特性構(gòu)造方法
        /// </summary>
        /// <param name="title">標(biāo)題</param>
        /// <param name="isCheckEmpty">單元格是否要檢查空數(shù)據(jù)</param>
        /// <param name="isCoordinateExpress">是否是公式列</param>
        /// <param name="outputFormat">是否有格式化輸出要求</param>
        public ExcelTitleAttribute(string title, bool isCheckEmpty = false, bool isCoordinateExpress = false, string outputFormat = "")
        {
            RowTitle = title;
            IsCheckContentEmpty = isCheckEmpty;
            IsCoordinateExpress = isCoordinateExpress;
            OutputFormat = outputFormat;
            RowTitleIndex = -1;
        }

        public ExcelTitleAttribute(int titleIndex, bool isCheckEmpty = false, bool isCoordinateExpress = false, string outputFormat = "")
        {
            RowTitleIndex = titleIndex;
            IsCheckContentEmpty = isCheckEmpty;
            IsCoordinateExpress = isCoordinateExpress;
            OutputFormat = outputFormat;
        }
    }
View Code

 

  7-Ecel標(biāo)題屬性映射幫助類:

 

/// <summary>
    /// 標(biāo)題字段映射類
    /// </summary>
    internal class ExcelTitleFieldMapper
    {
        /// <summary>
        /// 屬性信息
        /// </summary>
        public PropertyInfo PropertyInfo { get; set; }
        /// <summary>
        /// 行標(biāo)題
        /// </summary>
        public string ExcelTitle { get; set; }
        /// <summary>
        /// 行標(biāo)題下標(biāo)位置
        /// </summary>
        public int ExcelTitleIndex { get; set; }
        /// <summary>
        /// 是否要做行內(nèi)容空檢查
        /// </summary>
        public bool IsCheckContentEmpty { get; set; }

        /// <summary>
        /// 字符輸出格式(數(shù)字和日期類型需要)
        /// </summary>
        public string OutputFormat { get; set; }

        /// <summary>
        /// 是否是公式列
        /// </summary>
        public bool IsCoordinateExpress { get; set; }

        /// <summary>
        /// 獲取對(duì)應(yīng)關(guān)系_T屬性添加了標(biāo)題映射關(guān)系
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public static List<ExcelTitleFieldMapper> GetModelFieldMapper<T>()
        {
            List<ExcelTitleFieldMapper> fieldMapperList = new List<ExcelTitleFieldMapper>(100);

            List<PropertyInfo> tPropertyInfoList = typeof(T).GetProperties().ToList();
            ExcelTitleAttribute excelTitleAttribute = null;
            foreach (var tPropertyInfo in tPropertyInfoList)
            {
                excelTitleAttribute = (ExcelTitleAttribute)tPropertyInfo.GetCustomAttribute(typeof(ExcelTitleAttribute));
                if (excelTitleAttribute != null)
                {
                    fieldMapperList.Add(new ExcelTitleFieldMapper
                    {
                        PropertyInfo = tPropertyInfo,
                        ExcelTitle = excelTitleAttribute.RowTitle,
                        ExcelTitleIndex = excelTitleAttribute.RowTitleIndex,
                        IsCheckContentEmpty = excelTitleAttribute.IsCheckContentEmpty,
                        OutputFormat = excelTitleAttribute.OutputFormat,
                        IsCoordinateExpress = excelTitleAttribute.IsCoordinateExpress
                    });
                }
            }
            return fieldMapperList;
        }

        /// <summary>
        /// 獲取對(duì)應(yīng)關(guān)系_手動(dòng)提供映射關(guān)系
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="fieldNameAndShowNameDic"></param>
        /// <returns></returns>
        public static List<ExcelTitleFieldMapper> GetModelFieldMapper<T>(Dictionary<string, string> fieldNameAndShowNameDic)
        {
            List<ExcelTitleFieldMapper> fieldMapperList = new List<ExcelTitleFieldMapper>(100);

            List<PropertyInfo> tPropertyInfoList = typeof(T).GetProperties().ToList();
            PropertyInfo propertyInfo = null;

            foreach (var item in fieldNameAndShowNameDic)
            {
                propertyInfo = tPropertyInfoList.Find(m => m.Name.Equals(item.Key, StringComparison.OrdinalIgnoreCase));

                fieldMapperList.Add(new ExcelTitleFieldMapper
                {
                    PropertyInfo = propertyInfo,
                    ExcelTitle = item.Value,
                    ExcelTitleIndex = -1,
                    OutputFormat = null,
                    IsCheckContentEmpty = false,
                    IsCoordinateExpress = false
                });
            }
            return fieldMapperList;
        }

        /// <summary>
        /// 獲取對(duì)應(yīng)關(guān)系_未提供(默認(rèn)屬性名和標(biāo)題名一致)
        /// </summary>
        /// <returns></returns>
        public static List<ExcelTitleFieldMapper> GetModelDefaultFieldMapper<T>()
        {
            List<ExcelTitleFieldMapper> fieldMapperList = new List<ExcelTitleFieldMapper>(100);

            List<PropertyInfo> tPropertyInfoList = typeof(T).GetProperties().ToList();

            foreach (var item in tPropertyInfoList)
            {
                fieldMapperList.Add(new ExcelTitleFieldMapper
                {
                    PropertyInfo = item,
                    ExcelTitle = item.Name,
                    ExcelTitleIndex = -1,
                    OutputFormat = null,
                    IsCheckContentEmpty = false,
                    IsCoordinateExpress = false
                });
            }
            return fieldMapperList;
        }

    }
View Code

 

  示例代碼1-單元格映射類:

  

/// <summary>
    /// 賬戶_多幣種交易報(bào)表_數(shù)據(jù)源
    /// </summary>
    public class AccountMultiCurrencyTransactionSource
    {
        /// <summary>
        /// 期初
        /// </summary>
        [ExcelCellAttribute("B9")]
        public decimal BeginingBalance { get; set; }

        /// <summary>
        /// 收款
        /// </summary>
        [ExcelCellAttribute("B19+C19")]
        public decimal TotalTransactionPrice { get; set; }

        /// <summary>
        /// 收到非EBay款項(xiàng)_主要指從其他賬戶轉(zhuǎn)給當(dāng)前賬戶的錢
        /// </summary>
        [ExcelCellAttribute("B21+C21")]
        public decimal TransferAccountInPrice { get; set; }

        /// <summary>
        /// 退款(客戶不提交爭議直接退款)
        /// </summary>
        [ExcelCellAttribute("B23+C23")]
        public decimal TotalRefundPrice { get; set; }

        /// <summary>
        /// 手續(xù)費(fèi)
        /// </summary>
        [ExcelCellAttribute("B25+C25")]
        public decimal TotalFeePrice { get; set; }

        /// <summary>
        /// 爭議退款
        /// </summary>
        [ExcelCellAttribute("B37+C37")]
        public decimal TotalChargebackRefundPrice { get; set; }

        /// <summary>
        /// 轉(zhuǎn)賬與提現(xiàn)(幣種轉(zhuǎn)換)
        /// </summary>
        [ExcelCellAttribute("B45+C45")]
        public decimal CurrencyChangePrice { get; set; }

        /// <summary>
        /// 轉(zhuǎn)賬與提現(xiàn)(轉(zhuǎn)賬到paypal賬戶)_提現(xiàn)失敗退回金額
        /// </summary>
        [ExcelCellAttribute("B47+C47")]
        public decimal CashWithdrawalInPrice { get; set; }

        /// <summary>
        /// 轉(zhuǎn)賬與提現(xiàn)(從paypal賬戶轉(zhuǎn)賬)_提現(xiàn)金額
        /// </summary>
        [ExcelCellAttribute("B49+C49")]
        public decimal CashWithdrawalOutPrice { get; set; }

        /// <summary>
        /// 購物_主要指從當(dāng)前賬戶轉(zhuǎn)給其他賬戶的錢
        /// </summary>
        [ExcelCellAttribute("B51+C51")]
        public decimal TransferAccountOutPrice { get; set; }

        /// <summary>
        /// 其他活動(dòng)
        /// </summary>
        [ExcelCellAttribute("B85+C85")]
        public decimal OtherPrice { get; set; }

        /// <summary>
        /// 期末
        /// </summary>
        [ExcelCellAttribute("C9")]
        public decimal EndingBalance { get; set; }

    }
View Code

 

  示例代碼2-標(biāo)題映射類(標(biāo)題映射分類字符串映射和下標(biāo)位置映射,,這里使用下標(biāo)位置映射):

  

/// <summary>
    /// 美元幣種轉(zhuǎn)換_數(shù)據(jù)源
    /// </summary>
    public class CurrencyChangeUSDSource
    {
        /// <summary>
        /// 日期[y/M/d]
        /// </summary>
        [ExcelTitleAttribute(0, true)]
        public DateTime Date { get; set; }
        /// <summary>
        /// 類型
        /// </summary>
        [ExcelTitleAttribute(1, true)]
        public string Type { get; set; }
        /// <summary>
        /// 交易號(hào)
        /// </summary>
        [ExcelTitleAttribute(2)]
        public string TX { get; set; }
        /// <summary>
        /// 商家/接收人姓名地址第1行地址第2行/區(qū)發(fā)款賬戶名稱_發(fā)款賬戶簡稱
        /// </summary>
        [ExcelTitleAttribute(3)]
        public string SendedOrReceivedName { get; set; }
        /// <summary>
        /// 電子郵件編號(hào)_發(fā)款賬戶全稱
        /// </summary>
        [ExcelTitleAttribute(4)]
        public string SendedOrReceivedAccountName { get; set; }
        /// <summary>
        /// 幣種
        /// </summary>
        [ExcelTitleAttribute(5)]
        public string CurrencyCode { get; set; }
        /// <summary>
        /// 總額
        /// </summary>
        [ExcelTitleAttribute(6)]
        public decimal TotalPrice { get; set; }
        /// <summary>
        /// 凈額
        /// </summary>
        [ExcelTitleAttribute(7)]
        public decimal NetPrice { get; set; }
        /// <summary>
        /// 費(fèi)用
        /// </summary>
        [ExcelTitleAttribute(8)]
        public decimal FeePrice { get; set; }
    }
View Code

  

  示例代碼3-模板文件數(shù)據(jù)替換-單元格映射類:

  

/// <summary>
    /// 多賬戶美元匯總金額_最終模板使用展示類
    /// </summary>
    public class AccountUSDSummaryTransaction
    {

        /// <summary>
        /// 期初
        /// </summary>
        [ExcelCellAttribute(cellParamName: "{DLZ_BeginingBalance}")]
        public decimal DLZ_BeginingBalance { get; set; }

        /// <summary>
        /// 收款
        /// </summary>
        [ExcelCellAttribute(cellParamName: "{DLZ_TotalTransactionPrice}")]
        public decimal DLZ_TotalTransactionPrice { get; set; }

        /// <summary>
        /// 收到非EBay款項(xiàng)_主要指從其他賬戶轉(zhuǎn)給當(dāng)前賬戶的錢
        /// </summary>
        [ExcelCellAttribute(cellParamName: "{DLZ_TransferAccountInPrice}")]
        public decimal DLZ_TransferAccountInPrice { get; set; }

        /// <summary>
        /// 退款(客戶不提交爭議直接退款)
        /// </summary>
        [ExcelCellAttribute(cellParamName: "{DLZ_TotalRefundPrice}")]
        public decimal DLZ_TotalRefundPrice { get; set; }

        /// <summary>
        /// 手續(xù)費(fèi)
        /// </summary>
        [ExcelCellAttribute(cellParamName: "{DLZ_TotalFeePrice}")]
        public decimal DLZ_TotalFeePrice { get; set; }

        /// <summary>
        /// 爭議退款
        /// </summary>
        [ExcelCellAttribute(cellParamName: "{DLZ_TotalChargebackRefundPrice}")]
        public decimal DLZ_TotalChargebackRefundPrice { get; set; }

        /// <summary>
        /// 轉(zhuǎn)賬與提現(xiàn)(幣種轉(zhuǎn)換)
        /// </summary>
        [ExcelCellAttribute(cellParamName: "{DLZ_CurrencyChangePrice}")]
        public decimal DLZ_CurrencyChangePrice { get; set; }

        /// <summary>
        /// 轉(zhuǎn)賬與提現(xiàn)(轉(zhuǎn)賬到paypal賬戶)_提現(xiàn)失敗退回金額
        /// </summary>
        [ExcelCellAttribute(cellParamName: "{DLZ_CashWithdrawalInPrice}")]
        public decimal DLZ_CashWithdrawalInPrice { get; set; }

        /// <summary>
        /// 轉(zhuǎn)賬與提現(xiàn)(從paypal賬戶轉(zhuǎn)賬)_提現(xiàn)金額
        /// </summary>
        [ExcelCellAttribute(cellParamName: "{DLZ_CashWithdrawalOutPrice}")]
        public decimal DLZ_CashWithdrawalOutPrice { get; set; }

        /// <summary>
        /// 購物_主要指從當(dāng)前賬戶轉(zhuǎn)給其他賬戶的錢
        /// </summary>
        [ExcelCellAttribute(cellParamName: "{DLZ_TransferAccountOutPrice}")]
        public decimal DLZ_TransferAccountOutPrice { get; set; }

        /// <summary>
        /// 其他活動(dòng)
        /// </summary>
        [ExcelCellAttribute(cellParamName: "{DLZ_OtherPrice}")]
        public decimal DLZ_OtherPrice { get; set; }

        /// <summary>
        /// 期末
        /// </summary>
        [ExcelCellAttribute(cellParamName: "{DLZ_EndingBalance}")]
        public decimal DLZ_EndingBalance
        {
            get
            {
                decimal result = this.DLZ_BeginingBalance + this.DLZ_TotalTransactionPrice + this.DLZ_TransferAccountInPrice
                                + this.DLZ_TotalRefundPrice + this.DLZ_TotalFeePrice + this.DLZ_TotalChargebackRefundPrice + this.DLZ_CurrencyChangePrice
                                + this.DLZ_CashWithdrawalInPrice + this.DLZ_CashWithdrawalOutPrice + this.DLZ_TransferAccountOutPrice + this.DLZ_OtherPrice;
                return result;
            }
        }

        /// <summary>
        /// 期末匯率差
        /// </summary>
        [ExcelCellAttribute(cellParamName: "{DLZ_EndingBalanceDifferenceValue}")]
        public decimal DLZ_EndingBalanceDifferenceValue
        {
            get
            {
                return this.DLZ_RealRateEndingBalance - this.DLZ_EndingBalance;
            }
        }

        /// <summary>
        /// 真實(shí)匯率計(jì)算的期末余額
        /// </summary>
        [ExcelCellAttribute(cellParamName: "{DLZ_RealRateEndingBalance}")]
        public decimal DLZ_RealRateEndingBalance { get; set; }



    }
View Code

 

  示例代碼4-存儲(chǔ)多個(gè)數(shù)據(jù)源到一個(gè)Excel中(這里我是保存到了不同的sheet頁里,,當(dāng)然也可以保持到同一個(gè)sheet的不同位置):

  

IWorkbook workbook = null;

            workbook = ExcelHelper.CreateOrUpdateWorkbook(dlzShopList, workbook, "獨(dú)立站");
            workbook = ExcelHelper.CreateOrUpdateWorkbook(ebayShopList, workbook, "EBay");

            ExcelHelper.SaveWorkbookToFile(workbook, ConfigSetting.SaveReceivedNonEBayReportFile);

 

  示例代碼5-讀取一個(gè)標(biāo)題位置在第8行的標(biāo)題行數(shù)據(jù):

 

ExcelHelper.ReadTitleDataList<T>("文件路徑", new ExcelFileDescription(7))

 

  示例代碼6-使用.net core API控制器方法返回文件流數(shù)據(jù):

[Route("api/[controller]")]
    [ApiController]
    public class TestController : ControllerBase
    {
        public ExcelHelper ExcelHelper { get; set; }

        public TestController(ExcelHelper excelHelper)
        {
            this.ExcelHelper = excelHelper;
        }

        [HttpGet]
        [Route("")]
        public async Task<ActionResult> Test()
        {
            IWorkbook workbook = null;
            CommonCellModelColl accountCellColl = new CommonCellModelColl(10 * 10000);
            for (var i = 0; i < 10; i++)
            {
                accountCellColl.Add(new CommonCellModel(0, i, "" + i + "")); //標(biāo)題行數(shù)據(jù)
            }
            // 最后循環(huán)數(shù)據(jù)列: vList 循環(huán)加到結(jié)合中去。
            int beginRowIndex = 2;
            List<dynamic> vList = new List<dynamic>(5);
            vList.Add(new { a = 2, b = 1 });
            vList.Add(new { a = 2, b = 2 });
            vList.Add(new { a = 2, b = 3 });
            vList.Add(new { a = 3, b = 1 });
            vList.Add(new { a = 3, b = 2 });
            vList.Add(new { a = 3, b = 3 });
            int objPropertyCount = 2;  //這里需要用反射獲取

            for (var i = 0; i < vList.Count; i++)
            {
                for (int j = 0; j < objPropertyCount; j++)
                {
                    //值這里實(shí)際應(yīng)根據(jù)屬性反射獲取屬性值
                    int testValue = 0;
                    if (j == 0)
                    {
                        testValue = ((dynamic)vList[i]).a;
                    }
                    else
                    {
                        testValue = ((dynamic)vList[i]).b;
                    }
                    accountCellColl.Add(new CommonCellModel(beginRowIndex, j, "測試數(shù)據(jù)" + testValue)); //內(nèi)容行數(shù)據(jù)
                }
                beginRowIndex++;
            }
            workbook = this.ExcelHelper.CreateOrUpdateWorkbook(accountCellColl, workbook, "sheet1");
            //生成字節(jié)流
            byte[] myFileByteArray = this.ExcelHelper.SaveWorkbookToByte(workbook);
            //設(shè)置導(dǎo)出文件名
            this.Response.Headers.Add("content-disposition", $"attachment;filename=test.xls");
            await this.Response.Body.WriteAsync(myFileByteArray, 0, myFileByteArray.Length);

            return Ok("success");
        }
    }

 

 

  

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,,所有內(nèi)容均由用戶發(fā)布,,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式,、誘導(dǎo)購買等信息,,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,,請(qǐng)點(diǎn)擊一鍵舉報(bào),。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多