[ASP.NET] Excel to LINQ - 讀取 Excel 檔案 - 多工作表

摘要:[ASP.NET] Excel to LINQ - 讀取 Excel 檔案 - 多工作表

 

 從程式中匯出 PDF 或 Excel ,幾乎變成每個專案必備的功能,但是反過來從 Excel 中讀取資料的需求就少了許多,最常被應用在資料的匯入功能,本篇就是要來說明該怎麼利用「linqtoexcel Library」來達成此項的需求,簡單的說就是讀取 Excel 檔案顯示在網頁上。

自從訂閱點部落之後,每天都可以收到許多新知,坦白說許多訊息會被我略過,但對於能應用上的部份,就會很好奇的想要試試看,此篇是基於Terry兄所說的,再加上自己需要的功能組合而成。

所需步驟:

  1. 下載函示庫
  2. 將函示庫加入參考 (方法可以參考
  3. 編寫下面的程式碼

---------------------------------------------------------------------------------

前端 aspx 使用元件:

> Fileupload:用來選取檔案
> Button :觸發呼叫事件
> Label :顯示讀取的結果

~畫面如最上方的顯示效果~

 

▼前端 aspx 頁面程式碼▲

<asp:FileUpload ID="FileUpload1" runat="server" Height="30px"Width="300px" />
<br />
<asp:Button ID="Button1" runat="server" Height="40px"onclick="Button1_Click" Text="讀取 Excel 檔案" Width="180px" />
<br />
<asp:Label ID="Label1" runat="server"></asp:Label>

 

後端 aspx.cs 程式碼

當 Fileupload 有選取檔案的時候,會讀取/顯示被選的檔案內容,若沒有選擇則預設抓取 App_Data 目錄下的 Book1.xlsx

讀取出來的結果會以 HTML Table 包裝,例子中是丟到 Label 去做顯示。

 

▼Button1 觸發事件▲

protected void Button1_Click(object sender, EventArgs e)

{
string xFile;
if (FileUpload1 .FileName != "") 
   xFile = FileUpload1.PostedFile.FileName;
else
   xFile =HttpContext.Current.Server.MapPath("App_Data\\Book1.xlsx");
Label1.Text = Excel2Linq(xFile);
}


▼載入函示庫▲ - 在 aspx.cs 中需要 using 載入剛剛加入參考的函示庫

using LinqToExcel;
using Remotion;

上面的「FileUpload1.PostedFile.FileName」為被選檔案的完整路徑
「HttpContext.Current.Server.MapPath」會加上專案所在的路徑位置,也就指到 book1.xlsx 的真實完整路徑。

Function 「Excel2Linq」傳入的是檔名,回傳的是 Excel 內容編成 Table 後的結果(含 Tag)

▼將 Excel 檔讀入▲

private string Excel2Linq(string xFile)
  {
    string ret_string = "";
    ExcelQueryFactory excel = new ExcelQueryFactory(xFile);
    int WorksheetCount = excel.GetWorksheetNames().Count();
    var SheetName = excel.GetWorksheetNames();
    string[] sName = new string[WorksheetCount];
    int sn = 0;
    foreach (var item2 in SheetName)  // 取得各個工作表名稱
     {
        sName[sn] = item2.ToString();
        sn++;
     }
    for (int x = 0; x < WorksheetCount; x++)  // 工作表 sheet 數量
     {   // LINQ 的輸出結果會隨著工作表名稱排序的順序
        IQueryable<Row> xquery = from p in excel.Worksheet(x)select p;
        if (x % 2 == 0)  // 多工作表時,輸出不同顏色的表格
           ret_string += "<table style=\"border: 2px double rgb(74, 145, 146); height: 30px; background-color: rgb(255, 255, 255); width: 90%;\" cellpadding=1 cellspacing=1";
         else
           ret_string += "<table style=\"border: 2px double rgb(163, 97, 27); height: 30px; background-color: rgb(255, 255, 255); width: 90%;\" cellpadding=1 cellspacing=1";
         ret_string += "<caption>" + "工作表名稱:" + sName[x] +"</caption>";
         int m = 0;
         foreach (Row item in xquery)  // 會自動將第一筆當作 Column Name
          {      // 所以 ColumnName 要額外處理
            int j = 0;
            if (m == 0) // 繪製 column name 表頭
             {
               if (x % 2 == 0)
                 ret_string += "<tr bgcolor=#CAE4E4>";
               else
                 ret_string += "<tr bgcolor=#F4D8BA>";
               foreach (string col in item.ColumnNames)
                {
                  ret_string += "<td>";
                  ret_string += col;
                  ret_string += "</td>";
                }
                ret_string += "</tr>";
                m++;
            } // End of m==0
           ret_string += "<tr>";
           for (int k = 0; k < item.Count; k++)  // 填入各個表格的內容
            {
              ret_string += "<td>";
              if (string.IsNullOrEmpty(item[j]))
                  ret_string += " ";     // 對付不對稱欄位數
              else
                  ret_string += item[j]; // item[j] 為表格內容
              ret_string += "</td>";
              j++;
            }//end of k for-loop, column records
           ret_string += "</tr>";
          }//end of foreach row records
         ret_string += "</table><br><br>";
      }//end of Worksheet Count
      return ret_string;
}

執行的結果  - 選擇檔案

嘗試以監理所的統計報表作為輸入的來源

 

**** 剛剛的例子是單一工作表 ****

底下展示多工作表的效果,以 Book1.xlsx 為例

經過程式的處理輸出為

補充說明:

  • 在 Linq 裡並未指定以什麼來作為排序,他會自動以工作表 worksheet 的名稱來作為排序,所以會造成工作表在 Excel 的順序跟在網頁顯示的順序並不同
  • 「ExcelQueryFactory」會預設把第一個行(ROW)當成欄位名稱(Column Name),如果漏掉了,他會幫你補上 Fx,也因此要印出欄位名稱,在程式中多做了一段來作為顯示的動作
  • 取得每一格裡面的內容,是從「Row item in xquery」的「item」中,以 item[subscript] 取得。

Reference:

 

檔案下載:ZIP

~ End