CSV Download

Export csv file of displayed month.

您需要先安裝使用者腳本管理器擴展,如 TampermonkeyGreasemonkeyViolentmonkey 之後才能安裝該腳本。

You will need to install an extension such as Tampermonkey to install this script.

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyViolentmonkey 後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyUserscripts 後才能安裝該腳本。

你需要先安裝一款使用者腳本管理器擴展,比如 Tampermonkey,才能安裝此腳本

您需要先安裝使用者腳本管理器擴充功能後才能安裝該腳本。

(我已經安裝了使用者腳本管理器,讓我安裝!)

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

(我已經安裝了使用者樣式管理器,讓我安裝!)

// ==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);
})();