[ASP.NET] 使用NPOI產生EXCEL

摘要:[ASP.NET] 使用NPOI產生EXCEL

前言


NPOI 是一個能夠快速讀取EXCEL與產生EXCEL檔案的第三方套件,對於需要產生EXCEL報表的情況下非常好用,以下簡單介紹一下使用方式。

 

範例


Step 1 下載NPOI Library

請至 CodePlex 下載 NPOI Library ,下載完成後解壓縮如下:

 

壓縮檔內有一些說明文檔可以先看看,另外包含兩個資料夾 examples 為範例檔、bin 為要加入專案的DLL檔案,在這我使用bin\.net 4.0\資料夾內的DLL檔案,將DLL加入參考至新網站中。

 

Step 2 建立報表樣版

使用NPOI可以自己動態建立EXCEL也能夠使用EXCEL樣版檔產生報表,在這使用我使用樣版檔的方式建立,首先建立一個 Office 2003 格式的 Excel檔案,將要顯示的相關欄位格式設定好,如下:

 

樣版製作好後將檔案放入網站下,稍微分一下目錄跟加入一個Default.aspx開始頁面讓之後能夠操作。

 

Step 3 撰寫報表產生類別

接下來就要開始撰寫程式碼,以下方法於範例中可以取得完整程式碼,這邊只大致說明一下使用方式:

InitReport() 方法

在InitReport方法中,要設定初始化報表的設定如下:

  • MaxCol : 總欄位數量,由此範例來看EXCEL共有5欄,但是在這要從0開始計算所以填4
  • StartRow : 起始的列,由此範例來看第一列為報表標題第二列為欄為標題所以從第三列開始,但也是從0開始所以填2
  • ExportPath : 產生檔案路徑,如要儲存產生的EXCEL這邊就要設定路徑
  • ExportFileName : 產生檔案的名稱
  • TemplatePath : 樣版檔路徑
  • TemplateFileName : 樣版檔案的名稱
  • TemplateFilePath : 樣版檔案的完整路徑
private void InitReport()
{
    MaxCol = 4;
    StartRow = 2;
    ExportPath = "~/Rpt/Export/";
    ExportFileName = "ProductReport.xls";
    TemplatePath = "~/Rpt/Template/";
    TemplateFileName = "TemplateReport.xls";
    TemplateFilePath = TemplatePath + TemplateFileName;
}

 

LoadSheet() 方法

在LoadSheet方法中,將會開啟指定的樣板檔,其中 HssfWorkbook.GetSheetAt(0) 這段主要為取得樣版中指定的Sheet Index Number,想用Sheet名稱取得話可以改用 GetSheet(string name) 方法。

因為之後要設定新增列的格式跟字體,所以額外建立 CreateCellStyle 與 CreateFont 物件,之所以不放在InserNewRow()法中產生是因為如每產生一列就新增樣式物件,會造成Excel資源消耗而發生樣式跑掉的問題。

private void LoadSheet()
{
    FileStream file = new FileStream(HttpContext.Current.Server.MapPath(TemplateFilePath), FileMode.Open, FileAccess.Read); // 開啟讀取樣版檔
    HssfWorkbook = new HSSFWorkbook(file);
    Sheet = HssfWorkbook.GetSheetAt(0); // 取得Index為0的Sheet
    CellStyle = HssfWorkbook.CreateCellStyle(); // 產生欄位樣式設定
    Font = HssfWorkbook.CreateFont();   // 產生字體樣式設定
}

 

InsertNewRow() 方法

在InsertNewRow方法中,主要的作用就是動態產生一列新列,產生後設定該列的樣式與字體等等後回傳該列讓後續操作。

private IRow InsertNewRow()
{
    IRow row;
    ICell cell;
    Sheet.ShiftRows(StartRow, Sheet.LastRowNum, 1);
    row = Sheet.GetRow(StartRow);   // 取得列
    if (row == null)
        row = Sheet.CreateRow(StartRow);    // 若無該列則產生新列
    for (int i = 0; i <= MaxCol; i++)
    {
        cell = row.CreateCell(i);   // 產生欄位
        // 設定欄位框線
        CellStyle.BorderBottom = BorderStyle.THIN;
        CellStyle.BorderLeft = BorderStyle.THIN;
        CellStyle.BorderRight = BorderStyle.THIN;
        CellStyle.BorderTop = BorderStyle.THIN;
        // 設定對齊方式
        CellStyle.Alignment = HorizontalAlignment.LEFT; // 水平
        CellStyle.VerticalAlignment = VerticalAlignment.CENTER; // 垂直
        CellStyle.WrapText = true; // 是否自動換行
        // 設定字體
        Font.FontName = "標楷體";
        Font.FontHeightInPoints = 12;

        CellStyle.SetFont(Font);
        cell.CellStyle = CellStyle;
    }
    StartRow++;
    return row;
}

 

ReportLogic() 方法

在ReportLogic方法中,主要就是報表邏輯的撰寫,此處將依照要產生的報表需求撰寫相關程式碼,直接取得樣版中欄位位置的方法就是使用 Sheet.GetRow(0).GetCell(0).SetCellValue("") 方法,如需要使用Excel的公式的話可以使用 row.GetCell(0).SetCellFormula(string formula) 方法,另外可以看到報表內容部分就是跑回圈取得來源資料後反覆進行[ 新增列 > 指定列的欄位值 ]動作。

private void ReportLogic()
{
    // 報表標題
    Sheet.GetRow(0).GetCell(0).SetCellValue("產品報表");

    // 報表內容
    foreach (ProductDao.ProductEntity entity in GetData())
    {
        IRow row = InsertNewRow(); // 插入新列

        row.GetCell(0).SetCellValue(entity.ProductID);
        row.GetCell(1).SetCellValue(entity.ProductName);
        row.GetCell(2).SetCellValue(entity.ProductPrice);
        row.GetCell(3).SetCellValue(entity.ProductNumber);
        row.GetCell(4).SetCellFormula(string.Format("C{0}*D{0}", StartRow));
    }
}

 

ExportExcel方法與SaveExcel方法

最後一步當然要將產生的資料輸出,這邊提供了兩種輸出方法

ExprotExcel() 方法為直接將網頁轉換ContentType後輸出,Client端就可以直接跳出EXCEL下載視窗。

SaveExcel() 方法為將先檔案儲存在Server的主機上並且也回傳檔案路徑回來。

public void ExportExcel()
{
    // 設定網頁ContentType
    HttpContext.Current.Response.ContentType = "application/vnd.ms-excel";
    HttpContext.Current.Response.AddHeader("Content-Disposition", string.Format("attachment;filename={0}", ExportFileName));
    HttpContext.Current.Response.Clear();
    // 讀取樣版資料
    LoadSheet();
    // 執行報表邏輯
    ReportLogic();  
    // 報表寫入資料流
    MemoryStream file = new MemoryStream();
    HssfWorkbook.Write(file);
    // 輸出報表跳出下載視窗
    HttpContext.Current.Response.BinaryWrite(file.GetBuffer());
    HttpContext.Current.Response.End();
}

public string SaveExcel()
{
    // 讀取樣版資料
    LoadSheet();
    // 執行報表邏輯
    ReportLogic();  
    // 儲存檔案路徑
    string saveFilePath = ExportPath + ExportFileName;
    // 報表寫入資料流
    FileStream file = new FileStream(HttpContext.Current.Server.MapPath(saveFilePath), FileMode.Create);
    HssfWorkbook.Write(file);
    file.Close();
    // 回傳產出檔案路徑
    return saveFilePath;
}

 

以上就是一個基本的 NPOI 動態產生 EXCEL 的使用範例,基本上抓下來後依照這種方式作或添加新設定就可以產生EXCEL,而針 NPOI 對於 EXCEL 的操作方法還有很多種設定,例如合併欄、其它函式操作、畫圖形等等的功能可以去參考 NPOI 官方文件網站查詢。

 

結果:

 

 

範例程式碼


TNPOI.rar

 

參考資料


官方網站

 

 


以上文章敘述如有錯誤及觀念不正確,請不吝嗇指教
如有侵權內容也請您與我反應~謝謝您 :)