初投稿です。
ちゃんと書けたかな?
概要
VBAェ...
Excel表をイマドキなJavaScriptで何とかする為の、WebApplicationの自分用テンプレートです。
経緯
事務作業でExcelをこねくり回す時、今更VBA...と思ったのがきっかけ。
"表は2次元配列にしてしまえば勝ち"
というパワープレイ思考をもとに、最近かじり始めたJavaScriptで、勉強も兼ねて書いてみる事にしました。
残念ながら、日本社会において絶対神Excelから逃れる事は不可能なので、せめてもの足掻き。
決め事
- カンマ区切CSV(UTF-8)のみ
- xlsx/csvの相互変換は手動で済ます
- 素のjsでやりきる
- 最新版Chromeで使う
色々と決め打ちが多いですが、その分コードはかなり簡素化されてると思います。
中身
JavaScript
hoge.js
// onchange: 読込ファイル名表示
function displayFileName(type){
if(document.getElementById(type).files[0]){
document.getElementById(type + "_name").innerHTML = document.getElementById(type).files[0].name;
}else{
document.getElementById(type + "_name").innerHTML = "";
}
}
// メインプロセス
async function executeProcess(){
const json = new Object();
const csv = new Array();
await readFile(document.getElementById("json_config").files[0])
.then((result)=>{
json.config = JSON.parse(result)
});
await readFile(document.getElementById("csv_table1").files[0])
.then((result)=>{
csv.table1 = parseCsv(result);
});
// 2次元配列化完了
// オマケでJSONも取り込んでます
// ココにお好みの処理を・・・
// 処理後
downloadFile(json.config, "json-config.csv");
downloadFile(csv.table1, "csv-table1.csv");
}
// ファイル読込
function readFile(file){
return new Promise((resolve, reject)=>{
const reader = new FileReader();
reader.onload = ()=>{
resolve(reader.result);
}
reader.onerror = (event)=>{
reject(event);
}
reader.readAsText(file);
});
}
// ダウンロード
function downloadFile(body, name){
// const bom = "\uEFBBBF";
const link = document.createElement("a");
link.href = URL.createObjectURL(new Blob([body], {type: "text/plain"}));
link.download = name;
link.click();
}
// CSV分解
function parseCsv(text){
const csv = new Array();
const line = text.split("\r\n");
for(let i = 0; i < line.length; i++){
csv[i] = line[i].split(',');
}
return csv;
}
// CSV結合
function joinCsv(csv){
let text = new String();
for(let i = 0; i < csv.length; i++){
text += csv[i].join(',');
text += "\r\n"
}
return text;
}
HTML
hoge.html
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title>タイトル</title>
</head>
<body>
<p><table>
<tr>
<td class="description">
テキストを入力
</td>
<td>
<input type="text" id="text_input" class="text text-search" placeholder="hoge"/>
</td>
</tr>
</table></p>
<p><table>
<tr>
<td>
<label class="hide button button-file">JSONを選択
<input type="file" id="json_config" accept=".json" onchange="displayFileName('json_config');"/>
</label>
<span id="json_config_name" class="description"/>
</td>
</tr>
<tr>
<td>
<label class="hide button button-file">CSVを選択
<input type="file" id="csv_table1" accept=".csv" onchange="displayFileName('csv_table1');"/>
</label>
<span id="csv_table1_name" class="description"/>
</td>
</tr>
</table></p>
<p><table>
<tr>
<td>
<label class="hide button button-execute">実行
<button onclick="executeProcess();"/>
</label>
</td>
</tr>
</table></p>
</body>
</html>
CSS
hoge.css
/***** フォーム隠蔽: input *****/
.hide > input {
display: none;
}
/***** フォーム隠蔽: button *****/
.hide > button {
display: none;
}
/***** テキスト: 説明文 *****/
.description {
user-select: none;
}
/***** テキストボックス: 共通 *****/
input.text {
cursor: text;
display: inline-block;
font-size: 14px;
height: 1.5em;
border:solid 1px #9f9f9f;
border-radius: 4px;
}
/***** テキストボックス - カラー: ホバー *****/
input.text-search:hover {
border:solid 1px #0fb920;
}
/***** ボタン: 共通 *****/
label.button {
user-select: none;
cursor: pointer;
display: inline-block;
padding: 0.1em 0.4em;
font-size: 14px;
text-decoration: none;
border-radius: 4px;
transition: 0.2s;
}
/***** ボタン - カラー: ファイル *****/
label.button-file {
color: #cf33dd;
border: solid 2px #cf33dd;
background: white;
}
label.button-file:active {
color: white;
background: #cf33dd;
}
/***** ボタン - カラー: 実行 *****/
label.button-execute {
color: #1c9ce6;
border: solid 2px #1c9ce6;
background: white;
}
label.button-execute:active {
color: white;
background: #1c9ce6;
}
/***** ボタン: トグル *****/
input.toggle {
position: absolute;
margin-left: -9999px;
}
input.toggle + label {
user-select: none;
display: block;
position: relative;
cursor: pointer;
outline: none;
user-select: none;
padding: 2px;
height: 18px;
width: 36px;
background-color: #9f9f9f;
border-radius: 36px;
transition: 0.2s;
}
input.toggle + label:before, input.toggle + label:after {
display: block;
position: absolute;
content: "";
}
input.toggle + label:before {
top: 2px;
left: 2px;
bottom: 2px;
right: 2px;
background-color: #ffffff;
border-radius: 36px;
transition: 0.2s;
}
input.toggle + label:after {
top: 4px;
left: 4px;
bottom: 4px;
width: 14px;
background-color: #9f9f9f;
border-radius: 36px;
transition: 0.2s;
}
input.toggle:checked + label {
background-color: #0fb920;
}
input.toggle:checked + label:after {
margin-left: 18px;
background-color: #0fb920;
}
振り返り
- FileReader便利
- Promiseの使い方は何となく掴んだ
- アローはとりあえず即時関数として使えば良いのかな?
ファイル編集は今までC#で行っていたのですが、簡単な処理ならjsでも全然行けますね。
コンパイルやUI作る手間がだいぶ省けるので、ちょっとしたオートメーション化に活用できそうです。
(VSCodeだけで完結可能なのは嬉しい)