2022年12月28日 星期三

HTML5 測試 : 讀寫本機文字檔案

今天在搜尋用瀏覽器讀寫本機檔案的方式時找到下面這篇文章 :


我以前使用微軟 ActiveX 的 FileSystemObject 物件來處理本機檔案讀寫, 但那只能用在 IE 與 Edge, 沒辦法在 Chrome 或 FireFox 上跑. 此篇文章使用 HTML5 的 FileReader 物件來讀取本機文字檔, 可以在任何瀏覽器上執行. 可惜 FileWriter 目前還在開發中尚未成熟, 否則就能踢開 ActiveX 了.  

由於這篇文章兼具說明用途, 原始碼夾在一堆 HTML 碼裡面較難閱讀, 我將其改寫為如下之範例來測試檔案讀取功能 : 



<!DOCTYPE html>
<html>
<head>
  <title>檔案讀取</title>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width,initial-scale=1">
</head>
<body>
  <input type="file" onchange="read_file(this)"><br><br>
  <textarea id="content" cols="80" rows="15"></textarea>
  <script>
    function $(id) {return document.getElementById(id);}
    function read_file(obj){
      file=obj.files[0];
      var fr=new FileReader();           
      fr.onload=function(e) {
        $('content').value=e.target.result;
        };
      fr.readAsText(file);      
      }
  </script>
</body>
</html>

此例網頁上有一個 type=file 的 input 按鈕元素, 當按下此按鈕時會觸發 onchange 事件 (注意不是 onclick 事件) 呼叫 read_file() 函式並傳入此按鈕物件, 其 files[0] 屬性會取得所選取之檔案內容, 然後建立一個 FilerReader 物件來讀取此檔案, 當載入完成就會觸發 onload 事件, 將檔案內容放入 textarea 元素中 (此處我模仿 jQuery 的 $ 來取得 DOM 物件).

我在 Chrome, Firefox, 以及 Edge 測試確實可用 :




不過檔案選取按鈕在不同瀏覽器上顯示的外觀不同, Chrome 與 Edge 都顯示 "選擇檔案", 而 FireFox 則顯示 "瀏覽 ...".

雖然 HTML5 的 FileWriter 尚未被實作在眾瀏覽器中, 若要將網頁中的資料儲存於本機中可以利用 window.location.href 下載檔案的方式來暫代, 參考下面這篇 : 


關鍵是如下指令 : 

window.location.href="data:application/x-download;charset=utf-8," + encodeURIComponent(data);

程式結構與上面類似, 如下面範例所示 :



<!DOCTYPE html>
<html>
<head>
  <title>檔案寫入 (下載)</title>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width,initial-scale=1">
</head>
<body>
  <input type="file" onchange="read_file(this)"><br><br>
  <textarea id="content" cols="80" rows="15"></textarea><br><br>
  <button onclick="write_file()">儲存內容</button>
  <script>
    function $(id) {return document.getElementById(id);}
    function read_file(obj){
      file=obj.files[0];
      file_name=file.name;
      var fr=new FileReader();           
      fr.onload=function(e) {
        $('content').value=e.target.result;
        };
      fr.readAsText(file);      
      }
    function write_file(){
      data=$('content').value
      window.location.href="data:application/x-download;charset=utf-8," +    
                           encodeURIComponent(data);      
      }
  </script>
</body>
</html>

結果如下 : 




選取檔案讀入文字檔內容進行編輯, 然後按 "儲存內容" 會詢問儲存到哪一個 : 




填入檔名按 "存檔" 即可.  

此外也可以用 document.createElemen() 建立一個 a 元素後將要下載的內容設定給 href 屬性, 然後呼叫其 click() 方法下載, 作法參考下面這篇 (#42) : 


<!DOCTYPE html>
<html>
<head>
  <title>檔案寫入 (下載)</title>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width,initial-scale=1">
</head>
<body>
  <input type="file" onchange="read_file(this)"><br><br>
  <textarea id="content" cols="80" rows="15"></textarea><br><br>
  <button onclick="write_file()">儲存內容</button>
  <script>
    function $(id) {return document.getElementById(id);}
    function read_file(obj){
      file=obj.files[0];
      file_name=file.name;
      var fr=new FileReader();           
      fr.onload=function(e) {
        $('content').value=e.target.result;
        };
      fr.readAsText(file);      
      }
    function write_file(){
      var a=document.createElement('a');
      data=$('content').value
      a.href="data:application/x-download;charset=utf-8," +
             encodeURIComponent(data);    
      a.click();
      }
  </script>
</body>
</html>

結果與上面用 window.location.href 一樣. 

沒有留言 :