要如何透過 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
- onkeyup=”myFunction()”
- 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)