エクセルなどで使われるCSVファイルをブラウザで表示して見るツール
デモ:http://pie.karou.jp/zf.html
サンプルとして郵便番号と住所の書いてあるcsvファイルが
ちょうどよいので”郵便番号 csv”で検索してダウンロードする
全国のデータ KEN_ALL_ROME.CSV 10.5MB
"0640941","北海道","札幌市 中央区","旭ケ丘","HOKKAIDO","SAPPORO SHI CHUO KU","ASAHIGAOKA"
1行がこんな感じで 12万行
-
csvファイルをinput fileで選択する
-
csvファイルはshiftJISが多くて文字化けするのでライブラリencoding.jsを使って対策する
-
12万行も表示できないので30行だけ表示する(ファイルを開くのに5秒くらい)
-
and検索をするために
Array.filter(function(v){ return v.join("").indexOf("東京")>-1); }).filter(function(v){ return v.join("").indexOf("新宿")>-1); });
これでデータ抽出すると1秒以下で697件見つけて表示される
<!doctype html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title>csvファイル検索ツール</title>
<style>
h1{font-size: 16px;display:inline;}
p{display:inline;}
input[type=number]{width:80px;}
</style>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.4/jquery.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.0.7/vue.min.js"></script>
<script src="folder3/encoding.min.js"></script>
</head>
<body>
<div id="app">
<h1>csvファイル 検索ツール(簡易オートフィルタ)</h1>
<input type="file" @change="fileChange">
<p>列幅調整はセル内でBackspace,←,→キー</p>
<hr>
検索文字:<input type="text" id="filter1">and<input type="text" id="filter2">
行:<input type="number" id="maxGyou" step="10" min="10" value="30">
<input type="button" @click="filterFn" value="抽出">
ページ:
<select v-model="index">
<option v-for="n in pageLength" v-bind:value="n">{{n}} </option>
</select> /{{ (pageLength==100)?"over": pageLength}}
<input type="button" value="←" @click="plus(-1)">
<input type="button" value="→" @click="plus(1)">
一致数:{{ matchNum }}
<hr>
<div v-for="n in gyouNum" style="white-space: nowrap;">
<input type="text" v-for="(v,i) in csvData[(index-1)*gyouNum + (n-1)]" :value="v"
@keyup.left="css(i,-25)" @keyup.right="css(i,50)" @keyup.delete="css(i,-1000)"
:style="{color : (colorArr[i] || 'black'), width: (widthArr[i] || 150) + 'px' }" readonly="readonly">
</div>
</div>
<script>
var vm = new Vue({
el: '#app',
data: {
index: 1,
gyouNum: 30,
fileData: [],
csvData: [],
widthArr: [],
colorArr: [],
matchNum: 0,
},
computed: {
pageLength: function() {
return Math.ceil(this.csvData.length / this.gyouNum);
},
},
methods: {
fileChange: function(e) {
$("#filter1,#filter2").val("");
var file = e.target.files[0];
var reader = new FileReader();
reader.onload = function(e) {
var codes = new Uint8Array(e.target.result);
var encoding = Encoding.detect(codes);
var unicodeString = Encoding.convert(codes, {
to: 'unicode',
from: encoding,
type: 'string'
});
var arr = unicodeString.trim().replace(/\"/g, "").split("\n");
vm.fileData = arr.map(v => v.split(","));
vm.filterFn();
};
reader.readAsArrayBuffer(file);
},
plus: function(x) {
if (this.index + x <= 0 || this.index + x > this.pageLength) return;
this.index += x;
},
css: function(x, y) {
this.widthArr[x] = this.widthArr[x] || 150;
this.widthArr[x] += y;
if (this.widthArr[x] < 15) {
this.widthArr[x] = 10;
this.colorArr[x] = "white";
} else {
this.colorArr[x] = "black";
}
this.colorArr.push();
this.widthArr.push();
},
filterFn: function() {
this.index = 1;
this.gyouNum = $("#maxGyou").val() - 0;
var filter1 = $("#filter1").val().toLowerCase();
var filter2 = $("#filter2").val().toLowerCase();
var arr = this.fileData.filter(function(v) {
return v.join("").toLowerCase().indexOf(filter1) > -1;
}).filter(function(v, i) {
return v.join("").toLowerCase().indexOf(filter2) > -1;
});
this.matchNum = arr.length;
this.csvData = arr.filter(function(v, i) {
return i < vm.gyouNum * 100;
});
},
},
});
</script>
</body>
</html>
vue.jsで書いたオセロ
https://jsfiddle.net/af9b4bq3/
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.0.7/vue.min.js"></script>
<p>オセロ</p>
<div id="app">
<p>白:{{ w }}, 黒:{{ b }}</p>
<p>{{ ["白","黒"][wb] }}の手番</p>
<div v-for="i in 8" class="container">
<div v-for="j in 8" class="waku">
<div :class="{ 'white': xy[i][j]==0, 'black': xy[i][j]==1 }" @click="oku(i, j)"></div>
</div>
</div>
<p>
<button @click="pass">pass</button>
</p>
</div>
p {
text-align: center;
}
div {
min-width: 35px;
min-height: 35px;
}
.container {
display: flex;
justify-content: center;
}
.waku {
border: 1px solid black;
background-color: green;
}
.white {
border-radius: 35px;
background-color: white;
}
.black {
border-radius: 35px;
background-color: black;
}
var vm = new Vue({
el: '#app',
data: {
wb: 1,
xy: [
[3, 3, 3, 3, 3, 3, 3, 3, 3, 3],
[3, 2, 2, 2, 2, 2, 2, 2, 2, 3],
[3, 2, 2, 2, 2, 2, 2, 2, 2, 3],
[3, 2, 2, 2, 2, 2, 2, 2, 2, 3],
[3, 2, 2, 2, 0, 1, 2, 2, 2, 3],
[3, 2, 2, 2, 1, 0, 2, 2, 2, 3],
[3, 2, 2, 2, 2, 2, 2, 2, 2, 3],
[3, 2, 2, 2, 2, 2, 2, 2, 2, 3],
[3, 2, 2, 2, 2, 2, 2, 2, 2, 3],
[3, 3, 3, 3, 3, 3, 3, 3, 3, 3],
],
},
computed: {
w: function() {
return (this.xy.join('').match(/0/g) || []).length;
},
b: function() {
return (this.xy.join('').match(/1/g) || []).length;
},
},
methods: {
oku: function(x, y) {
if (this.xy[x][y] != 2) return;
var flag = false;
for (var dx = -1; dx <= 1; dx++) {
for (var dy = -1; dy <= 1; dy++) {
if (dx == 0 && dy == 0) continue;
var k = 1;
while (this.xy[x + k * dx][y + k * dy] <= 1) {
if (this.xy[x + k * dx][y + k * dy] == this.wb) {
k = 1;
while (this.xy[x + k * dx][y + k * dy] == 1 - this.wb) {
flag = true;
this.xy[x + k * dx][y + k * dy] = this.wb;
k++;
}
break;
}
k++;
}
}
}
if (flag == false) return;
this.xy[x][y] = this.wb;
this.wb = 1 - this.wb;
this.xy.push();
},
pass: function() {
this.wb = 1 - this.wb;
},
},
});