數個月前使用者在詢問能不能匯出excel,於是上網找了資料後,便刻了匯出excel功能給他們,沒想到這只是噩夢的開始,幾周前又開始問我能不能用匯入的...
於是就找到了這個套件,讓我們一起來看看怎麼使用它吧
用之前先做個介紹
相關連結:
1.官方網站
2.讀取 Excel 你還在用 NPOI 嗎?快來試試 LinqToExcel
另外附上問題的解法
1.提供者並未登錄於本機電腦上 - 下載Microsoft Access Database Engine並進行安裝
(注意電腦位元數)
2.第一次上傳時總是沒反應:
請在讀取前加入這行程式碼
excelFile.DatabaseEngine = LinqToExcel.Domain.DatabaseEngine.Ace;
進入正題啦~
首先先去nuget將套件載回來,並在要使用的地方using
using LinqToExcel;
建立物件並給與excel的實體路徑
ExcelQueryFactory excelFile = new ExcelQueryFactory(filePath);
設定只做讀取以及資料庫引擎
excelFile.DatabaseEngine = LinqToExcel.Domain.DatabaseEngine.Ace;
excelFile.ReadOnly = true;
欄位繫節的部分直接在要存的類之中掛attr
例如excel欄位名稱為編號,轉入程式之中的命名要為ID,直接在類中掛
[ExcelColumn(欄位名稱)]即可,如下
需要特別處理的是列舉的型別對應部分,需要自己手動自幹
//第一種寫法 excel欄位 繫節到 class中的屬性
excelFile.AddMapping<UploadExcel>(UploadExcel => UploadExcel.StatusID, "狀態");
//第二種寫法 excel欄位是列舉型別,透過Func來型別對應
//這個方法是在第三個參數中,把每一列的編號(第二個參數)傳進來做處理,並綁定到第一個參數ID
//這個範例是 將數字轉型為列舉(Status) 的處理方式
excelFile.AddMapping<UploadExcel>(UploadExcel => UploadExcel.StatusID, "狀態", p => (Status)Convert.ToInt32(p));
在實務面上還會遇到一個問題,就是列舉在變數命名時,通常會命名為英文,但轉送到client端的時候必須顯示中文,因此會再加掛attr,例如這樣。
再匯入的時候問題就來了,使用者不會知道要輸入10或是OnLine,而只會輸入「上線」,因此又產生了新的問題。
這邊再透過先前介紹的第二個方法稍微衍伸做個處理,即可把資料再轉型回來
首先 讓列舉顯示Description的資料可以參考這篇 列舉型別的資料對應
public static class ExtenxionMethod
{
public static string ExtGetAttributeDescription(this Enum en)
{
Type type = en.GetType();
MemberInfo[] members = type.GetMember(en.ToString());
// 如果沒有任何attribute則報錯
if (members == null)
throw new ArgumentException("There is no property in this attribute");
object[] attributes = members[0].GetCustomAttributes(typeof(DescriptionAttribute), false);
// 如果attribute中沒有description則報錯
if (attributes == null)
throw new ArgumentException("There is no attribute in this description");
return ((DescriptionAttribute)attributes[0]).Description;
}
}
再來透過迴圈把所有列舉的名稱以及其Description資料讀出來,並存入字典中
public static Dictionary<string, string> ToDictionary<T>() where T : struct, IConvertible
{
Type type = typeof(T);
if (!type.IsEnum)
throw new ArgumentException("Type must be an enum");
Dictionary<string, string> di = new Dictionary<string, string>();
foreach (string str in Enum.GetNames(type))
// 這段的ExtGetAttributeDescription()是前面寫的擴充方法
di.Add(str, ((T)Enum.Parse(type, str, true) as Enum).ExtGetAttributeDescription());
return di;
}
此時已經取到列舉的字典,當然如果要取int+Description,也可以透過這段程式碼修改來達到目的
最後再AddMapping前先取得字典
Dictionary<string, string> di = ToDictionary<Status>();
再來就是列舉資料對應的程式碼了
excelFile.AddMapping<UploadExcel>(
// 對應的DTO欄位
UploadExcel=> UploadExcel.StatusID,
// Excel對應的欄位
"狀態",
// 將列舉型別轉型的Lambda函式
p =>
(Status)Enum.Parse(
typeof(Status),
di.Where(w => w.Value.Equals(p)).First().Key,
true));
這樣就可以讓使用者輸入的資料與列舉型別進行對應囉!
最後事實證明,使用者的慾望是永無止盡的,後來我又被要求做了其他的excel的功能...
歡迎您的加入,讓這個社群更加美好!