Have fun! 新手也能打造的Javascript微型專案! Day23: 你的頁面有表格嗎? 替它加個輸出成Csv檔案按鈕吧!

tags: ItIron2022 Javascript

前言

嚴格說起來這並不算個微型專案,不過確實是一個相當常見的功能,許多在實務上的專案會直接採用第三方套件來處理,但實際上自己寫並不是這麼的困難,今天就讓我們來完成這個實用的功能吧!

預期成果

我們這次要做的成果再簡單也不過了,點擊按鈕後會將表格的內容下載為一個csv檔案,that’s it!

Getting started

Step1: 專案結構

首先一樣請你建立幾個基本的檔案,也就是index.html, style.css, script.js,但由於這次僅是要demo下載的功能,實際上你也可以弄個codepen就行囉!

老樣子我們先處理ui的部分,請在html & css檔案寫入以下內容

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Export As Excel Demo</title>
    <link rel="stylesheet" href="./style.css" />
    <script src="./script.js" defer></script>
  </head>
  <body>
    <div class="export-btn">Export as CSV</div>
    <div class="table-container">
      <span class="table-header">ID</span>
      <span class="table-header">Name</span>
      <span class="table-header">Gender</span>
      <span class="table-body">1</span>
      <span class="table-body">Danny</span>
      <span class="table-body">Male</span>
      <span class="table-body">2</span>
      <span class="table-body">Mike</span>
      <span class="table-body">Male</span>
      <span class="table-body">3</span>
      <span class="table-body">Cindy</span>
      <span class="table-body">Female</span>
    </div>
  </body>
</html>
* {
  padding: 0;
  margin: 0;
  box-sizing: border-box;
}

body {
  height: 100vh;
  display: flex;
  flex-direction: column;
  gap: 16px;
  justify-content: center;
  align-items: center;
}

.table-container {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  border: 1px solid black;
}

.table-container > span {
  padding: 8px 4px;
  border: 1px solid black;
}

.export-btn {
  padding: 8px 16px;
  border: 1px solid black;
  border-radius: 8px;
  cursor: pointer;
  font-weight: bold;
}

此時看到的畫面應為這樣,相當的簡陋,但堪用了

Step2: 加入下載csv檔案功能

接著就是今天的最後一步了,是的,就這麼簡單。偶爾也需要放鬆一下。
我們還是要釐清一下等一下的目的,一般以表格來說你收到的資料格式會是類似這樣

const tableData = [
  ["ID", "Name", "Gender"],
  ["1", "Danny", "Male"],
  ["2", "Mike", "Male"],
  ["3", "Cindy", "Female"],
];

也就是一列一列的給資料,我們要將其弄成csv檔案的格式其實很簡單,只要把每一個列的值用","連接起來,該列沒有資料時再換下一列即可!
剩下的東西就簡單多了,要透過點擊並下載檔案有個很常見的方法,就是建立一個a元素,並附上對應的屬性讓它知道你要下載什麼檔案,最後用dom操作去點擊該元素即可!

大略理解以上的內容後就請你將以下的內容寫入js檔案中,我知道有些東西你看起來會很困惑,我會作相應的說明,放心。

const exportBtn = document.querySelector(".export-btn");

const tableData = [
  ["ID", "Name", "Gender"],
  ["1", "Danny", "Male"],
  ["2", "Mike", "Male"],
  ["3", "Cindy", "Female"],
];

const exportToCsv = () => {
  let csvString = "";
  tableData.forEach((rowItem) => {
    rowItem.forEach((colItem) => {
      csvString += colItem + ",";
    });
    csvString += "\r\n";
  });

  csvString = "data:application/csv," + encodeURIComponent(csvString);
  let anchor = document.createElement("a");
  anchor.setAttribute("href", csvString);
  anchor.setAttribute("download", "demo.csv");
  document.body.appendChild(anchor);
  anchor.click();
};

exportBtn.addEventListener("click", () => {
  exportToCsv();
});
  • download屬性
    加入download屬性後便可以觸發download的行為,第二個參數則是檔案的名稱,其中包括副檔名。
  • csvString

利用"data:application/csv,"這樣的前綴可以讓瀏覽器知道這個檔案的類型與內容,這類data:前綴的概念稱作Data Urls,有興趣的可以參考MDN的說明

接著再讓我們在表格中的文字透過encodeURIComponent函數處理,讓它可以正確地被編譯(以防有特殊文字或中文字元),最終將一切連接在一起就是一個有完整表格內容的字串囉!

總結

這麼一來今天的示範就完成了! 雖然簡單但卻是後台常見的功能之一,實際自己寫寫也不會真的多困難,今天結束之後我們就會進入最後的幾個主題,今年的系列文就會結束啦!!

文章中的範例程式碼可以在這邊取得,歡迎自行取用

轉職Q & A

Danny,收到offer之後對方有先問我可以上工的時間,但我還有其他面試過程進行中,這該怎麼辦呢?

很好、也是很實在的問題,我是覺得這種問題並沒有所謂的標準答案,但我可以分享我自己的回答模式。
就像我之前有提到的,我認為求職是一種雙向的概念,求職者並沒有必要將自己的地位放太低,很多需求都是可以討論的,那種要你下週馬上上班的公司我覺得反而是一種不尊重。

一般來說我都會老實的回答自己目前的面試進度,並告知面試流程大致什麼時候結束,在那之後就會正式考慮要接受哪一份offer,從接受offer到上工會需要1~2週的時間(搬家、雜事處理之類的,可以隨自己的需求拉長/縮短時間)。也許你會覺得公司不可能願意等你這麼久,在某些企業可能是這樣吧! 但面試一個工程師需要花費相當高的時間成本,且求職者同時有幾個面試在跑也是極為正常的事情,比起這短短的等待時間,重新面試人選反倒是更不划算的選擇,願意尊重員工的公司我想在這方面都是比較好溝通的,就放心地提出你的要求吧! 老實、誠懇是你的好幫手,再次強調你並不需要把自己姿態放很低,需求是互相的!

廣告

發表迴響

在下方填入你的資料或按右方圖示以社群網站登入:

WordPress.com 標誌

您的留言將使用 WordPress.com 帳號。 登出 /  變更 )

Twitter picture

您的留言將使用 Twitter 帳號。 登出 /  變更 )

Facebook照片

您的留言將使用 Facebook 帳號。 登出 /  變更 )

連結到 %s