[ASP.NET MVC] 匯出 .csv 檔案

常見的匯出檔案有 .pdf .xls .ods .csv,下面筆記最簡單的 .csv 檔,可用常見的 Microsoft Office Excel 或 LibreOffice Calc 等報表軟體開啟:


產生檔案下載

Controller 可以用 return File(); 來做到檔案下載,引數分別為 byte[] 的檔案內容,string 表示的檔案類型和 string 下載後檔案名稱,而 byte[] 類型可用 System.Text.Encoding.Default.GetBytes() 方法來獲得位元組序列,以下為名稱 Demo 的 Controller 程式碼:

  using System.Text;
  namespace prjMVC.Controllers
  {
    public class DemoController : Controller
    {
      public ActionResult GetFiles(string output)
      {
        string fileName = "output.txt";                            // 存成檔名
        byte[] fileContent = Encoding.Default.GetBytes(output);    // 轉成位元組序列
        return File(fileContent, "text/plain", fileName);
      }
    }
  }

以上 Action 在瀏覽器輸入 ~/Demo/GetFiles?output=xxxx 的網址,或是 View 中有 @Html.ActionLink("下載", "GetFiles", new { output = "xxxx" }) 產生的超連結被點擊時,瀏覽器就會下載一個文字檔案 output.txt:

下面就是傳入 output 字串 "測試文字" 得到的下載文字檔案:


列出清單結果

這個部份不是產生匯出檔案必要的,但是通常是先在網頁有呈現結果,再提供匯出檔案的功能,所以我也把這個部份做出來。而且因為網頁呈現與匯出檔案都需要一樣的資料,所以我先在 ~/Service 資料夾增加一個SEmployee.cs 類別檔案,負青處理列出資料的邏輯,以下為 SEmployee.cs 的程式碼:

  using System.Collections.Generic;
  using System.Linq;
  using prjMVC.Models;

  namespace prjMVC.Service
  {
    public class SEmployee
    {
      dbTestEntity db = new dbTestEntity();
      public List<Employee> QueryAll()
      {
        return db.Employee.ToList();    // 用 EntityFramework 取得所有員工資料
      }
    }
  }

而 DemoController 中有一個網頁呈現用的 Action List 和準備匯出檔案用的 Action Output:

  using System.Collections.Generic;
  using System.Linq;
  using prjMVC.Models;
  using prjMVC.Service;

  namespace prjMVC.Controllers
  {
    public class DemoController : Controller
    {
      SEmployee service = new SEmployee();

      public ActionResult List()
      {
        List<Employee> result = service.QueryAll();
        return View(result) ;    // 將查詢的員工資料傳給 View
      }

      [HttpPost]
      public ActionResult OutputCSV()
      {
        return View();           // 暫時這樣寫,等下改寫成 return File();
      }
    }
  }
      

而 List 的 View 中除了 foreach 遍歷所有資料放入 <table> 中,還有一個 <input type="submit"> 的 button 來提供匯出 .csv 檔案:

  @model IEnumerable<prjMVC.Models.Employee>
  @{
    ViewBag.Title = "List";
  }

  <h2>List</h2>
  <p>
      @Html.ActionLink("Create New", "Create")
  </p>
  @using (Html.BeginForm("OutputCSV","Demo"))    // Post 去 OutputCSV 這個 Action
  {
    @Html.TextBox("btn", "匯出檔案", new  { @class= "btn btn-success", type="submit" })
  }

  <table class="table">
    <tr>
      <th>
        @Html.DisplayNameFor(model => model.Name)
      </th>
      <th>
        @Html.DisplayNameFor(model => model.Salary)
      </th>
      <th></th>
    </tr>

  @foreach (var item in Model) {                 // 遍歷資料
    <tr>
      <td>
        @Html.DisplayFor(modelItem => item.Name)
      </td>
      <td>
        @Html.DisplayFor(modelItem => item.Salary)
      </td>
      <td>
        @Html.ActionLink("Edit", "Edit", new { id=item.Id }) |
        @Html.ActionLink("Details", "Details", new { id=item.Id }) |
        @Html.ActionLink("Delete", "Delete", new { id=item.Id })
      </td>
    </tr>
  }
  </table>

以上 View 的結果是:

點擊那個「匯出檔案」按鈕要產生 .csv 檔案並下載,接下來來看 OutputCSV() 的內容。


匯出 .csv 檔案

在匯出前先看 .csv 是怎麼一回事,使用記事本打開會發現,其實也就是用逗點和斷行字元做出來的純文字檔案:

其實他只是文字檔案,這樣方向就很簡單了,我們可以使用 StringBuilder 物件將 List<Employee> 資料串出字串,然後讓 Controller 以 return File() 回傳,就可以下載檔案,以下是 Controller 內的 OutputCSV Action 的程式碼:

  using System.Text;
  using prjMvc.Service;

  namespace prjMVC.Controllers
  {
    public class DemoController : Controller
    {
      SEmployee service = new SEmployee();

      [HttpPost]
      public ActionResult OutputCSV()
      {
        List<Employee> qryResult = service.QueryAll();

        StringBuilder sb = new StringBuilder();
        sb.AppendLine("姓名,薪水");            // .csv 的第一列標題
        foreach(Employee emp in qryResult)
        {
          sb.AppendLine($"{emp.Name},{emp.Salary}");
        }
        string fileName = "薪水.csv";          // 存成檔名
        byte[] fileContent = Encoding.Default.GetBytes(sb.ToString());
        return File(fileContent, "text/plain", fileName);
      }
    }
  }

在點擊「匯出檔案」按鈕後瀏覽器就會下載一份 .csv 檔案到資料夾中。

留言