Web上でファイルの読み・書き
  1. Web Storage でデータを保存
     Web Storageはブラウザにデータを保存するクッキーの後継的な仕組みで、データの保存・上書き・削除・クリアなどの操作を JavaScriptで行うことが出来ます。
     Web Storage には、sessionStorageと localStorageの2種類が用意されており、キー(key)と値(value)とをペアで保存します。  参考1  参考2  参考3
      ウィンドウ間の
    データ共有
    データの有効期限 データ量の上限 サーバーへのデータ送信
    sessionStorage    × ウィンドウやタブを閉じるまで 1オリジン当たり5MB 必要時のみスクリプトやフォームで送信
    localStorage    ○ 永続的に有効
    クッキー    ○ 指定期限まで 4KB サーバーへアクセスする度に自動送信
      
    *オリジン: 「http://www.example.com:80」のような「URL のスキーム://ホスト名:ポート番号」(言わば一ウェブサイト)のこと 参考
     localStorage、sessionStorage オブジェクトのメソッド・属性
    メソッド 説明 記述例 1 記述例 2
    setItem(key, value) key に値(value)を設定 localStorage.setItem("sample", "Sample Data"); localStorage.sample = "Sample Data";
    getItem(key) key の値を参照 localStorage.getItem("sample"); localStorage["sample"];
    key(n) n番目のキーを取得 localStorage.key(n); sessionStorage.key(n);
    removeItem(key) key の値を削除 localStorage.removeItem("sample"); sessionStorage.removeItem("sample");
    clear() 値をすべて削除 localStorage.clear(); sessionStorage.clear();
    length 保存されているデータの数 localStorage.length; sessionStorage.length;
     sessionStorage の利用例 → 動作例 別窓表示
    <!DOCTYPE html>
    <html lang="ja">
    <head>
      <meta charset=utf-8>
      <title>Web Storage サンプル</title>
      <style>
        body { background:#fff; }
        section{ width:600px; margin:0 auto; font-size: 14; }
        #show_result {  background:#eee;
          display: block; padding: 0; margin:0 0 16px 0; width: 100%; }
      </style>
      <script>
        if(('sessionStorage' in window) && (window.sessionStorage !== null)) {
          alert("sessionStorage が使えます"); // セッションストレージが使える
        } else {
          alert("sessionStorage がサポートされていません"); // 使えない。
        }
       
        var storage = sessionStorage; //変数storageにsessionStorageを格納
    
        //データを保存する
        function set() {
          var k = document.getElementById("k").value;
          var v = document.getElementById("v").value;
          storage.setItem(k, v);  // 指定key でデータを保存
          show_result();
        }
    
        //データを削除する
        function remove() {
          var txt = document.getElementById("keyin").value;
          storage.removeItem(txt);  // 指定key に対応するデータを削除
          show_result();
        }
    
        //全データをクリアする
        function cle() {
          storage.clear();
          show_result();
        }
    
        //保存されているデータをリスト表示する
        function show_result() {
          var result = "";
          for(var i=0; i<storage.length; i++){   // データの数だけループ
            var k = storage.key(i);  //i番目のキーを取得
            //キーと値をコロン(:)区切りのテキストにする
            result += k + ":" + storage.getItem(k) + "<br>";
          }
          //上のループで作成されたテキストを表示する
          document.getElementById("show_result").innerHTML = result;
        }
      </script>
    </head>
    <body onload="show_result()">
      <section>
        <p>
          key: <input id="k" type="text" size=8>
           値: <input id="v" type="text" size=36>
          <input type="button" value="Storageに保存" onClick="set()">
        </p>
        <div>
          ■ sessionStorage 一覧
          <div id="show_result"> sessionStorage 一覧</div>
          削除対象key: <input type="text" id="keyin" value="keyを入力" size=10>
          <input type="button" value="keyデータを削除" onClick="remove()">    
          <input type="button" value="ストレージ全体をクリア" onClick="cle()">
        </div>
      </section>
    </body>
    </html>
     ■ localStorage の利用例 参考 地図マーカーデータ
      data保存の例 (キーを決めてデータを保存する) 別窓表示
    <!DOCTYPE html>
    <html lang="ja">
    <head>
      <meta charset=utf-8>
      <title>localStorage サンプル01</title>
      <style>
        section{ width:650px; margin:0 auto; font-size: 14; background:#ffe; }
        #show_result {  background:#eee; overflow:auto; padding: 5px; margin:0 0 16px 0; height:200px; }
      </style>
      <script>
        if(('localStorage' in window) && (window.localStorage !== null)) {
         // alert("localStorage が使えます"); // localStorageが使える
        } else {
          alert("localStorage がサポートされていません"); // 使えない。
        }
        var storage = localStorage; //変数storageに localStorageを格納
        //データを保存する
        function set() {
          var k = document.getElementById("k").value;
          var v = document.getElementById("v").value;
          storage.setItem(k, v);  // 指定key でデータを保存
          show_result();
        }
        //データを削除する
        function remove() {
          var txt = document.getElementById("keyin").value;
          storage.removeItem(txt);  // 指定key に対応するデータを削除
          show_result();
        }
        //全データをクリアする
        function cle() {
          storage.clear();
          show_result();
        }
        //保存されているデータをリスト表示する
        function show_result() {
          var result = "";
          for(var i=0; i<storage.length; i++){   // データの数だけループ
            var k = storage.key(i);  //i番目のキーを取得
            //キーと値をコロン(:)区切りのテキストにする
            result += k + ":" + storage.getItem(k) + "<br>";
          }
          //上のループで作成されたテキストを表示する
          document.getElementById("show_result").innerHTML = result;
        }
      </script>
    </head>
    <body onload="show_result()">
      <section>
        <p>
           key: <input id="k" type="text" size=7  value="test">
           値: <input id="v" type="text" size=47  value="これはローカルストレージのテストです">
          <input type="button" value="localに保存" onClick="set()">
        </p>
        <div>
          ■ localStorage 一覧
          <div id="show_result"> localStorage 一覧</div>
           削除対象key: <input type="text" id="keyin" value="keyを入力" size=10>
          <input type="button" value="keyデータを削除" onClick="remove()">    
          <input type="button" value="localStorage全体をクリア" onClick="cle()">
        </div>
      </section>
    </body>
    </html>
      data読出しの例 (保存済みデータをキーを指定して呼び出す) 別窓表示
    <!DOCTYPE html>
    <html lang="ja">
    <head>
      <meta charset=utf-8>
      <title>localStorage サンプル02</title>
      <style>
        section{ width:650px; margin:0 auto; font-size: 14; background:#ffe; }
        #outlcl{ border:2px #c66 dashed; height:60px; margin-bottom:1em;  padding:5px; overflow:auto; }    
        #show_result {  background:#eee; overflow:auto; padding: 5px; margin:0 0 16px 0; height:200px; }
      </style>
      <script>
        if(('localStorage' in window) && (window.localStorage !== null)) {
         // alert("localStorage が使えます"); // localStorageが使える
        } else {
          alert("localStorage がサポートされていません"); // 使えない。
        }
        var storage = localStorage; //変数storageに localStorageを格納
        // データを呼び出す
        function read() {
          var k = document.getElementById("k").value;
          document.querySelector("#outlcl").innerText = storage.getItem( k );
        }
        // データを保存する
        function set() {
          var k = document.getElementById("k").value;
          var v = document.getElementById("v").value;
          storage.setItem(k, v);  // 指定key でデータを保存
          show_result();
        }
        // データを削除する
        function remove() {
          var txt = document.getElementById("keyin").value;
          storage.removeItem(txt);  // 指定key に対応するデータを削除
          show_result();
        }
        //全データをクリアする
        function cle() {
          storage.clear();
          show_result();
        }
        //保存されているデータをリスト表示する
        function show_result() {
          var result = "";
          for(var i=0; i<storage.length; i++){   // データの数だけループ
            var k = storage.key(i);  //i番目のキーを取得
            //キーと値をコロン(:)区切りのテキストにする
            result += k + ":" + storage.getItem(k) + "<br>";
          }
          //上のループで作成されたテキストを表示する
          document.getElementById("show_result").innerHTML = result;
        }
      </script>
    </head>
    <body onload="show_result()">
      <section>
        <p>
           key: <input id="k" type="text" size=8  value="test">
          <input type="button" value="指定 key の内容の呼び出し" onClick="read()">
        </p>
        ■ key の localStorageを表示します
        <div id='outlcl'>ここに keyの localStorageの内容を表示します</div>
        <div>
          ■ localStorage 一覧
          <div id="show_result"> localStorage 一覧</div>
           削除対象key: <input type="text" id="keyin" value="keyを入力" size=10>
          <input type="button" value="keyデータを削除" onClick="remove()">    
          <input type="button" value="localStorage全体をクリア" onClick="cle()">
        </div>
      </section>
    </body>
    </html>
     ※ Web Storage  概要と使い方  仕組み  注意点  F12 ツール  Excel用に出力  使い方

  2. Blob の利用
     Blob ( Binary Large Object )は、データベース管理システム(DBMS)においてバイナリデータを格納する場合のデータ型です。画像や音声、動画、実行ファイル、圧縮ファイルなど様々なデータをデータベースのレコード中に直接格納するために用いられます。  参考1  参考2  参考3  参考4  参考5

     Blob の利用例 1 → 動作例 別窓表示
    <!DOCTYPE html>
    <html lang="ja">
    <head>
      <meta charset="UTF-8">
      <style>
        section { width:600px; margin:0 auto; text-align: center; background:#efe; }
        #output, #download { background:#eef; margin-bottom:5px; }
        section>div { margin-left: 20%; text-align:left; }
      </style>
    <title>Blob</title>
      <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
      <script>
          $(function() {
            if (typeof Blob == "undefined") {
              alert('このブラウザには対応していません');
            } else {
              //  alert('このブラウザに対応しています');
            }
            $("#content").keyup(function(){
              setBlobUrl("download", $("#content").val());
            });
            $("#content").keyup(); // 上で設定したkeyupイベント(setBlobUrl)を実行する
          });
          function setBlobUrl(id, content) {
            // 指定されたデータを保持するBlobを作成する。
            var blob = new Blob([ content ], { "type" : "application/x-msdownload" });
            // Aタグのhref属性にBlobオブジェクトを設定する。
            window.URL = window.URL || window.webkitURL;
            $("#" + id).attr("href", window.URL.createObjectURL(blob));
            $("#" + id).attr("download", "tmp.txt"); // tmp.txt 名でダウンロード
            document.getElementById("output").innerHTML = content;
            document.getElementById("Bsize").innerHTML = "Blob.size = "+blob.size;
            document.getElementById("Btype").innerHTML = "Blob.type = "+blob.type;
          }
      </script>
    </head>
    <body>
      <section>
        入力: <br>
        <textarea id="content" cols="50" rows="5"> このテキストを修正すると・・・・
     blob が生成され、下の枠内表示も修正され、
     ダウンロードも出来ます。</textarea>
        <div id="Bsize"></div>
        <div id="Btype"></div>
        <br>
        出力: <br>
        <textarea id="output" cols="50" rows="5"></textarea><br>
        <a id="download" target="_blank">ダウンロード</a>出来ます
      </section>
    </body>
    </html>
     ※ Blob  BLOBの読み込み  Blob と File クラス  Adapter Webject  File API : write  blob をダウンロード  blob  テキストを保存

     Blob の利用例 2 (csv 編集) → 動作例 別窓表示
    <!DOCTYPE html>
    <html lang="ja">
    <head>
    <meta charset="UTF-8">
    <style>
      header{ text-align:center;}
      .wrap { width:calc(70% + 320px); margin:0 auto; line-height:1.6; display:flex; }
      #bxleft{flex-basis:320px; background:#eff; padding:8px;} 
          #tablein { overflow: auto; padding:4px;  }
          #tablein { border-collapse: collapse; margin:0 auto; background: #fff; }
          #tablein td { font-size: 12px; padding: .2em .5em; border: solid 1px #ccc; text-align:center; }
          #tablein tr:first-child { background: #dfd; }
          #download { background:#eee; margin-bottom:5px; padding:0px 8px; border:#333 1px solid; }
      #bxright{ flex:3;height:500px; overflow:auto; background:#efe;}
    
    </style>
    <script>  
          let Elmnt = ""; // 表示する要素列    
          function init(){  // csv の読込設定
            var file = document.querySelector('#getfile');
            file.onchange = function (){    // input 変化時に読み込む
              var fileList = file.files;
              var reader = new FileReader();
              reader.readAsText(fileList[0]);
              reader.onload = function  () {    //読み込み後表示
                csv_array(reader.result); //csv_arrayの関数を実行 +++++++++++++
              };
            };
          }; //  init()  ----------------
    
          function csv_array(data) { // 読込ファイルをテーブル表示
            const dataArray = [];     // 配列を用意
            const dataString = data.split('\r\n'); // 改行で分割
            for (let i = 0; i < dataString.length; i++) { 
              dataArray[i] = dataString[i].split(','); 
            }
            let insertElement = ''; //テーブルタグ表示用の変数
            dataArray.forEach((element) => { //配列の中身を表示
              insertElement += '<tr>';
              for( i=0; i<element.length; i++){
                insertElement += '<td>' + element[i] + '</td>';
                if( i==0 ){ Elmnt += element[i]; 
                } else { Elmnt += ',' + element[i]; }
              }
              insertElement += '</tr>';
              Elmnt += '\n';
            });        
            let output_csv = document.getElementById('tablein');
            output_csv.innerHTML = insertElement; // 表示
          };//   csv_array(data)  ----------------
          
          function handleDownload() { // CSV出力&ダウンロード ------------
            var bom = new Uint8Array([0xEF, 0xBB, 0xBF]); //文字コードをBOM付きUTF-8に指定
            var table = document.getElementById('tablein'); //id=tableinという要素を取得
            var data_csv=""; //ここに文字データとして値を格納していく
     
            for(var i = 0;  i < table.rows.length; i++) {
              for(var j = 0; j < table.rows[i].cells.length; j++) {
                data_csv += table.rows[i].cells[j].innerText; //HTML中の表のセル値をdata_csvに格納
                if(j == table.rows[i].cells.length-1){  // 最終行末を除外
                  if( i != table.rows.length -1) {data_csv += "\r\n"; } //行終わりに改行コードを追加  \r
                } else { data_csv += ","; } //セル値の区切り文字として,を追加
              }
            }
            var blob = new Blob([ bom, data_csv], { "type" : "text/csv" }); //data_csv をダウンロードする関数
            if (window.navigator.msSaveBlob) { //IEの場合の処理
              window.navigator.msSaveBlob(blob, "test.csv");
              window.navigator.msSaveOrOpenBlob(blob, "test.csv");// msSaveOrOpenBlobの場合はファイルを保存せずに開ける
            } else {
              document.getElementById("download").href = window.URL.createObjectURL(blob);
            }
            delete data_csv; //data_csvオブジェクトはもういらないので消去してメモリを開放
          }; // handleDownload()  -------------------
    </script>
    </head>
    
    <body onload="init()">
      <header>
        <h3>csv 読込 → 編集 → 保存</h3>
      </header>
      <section class="wrap">
        <article id="bxleft">
          【***.csv を読込む】<br>
          <input type="file" id="getfile" accept="text/*" ><br><br>
          (右表は直接編集します)<br>
          <a id="download" href="" download="download.csv" onclick="handleDownload()">csv 保存</a>
          【ファイル名: download.csv】
        </article>
        <article id="bxright">
          <table id="tablein" contenteditable="true"></table>
        </article>
      </section>
    </body>
    </html>
  3. File API を利用
     File API は、JavaScript からクライアント側のファイルにアクセスするための API です。File オブジェクトは特別な Blob オブジェクトで Blob が利用できる場面で利用できます。  参考  File API  File APIを使う  File API入門
    • File API の利用例 → 動作例 別窓表示
      <!DOCTYPE html>
      <html>
      <head>
        <meta charset="utf-8" />
        <title>File API Sample</title>
        <style>
          html,body{ margin:0; padding:0px; }
          body{ background: url(https://kurage.ready.jp/img/p_bcg007.gif);  }
          h3{ margin:3px auto 10px; text-align:center; }
          #wrap { position:relative; width:1000px; margin:0 auto; padding:6px; background:#ffe; text-align:center; }
          #link{ position:absolute; top:8px; left:10px; }
          #wpdrop{ display:flex; justify-content:center; align-items:center; }
          #getfile{  width:100%;  height:30px;}
          #drop{ border:2px dashed #acf; width:40%; height:40px; background:#eee; }
          #disp1, #disp2 { width:98%; margin:2px auto; padding:3px; border:1px solid #cdd; overflow:auto; }
          #disp1{ height:40px; }
          #disp2{ height:300px; text-align:left; }
          li{ list-style-type:none; }
          textarea#dturl{ width:95%; height:330px; margin:3px auto; padding:3px; overflow:auto; }
        </style>
      </head>
      <body>
        <section id="wrap">
          <h3>画像、textファイルを、指定又はドラッグ&ドロップし、その内容を表示します</h3>
          <div id="wpdrop">
            <div id="link"><a href="../localF.html">localF</a></div>
            <div><input type="file" id="getfile" ></div>
               <article>文字コード<br>
                <select id="encode-type">
                  <option value="utf-8">utf-8</option>
                  <option value="shift-jis">shift-jis</option>
                </select>
            </article>  
            <article id="drop" ondragover="onDragOver(event);" >ここにファイルをドロップして下さい</article>
          </div>
          <div id="disp1" >ここにファイルの属性を表示します。</div>
          <div id="disp2" >画像はここに表示します。</div>
          <textarea id="dturl" readonly>テキスト、image data URL を出力</textarea>
        </section>
        
        <script type="text/javascript">
            let files = new Array;
            let encode_type;// = document.getElementById("encode-type").value;
            if (window.File) {  // File APIを利用できるかをチェック(1)
                //       window.alert("File APIが実装されてます。");
              let disp1 = document.getElementById("disp1");
              let disp2 = document.getElementById("disp2");
      
              document.getElementById("drop").addEventListener("drop", function(){
                files = event.dataTransfer.files;  // 転送中のデータを取得 for drop
                onstart() 
              }, false);
              
              document.getElementById("getfile").addEventListener("change",function(){
                files = event.target.files;   //選択ファイルを配列形式で取得  for change
                onstart() 
              }, false);
              
            } else {
                window.alert("本ブラウザではFile APIが使えません");
            }; // if (window.File)  ------------------------------
            
            // ファイルのプロパティ情報読み取り処理
            function onstart(event){
              encode_type = document.getElementById("encode-type").value;
              disp1.innerHTML =""; disp2.innerHTML =""; document.getElementById("dturl").value = "テキスト、image data URL を出力";
              // ファイルの配列から1つずつファイルを選択
              for(var i=0; i< files.length; i++){
                let f = files[i];
                // ファイル名とサイズを表示
                disp1.innerHTML += "ファイル名 :" + f.name + " ファイルの型:" + f.type + " サイズ:" + f.size / 1000 + " KB " + " URN:" + f.urn + "<br />";
                // ①FileReaderオブジェクトの生成
                let reader = new FileReader();
                // ②画像ファイルかテキストファイルかを判定
                if (!f.type.match('image.*') && !f.type.match('text.*') && !f.name.match(/csv$/m)) {
                  alert("画像ファイルとテキストファイル以外は表示できません。");
                  continue;
                }
                // ③エラー発生時の処理
                reader.onerror = function (evt) {
                  disp2.innerHTML = "読み取り時にエラーが発生しました。";
                }
                if (f.type.match('image.*')) {          // ④画像ファイルの場合の処理
                  reader.onload = function (evt) {
                    var dataUrl = reader.result;
                    document.getElementById("dturl").value = dataUrl;
                    let li = document.createElement('li');
                    let img = document.createElement('img');
                    img.src = evt.target.result;
                    li.appendChild(img);
                    li.innerHTML += "<br />";
                    disp2.appendChild(li);
                  }
                  // readAsDataURLメソッドでファイルの内容を取得
                  reader.readAsDataURL(f);
                }
                if(f.type.match('text.*') || f.name.match(/csv$/m)){ // テキストファイルの場合の処理
                  reader.onload = function (evt) {
                    // FileReaderが取得したテキストをそのままdivタグに出力
                    document.getElementById("dturl").value = reader.result;
                    disp2.innerHTML ="画像はここに表示します。"; 
                  }
                  reader.readAsText(f, encode_type);   // ファイルの内容を取得
                }
                event.preventDefault();
              }
              event.preventDefault();   // ⑥ブラウザ上でファイルを展開する挙動を抑止
            }; // onstart(event)  ---------------------------------
      
            function onDragOver(event){ 
              // ⑥ブラウザ上でファイルを展開する挙動を抑止
              event.preventDefault(); 
            }; // onDragOver(event)  -----------------------------
        </script>
      </body>
      </html>
  4. 参考サイト