1. 程式人生 > >EpPlus讀取生成Excel幫助類+讀取csv幫助類+Aspose.Cells生成Excel幫助類

EpPlus讀取生成Excel幫助類+讀取csv幫助類+Aspose.Cells生成Excel幫助類

大部分功能邏輯都在,少量自定義異常類和擴充套件方法 ,可用類似程式碼自己替換

//EpPlus讀取生成Excel幫助類+讀取csv幫助類,epplus只支援開放的Excel檔案格式:xlsx,不支援 xls格式

/* ==============================================================================
 * 功能描述:EppHelper  
 * 創 建 者:蒲奎民
 * 建立日期:2016-07-21 14:30:35
 * CLR Version :4.0.30319.42000
 * ==============================================================================*/
using OfficeOpenXml;
using OfficeOpenXml.Style;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using YCF.HRMS.Utilities.ExceptionHeper;
using YCF.HRMS.Utilities.ExtensionHelper;
/*
 * 引用檔案:
 * packages\EPPlus.4.1.0\lib\net40\EPPlus.dll
 * packages\EPPlus.Extensions.1.0.0.0\lib\net40\EPPlus.Extensions.dll
 */
namespace YCF.HRMS.Utilities.CommomHelper
{
    /// <summary>
    /// EpPlus讀取Excel幫助類+讀取csv幫助類
    /// </summary>
    public class EppHelper
    {
        #region 由List建立簡單Exel.列頭取欄位的Description或欄位名
        /// <summary>
        /// 由List建立簡單Exel.列頭取欄位的Description或欄位名
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="filePath">The file path.</param>
        /// <param name="dataList">The data list.</param>
        public static void CreateExcelByList<T>(string filePath, List<T> dataList) where T : class
        {

            string dirPath = Path.GetDirectoryName(filePath);
            string fileName = Path.GetFileName(filePath);
            FileInfo newFile = new FileInfo(filePath);
            if (newFile.Exists)
            {
                newFile.Delete();  // ensures we create a new workbook
                newFile = new FileInfo(filePath);
            }
            PropertyInfo[] properties = null;
            if (dataList.Count > 0)
            {
                Type type = dataList[0].GetType();
                properties = type.GetProperties(BindingFlags.Instance | BindingFlags.Public);
                var filedDescriptions = CommonFunctions.GetPropertyDescriptions<T>(true);//欄位與excel列名對應關係
                using (ExcelPackage package = new ExcelPackage(newFile))
                {
                    ExcelWorksheet worksheet = package.Workbook.Worksheets.Add("sheet1");
                    //設定表頭單元格格式
                    using (var range = worksheet.Cells[1, 1, 1, properties.Length])
                    {
                        range.Style.Font.Bold = true;
                        range.Style.Fill.PatternType = ExcelFillStyle.Solid;
                        range.Style.Fill.BackgroundColor.SetColor(Color.DarkBlue);
                        range.Style.Font.Color.SetColor(Color.White);
                    }
                    int row = 1, col;
                    object objColValue;
                    string colValue;
                    //表頭
                    for (int j = 0; j < properties.Length; j++)
                    {
                        row = 1;
                        col = j + 1;
                        var description = filedDescriptions.Where(o => o.Key == properties[j].Name).Select(o => o.Value).FirstOrDefault();
                        worksheet.Cells[row, col].Value = (description == null || description.Description.IsNullOrEmpty()) ? properties[j].Name : description.Description;
                    }
                    worksheet.View.FreezePanes(row + 1, 1); //凍結表頭
                    //各行資料
                    for (int i = 0; i < dataList.Count; i++)
                    {
                        row = i + 2;
                        for (int j = 0; j < properties.Length; j++)
                        {
                            col = j + 1;
                            objColValue = properties[j].GetValue(dataList[i], null);
                            colValue = objColValue == null ? "" : objColValue.ToString();
                            worksheet.Cells[row, col].Value = colValue;
                        }
                    }
                    package.Save();
                }

            }
        }
        #endregion

        #region 讀取Excel資料到DataSet
        /// <summary>
        /// 讀取Excel資料到DataSet
        /// </summary>
        /// <param name="filePath">The file path.</param>
        /// <returns></returns>
        public static DataSet ReadExcelToDataSet(string filePath)
        {
            DataSet ds = new DataSet("ds");
            DataRow dr;
            object objCellValue;
            string cellValue;
            using (FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.ReadWrite))
            using (ExcelPackage package = new ExcelPackage())
            {
                package.Load(fs);
                foreach (var sheet in package.Workbook.Worksheets)
                {
                    if (sheet.Dimension == null) continue;
                    var columnCount = sheet.Dimension.End.Column;
                    var rowCount = sheet.Dimension.End.Row;
                    if (rowCount > 0)
                    {
                        DataTable dt = new DataTable(sheet.Name);
                        for (int j = 0; j < columnCount; j++)//設定DataTable列名
                        {
                            objCellValue = sheet.Cells[1, j + 1].Value;
                            cellValue = objCellValue == null ? "" : objCellValue.ToString();
                            dt.Columns.Add(cellValue, typeof(string));
                        }
                        for (int i = 2; i <= rowCount; i++)
                        {
                            dr = dt.NewRow();
                            for (int j = 1; j <= columnCount; j++)
                            {
                                objCellValue = sheet.Cells[i, j].Value;
                                cellValue = objCellValue == null ? "" : objCellValue.ToString();
                                dr[j - 1] = cellValue;
                            }
                            dt.Rows.Add(dr);
                        }
                        ds.Tables.Add(dt);
                    }
                }
            }
            return ds;

        }
        #endregion

        #region 讀取csv資料到List<T>,列頭與欄位的Description對應
        /// <summary>
        /// 讀取csv資料到List<T>,列頭與欄位的Description對應
        /// </summary>
        /// <typeparam name="T">輸出型別</typeparam>
        /// <param name="filePath">檔案路徑</param>
        /// <returns></returns>
        public static List<T> ReadCsvToModelList<T>(string filePath, string uploadMonth, long userId) where T : class
        {
            List<T> list = new List<T>();
            object objCellValue;
            string cellValue;
            string columnName;
            var filedDescriptions = CommonFunctions.GetPropertyDescriptions<T>(false);//欄位與excel列名對應關係
            var fieldIndexs = new List<KeyValuePair<int, FieldDescriptionModel>>();//Excel列索引與欄位名對應關係
            int lineCount = 1;
            string mes = "";
            Type type = typeof(T);
            int iUserId = int.Parse(userId.ToString());
            var properties = type.GetProperties();
            using (FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read))
            using (StreamReader sr = new StreamReader(fs, Encoding.Default))
            {

                string line;
                var columnCount = 0;
                bool isEmptyCellValue = false;//是否有必須填寫但實際沒填寫的資料
                while (true)
                {
                    isEmptyCellValue = false;
                    line = sr.ReadLine();
                    if (string.IsNullOrWhiteSpace(line))
                    {
                        break;
                    }
                    string[] split = SplitCsvLine(line);
                    if (lineCount == 1)//列頭
                    {
                        columnCount = split.Length;
                        for (int j = 0; j < columnCount; j++)//設定DataTable列名
                        {
                            objCellValue = split[j];
                            cellValue = objCellValue == null ? "" : objCellValue.ToString();
                            var cellFieldName = filedDescriptions.Where(o => o.Key == cellValue).Select(o => o.Value).FirstOrDefault();
                            fieldIndexs.Add(new KeyValuePair<int, FieldDescriptionModel>(j, cellFieldName));
                        }
                        lineCount++;
                        continue;
                    }

                    //當第一列為空時退出csv讀取
                    if (string.IsNullOrWhiteSpace(split[0]))
                    {
                        break;
                    }
                    if (split.Length > columnCount)
                    {
                        mes += lineCount.ToString() + ","; //string.Format("第{0}行讀取有誤,資料列數{1}大於標題列數{2},請檢查該行單元格內是否有逗號<\br>", lineCount, split.Length, dataTypes.Length);
                        lineCount++;
                        continue;
                    }
                    if (split.Length < columnCount)
                    {
                        mes += lineCount.ToString() + ",";//string.Format("第{0}行資料讀取有誤,資料列數{1}小於標題列數{2},請檢查該行單元格內是否有逗號<\br>", lineCount, split.Length, dataTypes.Length);
                        lineCount++;
                        continue;
                    }
                    T model = Activator.CreateInstance<T>();

                    for (int j = 0; j < columnCount; j++)
                    {
                        objCellValue = split[j];
                        var field = fieldIndexs.First(o => o.Key == j).Value;
                        columnName = field.FieldName;
                        if (columnName.IsNullOrEmpty()) continue;
                        PropertyInfo p = properties.FirstOrDefault(o => string.Equals(o.Name, columnName, StringComparison.InvariantCultureIgnoreCase));
                        if (p == null) continue;
                        SetPropertyValue<T>(ref model, ref p, ref objCellValue, ref field, ref isEmptyCellValue);
                    }
                    if (isEmptyCellValue)
                    {
                        continue;
                    }
                    SetPropertyValueForKnowColumns<T>(ref model, ref properties, ref uploadMonth, ref userId, ref iUserId);
                    list.Add(model);
                    lineCount++;
                }
            }
            if (mes != "") throw new BusinessException("第" + mes.TrimEnd(',') + "行讀取有誤,請檢查該行單元格內是否有逗號");
            #region 判斷第一行資料是否合格,Excel列名和欄位對不上的情況,檢查一個就等於檢查全部
            var firstModel = list.FirstOrDefault();
            CheckModelRequiredData<T>(ref firstModel, ref properties, ref filedDescriptions);
            #endregion
            return list;
        }

        #endregion

        #region 設定欄位屬性的值
        /// <summary>
        /// 設定欄位屬性的值
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="model">The model.</param>
        /// <param name="p">The p.</param>
        /// <param name="objCellValue">The object cell value.</param>
        /// <param name="field">The field.</param>
        /// <param name="isEmptyCellValue">if set to <c>true</c> [is empty cell value].</param>
        /// <exception cref="BusinessException">出錯,欄位名: + p.Name + ,型別: + p.PropertyType.ToString() + ,資料: + (objCellValue == null ?  : objCellValue.ToString()) + ,錯誤資訊: + ex.Message</exception>
        private static void SetPropertyValue<T>(ref T model, ref PropertyInfo p, ref object objCellValue, ref FieldDescriptionModel field, ref bool isEmptyCellValue) where T : class
        {
            var propertyType = p.PropertyType.ToString();
            switch (propertyType)
            {
                case "System.String":
                    {
                        if (objCellValue is string == false)
                        {
                            if (objCellValue == null) objCellValue = "";
                            else objCellValue = objCellValue.ToString();
                            if (field.IsRequire && objCellValue.ToString() == "")
                            {
                                isEmptyCellValue = true;
                                break;
                            }
                        }
                        if (objCellValue != null) objCellValue = objCellValue.ToString().Replace("\r\n", "").Trim();
                    }
                    break;
                case "System.Decimal":
                case "System.Nullable`1[System.Decimal]":
                    {
                        if (objCellValue is decimal == false)
                        {
                            if (objCellValue != null)
                            {
                                if (objCellValue.ToString().EndsWith("%"))
                                {
                                    objCellValue = Convert.ToDecimal(objCellValue.ToString().TrimEnd('%')) / 100M;
                                }
                                else objCellValue = Convert.ToDecimal(objCellValue.ToString());
                            }
                        }
                    }
                    break;
                case "System.Int32":
                case "System.Nullable`1[System.Int32]":
                    {
                        if (objCellValue is int == false)
                        {
                            if (objCellValue != null) objCellValue = Convert.ToInt32(objCellValue);
                        }
                    }
                    break;
                case "System.Int64":
                case "System.Nullable`1[System.Int64]":
                    {
                        if (objCellValue is long == false)
                        {
                            if (objCellValue != null) objCellValue = Convert.ToInt64(objCellValue);
                        }
                    }
                    break;
                case "System.DateTime":
                case "System.Nullable`1[System.DateTime]":
                    {
                        if (objCellValue is DateTime == false)
                        {
                            if (objCellValue != null) objCellValue = ToDateTimeValue(objCellValue.ToString());
                        }
                    }
                    break;
                case "System.Boolean":
                case "System.Nullable`1[System.Boolean]":
                    {
                        if (objCellValue is bool == false)
                        {

                            if (objCellValue != null)
                            {
                                var tempValue = objCellValue.ToString().Trim();
                                if (tempValue == "#N/A") tempValue = "";
                                else if (tempValue == "是") tempValue = "True";
                                else if (tempValue == "否") tempValue = "False";
                                if (tempValue != "") objCellValue = Convert.ToBoolean(tempValue);
                                else objCellValue = null;
                            }
                        }
                    }
                    break;
            }
            try
            {
                p.SetValue(model, objCellValue, null);
            }
            catch (Exception ex)
            {
                throw new BusinessException("出錯,欄位名:" + p.Name + ",型別:" + p.PropertyType.ToString() + ",資料:" + (objCellValue == null ? "" : objCellValue.ToString()) + ",錯誤資訊:" + ex.Message);
            }
        }
        #endregion

        #region 其他已知屬性賦預設值
        /// <summary>
        /// 其他已知屬性賦預設值
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="model">The model.</param>
        /// <param name="properties">The properties.</param>
        /// <param name="uploadMonth">The upload month.</param>
        /// <param name="userId">The user identifier.</param>
        /// <param name="iUserId">The i user identifier.</param>
        private static void SetPropertyValueForKnowColumns<T>(ref T model, ref PropertyInfo[] properties, ref string uploadMonth, ref long userId, ref int iUserId)
        {
            var monthProperty = properties.FirstOrDefault(o => string.Equals(o.Name, "Month", StringComparison.InvariantCultureIgnoreCase));
            if (monthProperty != null)
            {
                monthProperty.SetValue(model, uploadMonth, null);
            }
            var createTimeProperty = properties.FirstOrDefault(o => string.Equals(o.Name, "CreationTime", StringComparison.InvariantCultureIgnoreCase));
            if (createTimeProperty != null)
            {
                createTimeProperty.SetValue(model, DateTime.Now, null);
            }
            var modifyTimeProperty = properties.FirstOrDefault(o => string.Equals(o.Name, "LastModificationTime", StringComparison.InvariantCultureIgnoreCase));
            if (modifyTimeProperty != null)
            {
                modifyTimeProperty.SetValue(model, DateTime.Now, null);
            }
            var createUserIdProperty = properties.FirstOrDefault(o => string.Equals(o.Name, "CreatorUserId", StringComparison.InvariantCultureIgnoreCase));
            if (createUserIdProperty != null)
            {
                if (createTimeProperty.PropertyType.ToString() == "System.Int32") createUserIdProperty.SetValue(model, iUserId, null);
                else createUserIdProperty.SetValue(model, userId, null);
            }
        }
        #endregion

        #region 最後判斷第一行資料是否合格,Excel列名和欄位對不上的情況,檢查一個就等於檢查全部
        /// <summary>
        /// 最後判斷第一行資料是否合格,Excel列名和欄位對不上的情況,檢查一個就等於檢查全部
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="model">The model.</param>
        /// <param name="filedDescriptions">The filed descriptions.</param>
        private static void CheckModelRequiredData<T>(ref T firstModel, ref PropertyInfo[] properties, ref List<KeyValuePair<string, FieldDescriptionModel>> filedDescriptions)
        {
            if (firstModel != null)
            {
                var fieldNameList = filedDescriptions.Where(o => o.Value != null).Select(o => o.Value).ToList();

                foreach (var p in properties)
                {
                    var fieldNameModel = fieldNameList.FirstOrDefault(o => string.Equals(o.FieldName, p.Name, StringComparison.InvariantCultureIgnoreCase));
                    if (fieldNameModel == null || fieldNameModel.IsRequire == false) continue;//為空或沒有Require標記,跳過
                    object objCellValue = p.GetValue(firstModel);
                    if (objCellValue == null || objCellValue.ToString() == "")
                    {
                        throw new BusinessException("出錯,欄位名:" + p.Name + ",型別:" + p.PropertyType.ToString() + " 必填欄位資料為空!");
                    }
                }
            }
        } 
        #endregion

        #region 讀取Excel資料到List<T>,列頭與欄位的Description對應
        /// <summary>
        /// 讀取Excel資料到List<T>,列頭與欄位的Description對應
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="filePath">The file path.</param>
        /// <returns></returns>
        public static List<T> ReadExcelToModelList<T>(string filePath, string uploadMonth, long userId, out string log, int titleRow = 1) where T : class
        {
            ExcelPackage package = null;
            FileStream fs = null;
            try
            {
                //ConcurrentBag<T> list = new ConcurrentBag<T>();
                List<T> list = new List<T>();
                log = string.Format("{0:yyyy-MM-dd HH:mm:ss}開始載入檔案{1}\r\n", DateTime.Now, filePath);
                var filedDescriptions = CommonFunctions.GetPropertyDescriptions<T>(false);//欄位與excel列名對應關係
                var fieldIndexs = new List<KeyValuePair<int, FieldDescriptionModel>>();//Excel列索引與欄位名對應關係
                fs = new FileStream(filePath, FileMode.Open, FileAccess.ReadWrite);
                package = new ExcelPackage();
                package.Load(fs);
                log += string.Format("{0:yyyy-MM-dd HH:mm:ss}完成載入檔案{1},開始解析\r\n", DateTime.Now, filePath);
                if (package.Workbook.Worksheets.Count == 0)
                {
                    throw new BusinessException("讀取的Excel中sheet數量為0,請檢查檔案格式是否為xlsx!");
                }
                var sheet = package.Workbook.Worksheets[1];

                if (sheet.Dimension == null) return list.ToList();
                var columnCount = sheet.Dimension.End.Column;
                var rowCount = sheet.Dimension.End.Row;
                if (rowCount == 0) return list.ToList();
                //DataTable dt = new DataTable(sheet.Name);
                for (int j = 1; j <= columnCount; j++)//列名與欄位名對應關係
                {
                    object objCellValue = sheet.Cells[titleRow, j].Value;
                    string cellValue = objCellValue == null ? "" : objCellValue.ToString();
                    if (cellValue.Len() == 0) continue;
                    var cellFieldName = filedDescriptions.Where(o => o.Key == cellValue).Select(o => o.Value).FirstOrDefault();
                    fieldIndexs.Add(new KeyValuePair<int, FieldDescriptionModel>(j, cellFieldName));
                    //dt.Columns.Add(cellValue, typeof(string));
                }
                Type type = typeof(T);
                int iUserId = int.Parse(userId.ToString());
                var properties = type.GetProperties();
                //List<int> rowIndexList = Enumerable.Range(titleRow + 1, rowCount - titleRow).ToList();//資料行的行號集合
                //Parallel.ForEach(rowIndexList, (i) =>
                for (int i = titleRow + 1; i <= rowCount; i++)
                {
                    #region 處理Excel每行資料
                    object objCellValue = null;
                    string columnName = null;
                    bool isEmptyCellValue = false;//是否有必須填寫但實際沒填寫的資料
                    T model = Activator.CreateInstance<T>();
                    for (int j = 1; j <= columnCount; j++)
                    {
                        objCellValue = sheet.Cells[i, j].Value;
                        var fieldPair = fieldIndexs.FirstOrDefault(o => o.Key == j);
                        var field = fieldPair.Value;
                        columnName = field == null ? "" : field.FieldName;
                        if (columnName.IsNullOrEmpty()) continue;
                        PropertyInfo p = properties.FirstOrDefault(o => string.Equals(o.Name, columnName, StringComparison.InvariantCultureIgnoreCase));
                        if (p == null) continue;
                        SetPropertyValue<T>(ref model, ref p, ref objCellValue, ref field, ref isEmptyCellValue);

                    }
                    if (!isEmptyCellValue)
                    {
                        SetPropertyValueForKnowColumns<T>(ref model, ref properties, ref uploadMonth, ref userId, ref iUserId);
                        list.Add(model);
                    }

                    #endregion
                }
                //);
                #region 判斷第一行資料是否合格,Excel列名和欄位對不上的情況,檢查一個就等於檢查全部
                var firstModel = list.FirstOrDefault();
                CheckModelRequiredData<T>(ref firstModel, ref properties, ref filedDescriptions);
                #endregion
                log += string.Format("{0:yyyy-MM-dd HH:mm:ss}完成解析檔案{1}\r\n", DateTime.Now, filePath);
                return list;
            }
            finally
            {
                if (package != null) package.Dispose();//釋放Excel物件資源
                if (fs != null)//關閉和釋放檔案流資源
                {
                    fs.Close(); fs.Dispose();
                }
            }

        }
        #endregion

        #region Splits the CSV line.
        /// <summary>
        /// Splits the CSV line.
        /// </summary>
        /// <param name="s">The s.</param>
        /// <returns></returns>
        private static string[] SplitCsvLine(string s)
        {
            Regex regex = new Regex("\".*?\"");
            var a = regex.Matches(s).Cast<Match>().Select(m => m.Value).ToList();
            var b = regex.Replace(s, "%_%");
            var c = b.Split(',');
            for (int i = 0, j = 0; i < c.Length && j < a.Count; i++)
            {
                if (c[i] == "%_%")
                {
                    c[i] = a[j++];
                }
            }
            return c;
        }
        #endregion

        #region Excel中數字時間轉換成時間格式
        /// <summary>
        /// Excel中數字時間轉換成時間格式
        /// </summary>
        /// <param name="timeStr">數字,如:42095.7069444444/0.650694444444444</param>
        /// <returns>日期/時間格式</returns>
        public static DateTime ToDateTimeValue(string strNumber)
        {
            if (!string.IsNullOrWhiteSpace(strNumber))
            {
                Decimal tempValue;
                DateTime tempret;
                if (DateTime.TryParse(strNumber, out tempret))
                {
                    return tempret;
                }
                if (strNumber.Length == 8 && strNumber.Contains(".") == false)//20160430
                {

                    strNumber = strNumber.Insert(4, "-").Insert(6 + 1, "-");
                    if (DateTime.TryParse(strNumber, out tempret))
                    {
                        return tempret;
                    }
                    else return default(DateTime);
                }
                //先檢查 是不是數字;
                if (Decimal.TryParse(strNumber, out tempValue))
                {
                    //天數,取整
                    int day = Convert.ToInt32(Math.Truncate(tempValue));
                    //這裡也不知道為什麼. 如果是小於32,則減1,否則減2
                    //日期從1900-01-01開始累加 
                    // day = day < 32 ? day - 1 : day - 2;
                    DateTime dt = new DateTime(1900, 1, 1).AddDays(day < 32 ? (day - 1) : (day - 2));

                    //小時:減掉天數,這個數字轉換小時:(* 24) 
                    Decimal hourTemp = (tempValue - day) * 24;//獲取小時數
                    //取整.小時數
                    int hour = Convert.ToInt32(Math.Truncate(hourTemp));
                    //分鐘:減掉小時,( * 60)
                    //這裡舍入,否則取值會有1分鐘誤差.
                    Decimal minuteTemp = Math.Round((hourTemp - hour) * 60, 2);//獲取分鐘數
                    int minute = Convert.ToInt32(Math.Truncate(minuteTemp));

                    //秒:減掉分鐘,( * 60)
                    //這裡舍入,否則取值會有1秒誤差.
                    Decimal secondTemp = Math.Round((minuteTemp - minute) * 60, 2);//獲取秒數
                    int second = Convert.ToInt32(Math.Truncate(secondTemp));
                    if (second >= 60)
                    {
                        second -= 60;
                        minute += 1;
                    }
                    if (minute >= 60)
                    {
                        minute -= 60;
                        hour += 1;
                    }

                    //時間格式:00:00:00
                    string resultTimes = string.Format("{0}:{1}:{2}",
                            (hour < 10 ? ("0" + hour) : hour.ToString()),
                            (minute < 10 ? ("0" + minute) : minute.ToString()),
                            (second < 10 ? ("0" + second) : second.ToString()));
                    var str = string.Format("{0} {1}", dt.ToString("yyyy-MM-dd"), resultTimes);
                    try
                    {
                        return DateTime.Parse(str);
                    }
                    catch (Exception ex)
                    {
                        throw new Exception("DateTime.Parse出錯,str:" + str, ex);
                    }

                }
            }
            return default(DateTime);
        }
        #endregion

    }
}


//Aspose.Cells生成xlsx檔案幫助類

using Aspose.Cells;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace YCF.HRMS.Utilities.CommomHelper
{
    /// <summary>
    /// Aspose.Cells生成xlsx檔案
    /// </summary>
    public static class AsposeCellsHelper
    {
        public static void CreateExcel<T>(IEnumerable<T> content, string filePath, string sheetName, int startRow,bool setBorder = false, string getColorMethodName = null)
        {
            var columnsAccessor = CreateColumnsAccessor<T>();
            var colInvoker = ExpressionHelper.GetMemberAccessor(columnsAccessor);
            var t = typeof(T);

            Workbook workbook = new Workbook();

            var sheet = workbook.Worksheets[0]; ;
            sheet.Name = sheetName;
            var freezeAttr = t.GetCustomAttribute<ExcelFreezeAttribute>();
            //凍結表頭
            if (freezeAttr != null)
                sheet.FreezePanes(startRow + 1, 0 + 1, freezeAttr.FreezeRowIndex + startRow + 1, freezeAttr.FreezeColumnIndex + 1);

            var cells = workbook.Worksheets[0].Cells;
            int rowIndex = startRow;
            int colIndex = 0;
            for (int i = 0; i < colInvoker.Count(); i++)
            {
                var col = colInvoker.ElementAt(i);
                //刪除隱藏屬性
                var widthAttr = col.Key.GetCustomAttribute<ExcelColumnAttribute>();
                if (widthAttr != null)
                {

                    if (widthAttr.Hide)
                    {
                        colInvoker.Remove(col.Key);
                        i--;
                        continue;
                    }
                }
                var title = col.Key.Name;
                var desc = col.Key.GetCustomAttribute<DescriptionAttribute>();
                if (desc != null)
                    title = desc.Description;
                else
                {
                    var display = col.Key.GetCustomAttribute<DisplayAttribute>();
                    if (display != null)
                        title = display.Name;
                }
                var myCell = sheet.Cells[rowIndex, colIndex];
                Style style = myCell.GetStyle();
                myCell.PutValue(title);
                style.Font.IsBold = true;
                style.HorizontalAlignment = TextAlignmentType.Center;
                style.Font.Name = "宋體";
                style.Font.Size = 10;
                if (setBorder)
                {
                    style.Borders[BorderType.BottomBorder].LineStyle = CellBorderType.Thin;
                    style.Borders[BorderType.BottomBorder].Color = System.Drawing.Color.Black;
                    style.Borders[BorderType.TopBorder].LineStyle = CellBorderType.Thin;
                    style.Borders[BorderType.TopBorder].Color = System.Drawing.Color.Black;
                    style.Borders[BorderType.LeftBorder].LineStyle = CellBorderType.Thin;
                    style.Borders[BorderType.LeftBorder].Color = System.Drawing.Color.Black;
                    style.Borders[BorderType.RightBorder].LineStyle = CellBorderType.Thin;
                    style.Borders[BorderType.RightBorder].Color = System.Drawing.Color.Black;
                }
                myCell.SetStyle(style);
                cells.SetColumnWidth(colIndex, 15);
                colIndex++;
            }

            rowIndex++;

            PropertyInfo[] properties = colInvoker.Keys.OfType<PropertyInfo>().ToArray();
            Func<T, string> getHtmlColorFunc = null;
            if(getColorMethodName != null)
            {
                MethodInfo getColorMethod = typeof(T).GetMethod(getColorMethodName);
                if (getColorMethod != null)
                {
                    var parameter = Expression.Parameter(typeof(T));
                    getHtmlColorFunc = Expression.Lambda<Func<T, string>>(Expression.Call(parameter, getColorMethod), parameter).Compile();
                }
            }

            //格式
            Func<PropertyInfo, Cell, Style> colunmnStyles = (p, cell) =>
             {
                 Style style = cell.GetStyle();
                 var type = p.PropertyType;
                 if (type.IsGenericType)
                 {
                     type = type.GetGenericArguments()[0];
                 }
                 if (type == typeof(DateTime))
                 {
                     style.Custom = "yyyyMMdd";
                 }
                 else if (type == typeof(double) || type == typeof(decimal))
                 {
                     style.Custom = "0.00";
                 }
                 style.Font.Name = "宋體";
                 style.Font.Size = 10;
                 return style;
             };
            var propertyValueSetter = properties.ToDictionary(p => p, p =>
            {
                Action<object, Cell> valueSetter;
                var type = p.PropertyType;
                if (type.IsGenericType)
                {
                    type = type.GetGenericArguments()[0];
                }
                if (type == typeof(DateTime))
                {
                    valueSetter = (o, cell) =>
                    {
                        if (o != null)
                        {
                            cell.PutValue(Convert.ToDateTime(o));
                        }
                    };
                }
                else if (type == typeof(double) || type == typeof(decimal) || type == typeof(int))
                {
                    valueSetter = (o, cell) =>
                    {
                        if (o != null)
                        {
                            cell.PutValue(Convert.ToDouble(o));
                        }
                    };
                }
                else
                {
                    valueSetter = (o, cell) =>
                    {
                        if (o != null)
                        {
                            cell.PutValue(o.ToString());
                        }
                    };
                }
                return valueSetter;
            });


            foreach (var item in content)
            {
                colIndex = 0;
                
                foreach (var propertyInfo in properties)
                {
                    object value = propertyInfo.GetValue(item);
                    var cell = sheet.Cells[rowIndex, colIndex++];
                    propertyValueSetter[propertyInfo](value, cell);
                    var style = colunmnStyles(propertyInfo, cell);
                    if (getHtmlColorFunc != null)
                    {

                        style.ForegroundColor = System.Drawing.ColorTranslator.FromHtml(getHtmlColorFunc(item));
                        style.Pattern = BackgroundType.Solid;
                    }
                    if (setBorder)
                    {
                        style.Borders[BorderType.BottomBorder].LineStyle = CellBorderType.Thin;
                        style.Borders[BorderType.BottomBorder].Color = System.Drawing.Color.Black;
                        style.Borders[BorderType.TopBorder].LineStyle = CellBorderType.Thin;
                        style.Borders[BorderType.TopBorder].Color = System.Drawing.Color.Black;
                        style.Borders[BorderType.LeftBorder].LineStyle = CellBorderType.Thin;
                        style.Borders[BorderType.LeftBorder].Color = System.Drawing.Color.Black;
                        style.Borders[BorderType.RightBorder].LineStyle = CellBorderType.Thin;
                        style.Borders[BorderType.RightBorder].Color = System.Drawing.Color.Black;
                    }
                    cell.SetStyle(style);
                }
                rowIndex++;
            }

            workbook.Save(filePath, new Aspose.Cells.OoxmlSaveOptions(Aspose.Cells.SaveFormat.Xlsx));
            workbook.Worksheets.Clear();
        }

        internal static Expression<Func<T, object>> CreateColumnsAccessor<T>()
        {
            var type = typeof(T);
            var ps = type.GetProperties(BindingFlags.Public | BindingFlags.Instance);
            var bindings = new List<MemberBinding>();
            var parameter = Expression.Parameter(type, "p");
            foreach (var p in ps)
            {
                bindings.Add(Expression.Bind(p, Expression.MakeMemberAccess(parameter, p)));
            }
            var creator = Expression.MemberInit(Expression.New(type), bindings);
            var columnsAccessor = Expression.Lambda<Func<T, object>>(creator, parameter);
            return columnsAccessor;
        }
    }
    /// <summary>
    /// 可加的列寬屬性
    /// </summary>
    /// <seealso cref="System.Attribute" />
    [AttributeUsage(AttributeTargets.Property)]
    public class ExcelColumnAttribute : Attribute
    {
        public int Width { get; set; }
        public bool Hide { get; set; }
    }
    /// <summary>
    /// 可加顏色屬性
    /// </summary>
    /// <seealso cref="System.Attribute" />
    [AttributeUsage(AttributeTargets.Class)]
    public class ExcelCellStyleAttribute : Attribute
    {
        public string HtmlColorAccessor { get; set; }
    }
    /// <summary>
    /// 可加凍結屬性
    /// </summary>
    /// <seealso cref="System.Attribute" />
    [AttributeUsage(AttributeTargets.Class)]
    public class ExcelFreezeAttribute : Attribute
    {
        public int FreezeColumnIndex { get; set; }
        public int FreezeRowIndex { get; set; }
    }
}
aspose引用:packages\Aspose.Cells\7.0.3(2011-11-12)\Aspose.Cells.dll

之前寫過npoi的讀取excel的文章,現在epplus也可以。

對比:

npoi可讀寫xls和xlsx,epplus只支援讀寫xlsx. 讀寫效率應該都差不了多少,寫入少量資料可用這兩個,大量資料寫的話最好要用aspose。

aspose寫入速度比npoi和epplus快。

相關推薦

EpPlus讀取生成Excel幫助+讀取csv幫助+Aspose.Cells生成Excel幫助

大部分功能邏輯都在,少量自定義異常類和擴充套件方法 ,可用類似程式碼自己替換//EpPlus讀取生成Excel幫助類+讀取csv幫助類,epplus只支援開放的Excel檔案格式:xlsx,不支援 xls格式/* ===============================

程式碼自動生成工具(一)-Csv讀表程式碼自動生成工具

之前提到了自定義的Csv格式的表格讀取的一個工具類CsvReader 這裡我們實現一個可以對任意符合我們人為規定的格式的Csv檔案,自動生成其對應的讀表程式碼 本工具需要boost庫支援,本人用的是1.55.0 這裡首先定義Csv中支援的幾種列型別:FieldType:

C# Aspose.Cells拷貝Excel

Workbook workBook = new Workbook(OFD.FileName); Cells cells = workBook.Worksheets[0].Cells; if (cells == null) return; Data

使用Aspose.cells實現Excel轉換為pdf

import java.io.FileInputStream; import java.io.InputStream; import com.aspose.cells.License; import com.aspose.cells.SaveFormat; import co

C# Aspose.Cells.dll Excel操作總結

簡介 Aspose.Cells是一款功能強大的 Excel 文件處理和轉換控制元件,不依賴 Microsoft Excel 環境,支援所有 Excel 格式型別的操作。 獲取Excel資料 Workbook workbook = new Workbook("E:\\test.xlsx"); C

EXCEL多sheet頁公用讀取方式

大概思路: 1.獲取前臺傳遞過來的FILE檔案及需要解析的XML檔案ID XML 如下: <?xml version="1.0" encoding="UTF-8" ?> <excels> <!-- 電力排程機構--><excel id="SCSE

用python從excel表格中讀取資料生成可以放在科技論文中的圖片

最近在寫畢業小論文,需要插入符合科技論文的資料圖,其實很多的設定都是規定好的,雖然自己在excel中設定一下也不花多少時間,覺得好玩想著是不是可以用python做一個自動讀取資料畫圖的小指令碼,以後寫報告也可以用得著。 其實整個思路很清楚,兩個晚上的樣子就搭好了大體的程式,

采用OleDB讀取EXCEL文件 讀取數字後,字符串無法讀取

tex i++ eem pty col ++ lena ons blog   很多人采用OleDB讀取EXCEL文件的時候會發現,當一列數據以數字開頭的時候,後面的字符串無法讀取,今天就給大家分享一下解決此問題的小竅門。   1、把列標題當做數據來讀取(HDR=NO設置把第

Java中使用字節流讀取文本內容

length inpu pre puts output 寫入 log oid cnblogs package cn.jbit.inputstream; import java.io.File; import java.io.FileInputStream; import

java 中properties 讀取k-v配置文件

.class void tput iter 讀取配置文件 絕對路徑 getprop stream 源配置 properties 讀取的配置文件key和values都是string 類型 package com.bjsxt.others.pro; import java

使用dataset讀取xml後 用dataview排序時為什麽不是按數字型排序 MQsz

父親 dataview 重要 找我 con 帶來 權力 view 尋找 <p>  秋天,葉子一片片落下,帶著一絲絲的遺憾,投向大地母親的懷抱。她們跳躍著,旋轉,著,輕舞飛揚著,翩然落下。仲春時節,輕寒料峭。一個朋友的父親專程從鄉下來縣城看我,他給我帶來了滿滿的一

利用反射與dom4j讀取javabean生成對應XML和讀取XML得到對應的javabean物件集合

首先實現生成對應的JAVAbean的XML檔案方法 /** * DMO4J寫入XML * @param obj 泛型物件 * @param entityPropertys 泛型物件的List集合 * @param Encode

C#實戰003:Excel操作系列-讀取Excel工作簿

成功連結上Excel檔案之後我們就可以開始讀取該Excel,首先我們先來讀取Excel下有幾個工作簿 C#實戰003:Excel操作系列-OleDb連結Excel //-----------------------------讀取Excel工作簿-----------------------

C#實戰004:Excel操作系列-讀取Excel工作簿

成功連結上Excel檔案之後我們就可以開始讀取該Excel,首先我們先來讀取Excel下有幾個工作簿 C#實戰003:Excel操作系列-OleDb連結Excel //-----------------------------讀取Excel工作簿-----------------------

0007-用OpenCV的VideoCapture讀取avi視訊檔案,並以幀流的形式顯示出來!

OpenCV用VideoCapture類實現avi視訊讀取的相關操作,具體怎麼使用,大家看程式碼便知! 示例程式碼如下: 程式碼中用的視訊下載連結:http://pan.baidu.com/s/1qYbRtqW 密碼:5bcu //opencv版本:OpenCV3.0 //VS版本:VS20

pytorch—ImageFolder/自定義 讀取圖片資料—Transform資料轉換

文章目錄 一、torchvision 影象資料讀取 [0, 1] 二、torchvision 的 Transform 三、讀取影象資料類 3.1 class torchvision.d

python讀取zip壓縮檔案裡面的csv資料

 利用zipfile模組和pandas獲取資料,程式碼比較簡單,做個記錄吧: # -*- coding: utf-8 -*- """ Created on Tue Aug 21 22:35:59 2018 @author: FanXiaoLei """ from zipfile im

Excel 檔案資料讀取和篩選

需求:已知一個excel 表中的"Sheet1"中,有id, name, salary 3列的內容,要求將薪水重複次數最多的按從高到低進行排序 #coding=utf-8 import xlrd from collections import Counter import opera

利用SqlHelper讀取儲存過程

 public DataSet pro_yd_待審清單()     {         return SqlHelper.ExecuteDataset(constr, CommandType

java對excel寫入與讀取

maven: <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi</artifactId> <version>3.16</ve