PHP – CSV -> Table + Search Bar

Loading

要如何透過 PHP 來讀取 Linux 下 CSV (每筆資料用 “,” 做區分) 檔案並把它轉成為 HTML Table 而且可以透過 search bar 來篩選(搜尋)內容.

測試環境為 CentOS 7 虛擬機 (IP: http://192.168.95.205) , Apache 安裝設定請參考 https://benjr.tw/323 , 如果使用 Nginx (Web server) 請參考 – https://benjr.tw/95761 與 PHP-FPM – https://benjr.tw/95767

使用 Ubuntu 16.04 x86_64 設定 Apache2 請參考 https://benjr.tw/95861 , web server 為 Nginx 請參考 https://benjr.tw/96633 .

參考網頁 https://www.w3schools.com/howto/howto_js_filter_table.asp

csv 檔為同事下午茶由 Excel 轉出的檔案,需注意 windows 記事本 notepad 處理中文編輯時,需將檔案 另存新檔 並將 編碼 選擇為 UTF-8 (8-bit Unicode Transformation Format) , HTML 顯示時才不會出現亂碼.

[root@localhost html]# cat tea.csv
Name,飲料品名,容量(M/L),備註,價錢
Ben1,粉圓綠茶,M,去冰無糖,30
Ben2,粉圓鮮奶茶,L,微糖去冰,60
Ben3,大甲芋頭鮮奶,M,"熱,半糖",65
Ben4,大甲芋頭鮮奶綠,M,微糖,65
Ben5,溪口甘蔗青茶,L,微糖去冰甘蔗濃,68
Ben6,鹿港麵茶,L,去冰微糖,65
Ben7,溪口甘蔗清茶 + 粉圓,L,去冰微糖,73
Ben8,溪口甘蔗清茶 + 粉圓,L,去冰微糖,73
Ben9,溪口甘蔗牛奶,L,微糖去冰(牛奶無法做甘蔗濃),68
Ben10,粉圓鮮奶茶,L,微糖去冰,60
Ben11,大甲芋頭鮮奶,M,微糖,65
Ben12,溪口甘蔗清茶 + 粉圓,L,去冰微糖,73
Ben13,冬瓜檸檬露加愛玉,L,微糖常溫-加點九如檸檬青茶(去冰無糖55),70
Ben14,溪口甘蔗牛奶,L,去冰無糖,68
Ben15,宜蘭金桔綠,L,少冰無糖,55
Ben16,中華愛玉檸檬,L,去冰微糖,55
Ben17,溪口甘蔗牛奶,L,去冰半糖,68
Ben18,溪口甘蔗牛奶,L,微冰半糖,68
Ben19,大甲芋頭鮮奶,M,微糖,65

程式碼如下(有 CSS , PHP 與 javascript):

<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
* {
  box-sizing: border-box;
}

#myInput {
  background-image: url('/css/searchicon.png');
  background-position: 10px 10px;
  background-repeat: no-repeat;
  width: 100%;
  font-size: 16px;
  padding: 12px 20px 12px 40px;
  border: 1px solid #ddd;
  margin-bottom: 12px;
}

#myTable {
  border-collapse: collapse;
  width: 100%;
  border: 1px solid #ddd;
  font-size: 18px;
}

#myTable th, #myTable td {
  text-align: left;
  padding: 12px;
}

#myTable tr {
  border-bottom: 1px solid #ddd;
}

#myTable tr.header, #myTable tr:hover {
  background-color: #f1f1f1;
}
</style>
</head>
<body>
<h2>My Customers</h2>

<input type="text" id="myInput" onkeyup="myFunction()" placeholder="Search for names.." title="Type in a name">

<table id="myTable">
  <tr class="header">
    <th style="width:15%;">Name</th>
    <th style="width:15%;">飲料品名</th>
    <th style="width:15%;">容量(M/L)</th>
    <th style="width:15%;">備註</th>
    <th style="width:15%;">價錢</th>
  </tr>
<?php
$file = fopen("tea.csv","r") or die("Unable to open file!");
while (($line = fgetcsv($file)) !== false) {
        echo "<tr>";
        foreach ($line as $cell) {
                echo "<td>" . htmlspecialchars($cell) . "</td>";
        }
        echo "</tr>\n";
}
fclose($file);
?>
</table>

<script>
function myFunction() {
  var input, filter, table, tr, td, i, txtValue;
  input = document.getElementById("myInput");
  filter = input.value.toUpperCase();
  table = document.getElementById("myTable");
  tr = table.getElementsByTagName("tr");
  for (i = 0; i < tr.length; i++) {
    td = tr[i].getElementsByTagName("td")[0];
    if (td) {
      txtValue = td.textContent || td.innerText;
      if (txtValue.toUpperCase().indexOf(filter) > -1) {
        tr[i].style.display = "";
      } else {
        tr[i].style.display = "none";
      }
    }       
  }
}
</script>

</body>
</html>

執行結果:
[php_everywhere]

程式可以區分為三段.

  • CSS
    <!DOCTYPE html>
    <html>
    <head>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <style>
    * {
      box-sizing: border-box;
    }
    
    #myInput {
      background-image: url('/css/searchicon.png');
      background-position: 10px 10px;
      background-repeat: no-repeat;
      width: 100%;
      font-size: 16px;
      padding: 12px 20px 12px 40px;
      border: 1px solid #ddd;
      margin-bottom: 12px;
    }
    
    #myTable {
      border-collapse: collapse;
      width: 100%;
      border: 1px solid #ddd;
      font-size: 18px;
    }
    
    #myTable th, #myTable td {
      text-align: left;
      padding: 12px;
    }
    
    #myTable tr {
      border-bottom: 1px solid #ddd;
    }
    
    #myTable tr.header, #myTable tr:hover {
      background-color: #f1f1f1;
    }
    </style>
    </head>
    

    CSS說明:
    # 開頭表示為 CSS ID ,因為後面的 javascript 函數 GetElementByID 使用時只能指定 ID ,無法使用 Class (兩者的差別在於 ID 在 HTML 文件中只能被使用一次,而 Class 可以被多次使用).

  • PHP
    將 CSV 檔案轉換成為 HTML Table 格式.

    <body>
    
    <h2>My Customers</h2>
    
    <input type="text" id="myInput" onkeyup="myFunction()" placeholder="Search for names.." title="Type in a name">
    
    <table id="myTable">
      <tr class="header">
        <th style="width:15%;">Name</th>
        <th style="width:15%;">飲料品名</th>
        <th style="width:15%;">容量(M/L)</th>
        <th style="width:15%;">備註</th>
        <th style="width:15%;">價錢</th>
      </tr>
    <?php
    $file = fopen("tea.csv","r") or die("Unable to open file!");
    while (($line = fgetcsv($file)) !== false) {
            echo "<tr>";
            foreach ($line as $cell) {
                    echo "<td>" . htmlspecialchars($cell) . "</td>";
            }
            echo "</tr>\n";
    }
    fclose($file);
    ?>
    </table>
    

    函數說明:

    • onkeyup=”myFunction()”
      這個就是後面自訂的 Javascript .
    • fopen() – Opens file or URL
      fopen ( string $filename , string $mode [, bool $use_include_path = FALSE [, resource $context ]] ) : resource
    • or die() – or 的用法跟 Linux bash script 的 cmd1 || cmd2 一樣 ,若 cmd1 執行正確且無錯誤,則 cmd2 不執行 ,反之若 cmd1 執行完畢且為錯誤,則開始執行 cmd2.
      會有下列的兩種情況.
      若 fopen(“test.txt”, “r”) 執行正確且無錯誤就結束.
      若 fopen(“test.txt”, “r”) 執行失敗就執行 die(“Unable to open file!”) (die 等同 exit – http://php.net/manual/en/aliases.php )- 顯示訊息並跳出程式.
    • fgets() – Gets a line from file pointer
      fgets ( resource $handle [, int $length ] ) : string
    • foreach() – The foreach construct provides an easy way to iterate over arrays.
      foreach (array_expression as $value) , foreach (array_expression as $key => $value)
    • htmlspecialchars() – Convert special characters to HTML entities
      htmlspecialchars ( string $string [, int $flags = ENT_COMPAT | ENT_HTML401 [, string $encoding = ini_get(“default_charset”) [, bool $double_encode = TRUE ]]] ) : string
    • fclose() – Closes an open file pointer
      close ( resource $handle ) : bool
  • Javascript
    只顯示與搜尋 Keyword 相關的欄位.

    <script>
    function myFunction() {
      var input, filter, table, tr, td, i, txtValue;
      input = document.getElementById("myInput");
      filter = input.value.toUpperCase();
      table = document.getElementById("myTable");
      tr = table.getElementsByTagName("tr");
      for (i = 0; i < tr.length; i++) {
        td = tr[i].getElementsByTagName("td")[0];
        if (td) {
          txtValue = td.textContent || td.innerText;
          if (txtValue.toUpperCase().indexOf(filter) > -1) {
            tr[i].style.display = "";
          } else {
            tr[i].style.display = "none";
          }
        }       
      }
    }
    </script>
    </body>
    </html>
    

    函數說明 – TBD :

    • getElementById();
    • getElementsByTagName();
    • input.value.toUpperCase();
    • txtValue.toUpperCase().indexOf(filter)
沒有解決問題,試試搜尋本站其他內容

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *

這個網站採用 Akismet 服務減少垃圾留言。進一步了解 Akismet 如何處理網站訪客的留言資料