最近有需要進行讀取Excel的任務,需要找個簡單的元件來輔助處理。一路由NPOI、EPPlus、Open XML SDK,到最後確定使用LinqToExcel。
前置作業
當然,也是使用LinqPad來進行測試,只是一下子就出現了錯誤訊息。
依據在LINQPad中使用LinqToExcel(如何引入參考與Namespaces)的做法,在LinqPad中找到另外下載的LinqToExcel的dll檔,再引入它的Namespace,就可以通過編譯了。
按下執行後,又出現另一個錯誤
'Microsoft.ACE.OLEDB.12.0' 提供者並未登錄於本機電腦上。
再依據炎龍牙-[C#] 解決'Microsoft.ACE.OLEDB.12.0' 提供者並未登錄於本機電腦的處理做法,下載Microsoft Access Database Engine 2010 可轉散發套件 並進行安裝,問題就解決了。
使用AddMapping處理欄位名稱的問題
因為我要讀取的Excel的欄位名稱有包含一些特殊符號以及空格,所以會造成查詢上的困難。
通常要做的第一件事情就是將資料轉換為Class,以便後續程式的處理。只是這些特殊符號及空格會讓Property的命名遇上困難,解決的方法就是透過LinqToExcel的 AddMapping
的功能將欄位名稱與我們自訂的Class屬性對應起來。
首先先建立自訂的Class
public class Order
{
public string Customer {get;set;}
public string PartNo {get;set;}
public int Qty {get;set;}
}
再加上AppMapping
的功能
void Main()
{
var fileName = System.IO.Path.Combine(@"D:\Temp\LabBlog.xlsx");
var excelFile=new ExcelQueryFactory(fileName);
excelFile.AddMapping<Order>(d=>d.Customer,"Customer*");
excelFile.AddMapping<Order>(d=>d.PartNo,"Part Number");
excelFile.AddMapping<Order>(d=>d.Qty,"Qty");
var excel=excelFile.Worksheet<Order>("Order")
.Where(d=>d.PartNo=="PN01");
foreach (var element in excel)
element.Dump();
}
結果如下
使用GetColumnNames
在處理Excel的經驗中,欄位名稱有時候會有一些小差異。例如Customer欄位,有些人會簡寫為Cust。如果欄位順序不變,只是欄位名稱有些小改變,則可以使用GetColumnNames()
這個method來取得欄位名稱。
有一個欄位名稱不同的Excel如下
使用GetColumnNames()
取得欄位名稱
void Main()
{
var fileName = System.IO.Path.Combine(@"D:\Temp\LabBlog2.xlsx");
var excelFile=new ExcelQueryFactory(fileName);
var columnNames = excelFile.GetColumnNames("Order").ToList();
excelFile.AddMapping<Order>(d=>d.Customer,columnNames[0]);
excelFile.AddMapping<Order>(d=>d.PartNo,columnNames[1]);
excelFile.AddMapping<Order>(d=>d.Qty,columnNames[2]);
var excel=excelFile.Worksheet<Order>("Order")
.Where(d=>d.PartNo=="PN01");
foreach (var element in excel)
element.Dump();
}
結果如下
所有的做法都是來自於網路的前輩,自己為這些處理流程做個紀錄