ブラウザで稼働しJavaScript(js)プログラムからtextファイルを読み込み表示するプログラムの記録。
名簿などはエクセルで管理している場合も多く、エクセルでhtml形式にして保存することも出来るが、出来上がったhtmlは、なにやら複雑でよくわからないjavascriptが組み込まれていてあまり使う気にはならない。他にpdfにも変換出来るがこれも一長一短で、自分でカストマイズできるように作れないものかと思っていた。
前versionではXMLHttpRequestを使用したが、今回は同じくHTTPリクエストを発行するFetch APIを使ってAjax通信を行い、サーバーから取得したデータを表示する。
* Fetch : 人や物を取って[連れて]くること
* API : Application Programming Interfaceの略語で、「機能を公開しているソフトウェア」と「その機能を使いたいソフトウェア」をつなげる窓口のようなものを指す
* Ajax : AsynchronousとJavaScriptに、XMLを組み合わせて作られた造語
Fetch API の概要 : Fetch API は、JavaScript を使ってサーバーに HTTP リクエストを送信できるインターフェースで、指定した URL からリソース(データ)を取得することができる。
XMLHttpRequest と同様の機能を持つが、よりシンプルで柔軟な API である。IE や一部のブラウザは対応していないが、主要なモダンブラウザで利用できる。
リソース(データ)を取得するためのリクエストの送信は、fetch() メソッドを使う
fetch() メソッドにリソースの URL を指定して呼び出すとリクエストが発行され、Response オブジェクトを結果に持つ Promise オブジェクトが返される。
Promise は非同期処理を扱うための仕組みで、Promise オブジェクトの then() メソッドに処理(コールバック関数)を記述することができる
webアプリケーションの疑似開発環境を作る。
導入はこちらから XAMPP
使い方 : XAMPPを導入したフォルダーのhtdocsフォルダーにtestフォルダーを作り html , css , javascriptプログラムを移行する。
XAMPPを起動し、メニューからApacheをstartしておき、ブラウザでhttp://localhost/test/readtxt.html と入力するとwebアプリケーションの疑似開発環境が使える。
dummy.csv
名前,名前(ひらがな),年齢 ,生年月日,性別 ,メールアドレス ,電話番号 ,郵便番号 ,住所
北風 聡美,きたかぜ さとみ,38,1984年2月18日,女,satomikitakaze@example.net,070-5981-7058,134-5048,東京都品川区南品川2-5-9
松沢 宏明,まつざわ ひろあき,76,1946年6月2日,男,matsuzawa_62@example.jp,050-8710-5333,062-6726,北海道札幌市北区北二十四条西4丁目2番5号
横瀬 誠,よこせ まこと,65,1956年11月27日,男,yokose_1127@example.org,090-8911-4466,187-0440,東京都港区虎ノ門3-5-6
丸山 毅,まるやま たかし,48,1974年6月13日,その他・不明,maruyama613@example.co.jp,050-2719-5034,802-3021,福岡県福岡市早良区干隈4丁目3番9号
................................500ライン.......................................
実際のサンプルコードを記述しておく
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8" />
<title>text file read</title>
<style>
<!--
body {background:url("back_g1.gif");background-color:ivory;}
h1 {color:green;text-align:center;margin:0px;}
h5 {float:right;margin-right:50px;}
#txt {width:90%;margin:10px auto;font-size:14px;text-shadow:0px 0px 1px black;font-family:"Courier New", Consolas, monospace;}
#txt span {color:blue;}
#modoru a:link , #modoru a:visited {
width:3%;
display:block;
text-decoration:none;
border:2px ridge ivory;
color:ivory;
text-shadow:1px 1px 0px black;
border-radius:5px;
}
#return a:link , a:visited {
border:2px ridge gold;
}
#modoru a:hover {
color:red;
background-color:lime;
}
/*------------------ mobile responsive -----------------------------*/
@media screen and (max-width: 480px) {
h1 {
width:80%;
font-size:1.2rem;
letter-spacing:0px;
}
#modoru a:link , #modoru a:visited {
width:10%;
display:block;
text-decoration:none;
border:2px ridge ivory;
color:ivory;
text-shadow:1px 1px 0px black;
border-radius:5px;
}
}
-->
</style>
<script src="js/readtxt.js"></script>
</head>
<body>
<div id="modoru"><a href="#" onClick="history.back(); return false;">戻る</a></div>
<h1><span id="title">ABC-XYZ会名簿</span></h1>
<h5>(テスト用架空データ)</h5>
<div style="clear:both;"></div>
<pre>
<div id="txt"></div>
</pre>
</div>
</body>
</html>
// ------------------------------------------------ text file read on 非同期
// --------------------------------------------------------------------------
var txt1 = txt2 = "";
var t0 = t1 = t2 = t3 = t4 = t5 = t6 = t7 = t8 = "" ;
var n = 1 ; // line number
fetch("data/dummy.csv")
.then(function(response){ // response
if (!response.ok) {return Promise.reject(new Error("error"));} // error
return response.text(); // ok string utf-8
})
.then(function(text){
display(text) ;
})
.catch(function(error){console.error("fetch error", error); // error処理
}); // ここで セミコロン(;)
// ---------------------- data handling
function display (text) {
var txt_list = text.split('\n'); // 改行で分ける
for ( i = 0 ; i < txt_list.length-1 ; i++) {
var txt_list1 = txt_list[i].split(',') ; // split by separater
if ( i == 0 ) { // header line only
for ( j = 0 ; j < txt_list1.length ; j++) {
if (j == 0 ) { t0 = txt_list1[j].padEnd(13,' ')} // 名前
else if ( j == 1 ) { t1 = txt_list1[j].padEnd(10 ,' ')} // ひらがな
else if ( j == 2 ) { t2 = txt_list1[j].padEnd(5,' ')} // 年齢
else if ( j == 3 ) { t3 = txt_list1[j].padEnd(12 ,' ')} // 生年月日
else if ( j == 4 ) { t4 = txt_list1[j].padEnd(9 ,' ')} // 性別
else if ( j == 5 ) { t5 = txt_list1[j].padEnd(25 ,' ')} // メールアドレス
else if ( j == 6 ) { t6 = txt_list1[j].padEnd(11 ,' ')} // 電話番号
else if ( j == 7 ) { t7 = txt_list1[j].padEnd(7 ,' ')} // 郵便番号
else if ( j == 8 ) { t8 = txt_list1[j].padEnd(10 ,' ')} // 住所
txt1 = '<b>' + 'No. ' + t0 + t1 + t2 + t3 + t4 + t5 + t6 + t7 + t8 + '</b>' ;
}
}
if ( i > 0 ) {
for ( j = 0 ; j < txt_list1.length ; j++) {
if (j == 0 ) { t0 = txt_list1[j].padEnd(9,' ')} // 名前
else if ( j == 1 ) { t1 = txt_list1[j].padEnd(10 ,' ')} // ひらがな
else if ( j == 2 ) { t2 = txt_list1[j].padEnd(5 ,' ')} // 年齢
else if ( j == 3 ) { t3 = txt_list1[j].padEnd(12 ,' ') + ' '} // 生年月日
else if ( j == 4 ) { t4 = txt_list1[j].padEnd(8 ,' ')} // 性別
else if ( j == 5 ) { t5 = '<span>' + txt_list1[j].padEnd(30 ,' ') + '</span>'} // メールアドレス
else if ( j == 6 ) { t6 = txt_list1[j].padEnd(14 ,' ')} // 電話番号
else if ( j == 7 ) { t7 = txt_list1[j].padEnd(9 ,' ')} // 郵便番号
else if ( j == 8 ) { t8 = txt_list1[j].padEnd(10 ,' ')} // 住所
txt1 = String(n).padStart(3,'0') + '. ' + t0 + t1 + t2 + t3 + t4 + t5 + t6 + t7 + t8 ;
}; // for end j
n += 1 ;
}; // if i >0
txt2 = txt2 + txt1 + '<br>'
document.getElementById("txt").innerHTML = txt2 ;
}; // for ( i = 0 ; i < txt_list.length-1 ; i++) {
}; // function handle end
// ---- end
fetch部分の解説
fetch("data/dummy.csv")
.then(function(response){ // response
if (!response.ok) {return Promise.reject(new Error("error"));} // error
return response.text(); // ok string utf-8
})
.then(function(text){
display(text) ;
})
.catch(function(error){console.error("fetch error", error); // error処理
}); // ここで セミコロン(;)
少々面倒だったのは、各項目を縦に揃えたかったこと。特に生年月日は半角数字と漢字が混在しており、数字の桁数の異なる場合がある。そのため後続の列が縦に揃わない。
例)
生年月日 性別
1984年2月18日 男
1956年11月27日 女
文字列の末尾に指定した文字列を繰り返し追加するpadEnd(12,' ')メソッドを使うが、htmlでは半角スペースを複数並べると一個しか使われない。
htmlタグの<pre> </pre>で挟むとこの制限はなくなるのに気がついた。但し等幅フォントをhtmlで指定する。