Export csv file of displayed month.
// ==UserScript==
// @name CSV Download
// @namespace https://github.com/Yuto-34
// @license Yuto-34
// @version 1.0.1
// @description Export csv file of displayed month.
// @author Yuto
// @match https://moneyforward.com/cf
// @icon https://www.google.com/s2/favicons?sz=64&domain=moneyforward.com
// @grant none
// ==/UserScript==
function handleDownload() {
// セルの中の改行を消す為の正規表現
const removeN = /\n.*/g;
const removeComma = /,/g;
const regex = 'icon-check icon-large';
// 文字コードをBOM付きUTF-8に指定
var bom = new Uint8Array([0xEF, 0xBB, 0xBF]);
// データが入っている要素を取得
var table = document.getElementById('cf-detail-table');
const yearSlash = document.getElementsByTagName("h2")[1].innerText.slice(0,5);
// ここに文字データとして値を格納していく
var data_csv="計算対象, 日付, 内容, 金額, 保有金融機関, 大項目, 中項目, メモ, 振替\n";
for(var i = 1; i < table.rows.length; i++){
var isTransfar
// 振替チェック
if(table.rows[i].cells[3].innerText.indexOf('\n') != -1) {
isTransfar = true;
} else {
isTransfar = false;
}
for(var j = 0; j < table.rows[i].cells.length - 1; j++){
// data_cell の用意
var data_cell = table.rows[i].cells[j];
// HTML中の表のセル値をdata_csvに格納
if(j == 0) {
if((data_cell.innerHTML + '').indexOf(regex) != -1) {
data_csv += 'TRUE';
} else {
data_csv += 'FALSE';
}
} else if(j == 1) {
var dataTemp = (yearSlash + data_cell.innerText.replace(removeN, "").replace(removeComma, ""));
data_csv += dataTemp.slice(0,10);
} else if(j == 8 && isTransfar) {
data_csv += 'TRUE';
} else {
data_csv += data_cell.innerText.replace(removeN, "").replace(removeComma, "");
}
// 行終わりに改行コードを追加
if(j == table.rows[i].cells.length - 2) data_csv += "\n";
// セル値の区切り文字として,を追加
else data_csv += ",";
}
}
// ダウンロードボタンの作成
var fileName = document.getElementsByTagName('h2')[1].innerText.slice(2,7).replace('/', '_');
fileName += '.csv';
var parentDiv = document.getElementsByClassName('pull-right mf-mb-medium')[0];
if(document.getElementById('download') != null) {
parentDiv.removeChild(download);
}
var childA = document.getElementsByClassName('btn cf-new-btn btn-warning')[0];
var blob = new Blob([ bom, data_csv ], { "type" : "text/csv" });
var newElement = document.createElement('a');
var newContent = document.createTextNode('Download');
newElement.appendChild(newContent);
newElement.setAttribute('id', 'download');
newElement.setAttribute('href', '#');
newElement.setAttribute('style', 'padding:5px 20px; width: 100px; height: 32px; line-height: 34px; margin-right: 10px;');
newElement.className = 'btn cf-new-btn btn-warning';
newElement.href = window.URL.createObjectURL(blob);
newElement.download = fileName;
parentDiv.insertBefore(newElement, childA);
// delete data_csv;//data_csvオブジェクトはもういらないので消去してメモリを開放
}
(function() {
'use strict';
// Your code here...
handleDownload();
var observer = new MutationObserver(function(){
// DOMの変化が起こった時の処理
console.log('DOMが変化しました');
var parentDiv = document.getElementsByClassName('pull-right mf-mb-medium')[0];
if(document.getElementById('download') != null) {
parentDiv.removeChild(download);
}
// handleDownloadを実行
console.log('reload');
handleDownload();
console.log('reloaded');
if(document.getElementsByTagName('h2')[0].innerText.indexOf('Loading') != -1) {
if(document.getElementById('download') != null) {
parentDiv.removeChild(download);
}
}
}, false);
// 監視対象の要素オブジェクト
const elem = document.getElementsByClassName('date_range transaction-in-out-header')[0];
// 監視時のオプション
const config = {
attributes: true,
childList: true,
characterData: true,
subtree: true,
};
// 要素の変化監視をスタート
observer.observe(elem, config);
})();