空表の準備を不要にしました

「Blog Table ⭐ Import」の「ver.0.1」は、目的をとりあえず達成する事で終始したので、表生成は「Blog Table ⭐」に任せています。 しかし「Import」に表生成のコードを実装するのは簡単で、空表の用意は不要だと気付きました。

 

大幅にコード整理をした「ver.0.2」は、「CSV」データから表をダイレクトに生成する仕様になっています。

 

 

 

「Blog Table ⭐ Import」の操作 

 

●「Ctrl+F3」のショートカットを押すと、ツールが起動して下の表示が出ます。

 

 

 

●「CSV」データの表を作成する場所を「Ctrl+左Click」で指定します。

 

▪ 何かの表示物や記入のある行は避け、適当な「空行」を指定してください。

 

 

 

▪ 作成する位置に「青」バーができて、下の操作メニューが表示されます。

 

 

 

●「CSVファイルを読込む」を「左Click」して、PC上の「CSVファイル」を選択して読込みます。

 

▪ ファイル名が「.csv」(CSV形式)以外は、読み込む事ができません。

 

▪ CSVファイルのデータから、元表の構成「列・行」が受け継がれます。 この値は、右端の「CSVデータの構成」の枠に表示されます。

 

 

 

●「データを表に展開する」を「左Click」します。

 

 

 

元表と同じ「列・行」の構成で、編集枠内に表が生成されます。

 

▪ 表の生成を行うと、上部メニューはリセットされ、最初の状態に戻ります。

 

 

 

 生成した表のデザインについて

「Blog Table ⭐ Import」が生成する表は、「Blog Table ⭐」の「ver.4.0」以降が生成する表と同じ仕様です。

 

表幅の初期値は「600px」で、セル内で文字列が改行されたり、余白が不適切という場合が考えられます。 これは、「Blog Table ⭐」「Blog Table ⭐ Cell Design」を使って、修正する事を前提にしています。 データに合う幅にする指定にしても、結局は修正が必要になると考えました。

 

以下は「Import」が生成する表の指定です。 これは一般的な表の初期値として妥当と思われる標準値としています。

 

     
項目 設定内容 table要素のCSS指定
表の幅 600px width: 600px
記事上の配置 中央配置 margin: 0 auto
セル幅の指定 指定しない table-layout: auto
セル枠の重ね合わせ 重ね合わせる border-collapse: collapse
セルの間隔 なし border-spacing: 0px
表全体の外枠線 なし border: 0px solid #aaa
表内の基本フォント メイリオ 16px font: 16px Meiryo
英文禁則 単語の途中で改行 word-break: break-all
     
表全体の背景色 background-color: #ffffff
最上行・左端列の配色 background-color: #ffffff
     
セルの枠線 濃いグレー border: 1px solid #aaa
セル内の余白 メイリオに最適化 padding: 0.2em 0.6em 0
セルの高さ メイリオに最適化 height: 1.5em;

 

 

 

「Blog Table ⭐ Import」を利用するには

このツールは Chrome / Edge / Firefox版の拡張機能「Tampermonkey」上で動作します。 以下に、このツールの導入手順を簡単に説明します。

 

❶「Tampermonkey」を導入します

◎ 使用しているブラウザに拡張機能「Tampermonkey」を導入する事が必要です。

既に「Tampermonkey」を導入している場合は、この手順 ❶ は不要です。 

拡張機能の導入については、以下のページに簡単な説明があるので参照ください。

 

 

❷「Tampermonkey」にスクリプトを登録します

◎「Tampermonkey」の「」マークの「新規スクリプト」タブを開きます。

 

 

 

◎「新規スクリプト」には、最初からテンプレートが記入されています。 これは全て削除して、完全に空白の編集枠に 下のコードをコピー&ペーストします。

 

〔コピー方法〕 軽量シンプルなツール「PreBox Button   」を使うと

  コード枠内を「Ctrl+左Click」➔「Copy code 」を「左Click」

  の操作で、掲載コードのコピーが可能になります。

 

◎ 最後に「ファイル」メニューの「保存」を押すと、ツールが使用可能になります。

 

 

〔 Blog Table ⭐ Import 〕 ver. 0.2

 

// ==UserScript==
// @name          Blog Table ⭐ Import
// @namespace    http://tampermonkey.net/
// @version       0.2
// @description  CSVファイルのデータを表に展開する「Ctrl+F3」
// @author        Ameba Blog User
// @match        https://blog.ameba.jp/ucs/entry/srventry*
// @exclude      https://blog.ameba.jp/ucs/entry/srventrylist.do*
// @grant         none
// ==/UserScript==



let retry=0;
let interval=setInterval(wait_target, 100);
function wait_target(){
    retry++;
    if(retry>10){ // リトライ制限 10回 1sec
        clearInterval(interval); }
    let target=document.getElementById('cke_1_contents'); // 監視 target
    if(target){
        clearInterval(interval);
        main(); }}



function main(){
    let task=0; // 起動1・更新3・終了0

    let target=document.getElementById('cke_1_contents'); // 監視 target
    let monitor=new MutationObserver( catch_key );
    monitor.observe(target, {childList: true, attributes: true}); // ショートカット待受け開始

    catch_key();

    function catch_key(){
        if(document.querySelector('.cke_wysiwyg_frame') !=null){ //「通常表示」から実行開始
            let editor_iframe=document.querySelector('.cke_wysiwyg_frame');
            let iframe_doc=editor_iframe.contentWindow.document;

            iframe_doc.addEventListener('keydown', check_key);
            document.addEventListener('keydown', check_key);

            function check_key(event){
                if(event.keyCode==13 && iframe_doc.hasFocus()){
                    remove_mark(); } // 改行入力が連続マークとなるのを抑止

                let gate=-1;
                if(event.ctrlKey==true){
                    if(event.keyCode==114){
                        event.preventDefault(); gate=1; }
                    if(gate==1){
                        event.stopImmediatePropagation();
                        do_task(); }}}

            function do_task(){
                if(task==0){
                    task=1;
                    table_panel();
                    enhanced(); }
                else{
                    task=0;
                    remove_t_panel();
                    remove_mark(); }}}

        before_end();

    } // catch_key()



    function table_panel(){
        let panel=
            '<div id="csv_panel">'+

            '<span class="csv_button0 csv_sw">CSVファイルを読込む</span>'+
            '<span class="csv_button1 csv_sw">データを表に展開する</span>'+
            '<input class="csv_data_input" type="file">'+
            '<span class="csv_label">CSVデータの構成</span>'+
            '<div class="csv_wnc"><input id="csv_col" type="number" min="1"></div>'+
            '<div class="csv_wnr"><input id="csv_row" type="number" min="1"></div>'+

            '<div id="csv_first">'+
            '<span id="csv_help">?</span>'+
            '<div class="csv_help1">'+
            '「table表」を作成する場所を<b>「Ctrl+左Click」</b>で指定してください</div>'+
            '</div>'+

            '<style>'+
            '#csv_panel { position: fixed; top: 15px; left: calc(50% - 490px); width: 954px; '+
            'height: 27px; font-size: 14px; padding: 6px 12px; overflow: hidden; '+
            'border: 1px solid #ccc; border-radius: 4px; background: #eff5f6; z-index: 10; }'+
            '#csv_panel * { user-select: none; }'+
            '#csv_panel .csv_sw { position: relative; margin: 0 20px; padding: 3px 10px 1px; '+
            'top: 0; box-sizing: border-box; border: thin solid #aaa; background: #fff; }'+
            '#csv_panel .csv_data_input { display: none; }'+
            '#csv_panel input { position: relative; margin-right: 10px; padding: 2px 2px 0 0; '+
            'height: 27px; box-sizing: border-box; border: thin solid #aaa; }'+

            '.csv_label { margin: 0 3px 0 0; }'+
            '.csv_wnc, .csv_wnr { position: relative; display: inline-block; margin: 0 5px; }'+
            '.csv_wnc::after { content: "列"; }'+
            '.csv_wnr::after { content: "行"; }'+
            '.csv_wnc::after, .csv_wnr::after { position: absolute; top: 2px; right: 12px; '+
            'padding: 3px 0 0; width: 17px; background: #fff; }'+
            '.csv_wnc:hover::after, .csv_wnr:hover::after { content: ""; }'+
            '#csv_col, #csv_row { width: 50px; text-align: center; }'+

            '#csv_first { position: absolute; top: 0; left: 0; color: #fff; background: #2196f3; '+
            'width: 100%; padding: 10px 0; font-size: 16px; text-align: center; }'+
            '#csv_help { position: absolute; top: 11px; right: 25px; padding: 2px 1px 0; '+
            'line-height: 16px; font-weight: bold; border-radius: 30px; '+
            'color: #2196f3; background: #fff; cursor: pointer; }'+
            '.csv_help1 { text-align: left; margin-left: 60px; }'+
            '</style>'+
            '</div>';

        if(!document.querySelector('#csv_panel')){
            document.body.insertAdjacentHTML('beforeend', panel); }

    } // table_panel()



    function enhanced(){
        let target_r=document.getElementById('cke_1_contents'); // 監視 target
        let monitor_r=new MutationObserver(select);
        monitor_r.observe(target_r, {childList: true}); // ショートカット待受け開始

        select();

        function select(){
            if(document.querySelector('.cke_wysiwyg_frame') !=null){ //「通常表示」から実行開始
                remove_mark; // Html編集後のリセット
                show_first(1);
                let editor_iframe=document.querySelector('.cke_wysiwyg_frame');
                let iframe_doc=editor_iframe.contentWindow.document;
                if(iframe_doc){
                    let style_csv_if=
                        '<style id="style_csv_if">'+
                        '.csv_active { box-shadow: #fff -4px 0px, #2196f3 -8px 0px !important; }'+
                        '</style>';
                    if(!iframe_doc.head.querySelector('#style_csv_if')){
                        iframe_doc.head.insertAdjacentHTML('beforeend', style_csv_if); }

                    let editor=iframe_doc.querySelector('.cke_editable');
                    if(editor){
                        editor.onclick=function(event){
                            event.stopImmediatePropagation();
                            if(event.ctrlKey){
                                remove_mark();
                                if(task==1){
                                    let elm=iframe_doc.elementFromPoint(event.clientX, event.clientY);
                                    if(elm.tagName=='P' || elm.tagName=='DIV'){
                                        elm.classList.add('csv_active');
                                        show_first(0);
                                        edit_table(task); } //「表作成」
                                }}}}}}} // select()

    } // enhanced()



    function edit_table(task){
        let result; // 最終的な二次元配列

        let editor_iframe=document.querySelector('.cke_wysiwyg_frame');
        let iframe_doc=editor_iframe.contentWindow.document;
        let csv_col=document.querySelector('#csv_col');
        let csv_row=document.querySelector('#csv_row');
        let csv_button1=document.querySelector('.csv_button1');
        let thead_style='padding-top: 0; height: 0; border: none; background: none;';

        if(task==1){
            csv_reader();

            csv_button1.onclick=function(event){
                event.preventDefault();
                if(result){
                    createTable(result); }
                else{
                    alert("CSVファイルを読み込んでください"); }}
        } // if(task==1)



        function csv_reader(){
            let csv_button0=document.querySelector('.csv_button0');
            let csv_data_input=document.querySelector('.csv_data_input');
            disp_result(result);

            csv_button0.onclick=function(){
                csv_data_input.click(); }

            csv_data_input.addEventListener('click', (event)=>{
                event.target.value=''; }); // 同ファイルを2回以上読める様にする

            csv_data_input.addEventListener('change', function(){
                if(!(csv_data_input.value)){ return; } // ファイルが選択されない場合
                let file_list=csv_data_input.files;
                if(!file_list){ return; }// ファイルリストが選択されない場合
                let file=file_list[0];
                if(!file){ return; }// ファイルが無い場合
                else{
                    if(!file.name.endsWith('.csv')){
                        alert("「CSV形式」のファイルのみに対応します"); }
                    else{
                        let file_reader=new FileReader();
                        file_reader.readAsText(file);
                        file_reader.onload=function(){
                            let csv_data=file_reader.result;
                            convert_array(csv_data);
                            disp_result(result); }}} // CSVデータを読込み
            });


            function convert_array(str){
                result=[];
                let tmp=str.split('\n'); // 改行を区切り文字として行の配列を生成
                for(let i=0;i<tmp.length;++i){ // 行からカンマ区切りの文字列から配列を生成
                    result[i]=tmp[i].split(','); }}


            function disp_result(result){
                if(result){
                    csv_row.value=result.length;
                    csv_col.value=result[0].length; }
                else{
                    csv_row.value='';
                    csv_col.value=''; }}

        } // csv_reader()



        function createTable(result){
            let n_table=iframe_doc.createElement("table");
            let rows=[];
            for(let i=0; i<result.length; i++){
                rows.push(n_table.insertRow(-1)); // 行の追加
                for(let j=0; j<result[0].length; j++){
                    let cell=rows[i].insertCell(-1);
                    cell.textContent=result[i][j]; }} // データの書込み

            let th_tr=n_table.createTHead().insertRow();
            th_tr.style.background='none';
            th_tr.style.lineHeight='0';
            for(let j=0; j<result[0].length; j++){
                let add_td=iframe_doc.createElement('td');
                add_td.setAttribute('style', thead_style);
                th_tr.appendChild(add_td); } // Headerの追加

            let table_id=new_table_id();
            n_table.setAttribute('id', table_id);

            let scroll_container=iframe_doc.createElement('div');
            scroll_container.setAttribute('style', 'overflow-x: auto');

            let selection=iframe_doc.getSelection();
            let range=selection.getRangeAt(0);
            let ac_node=selection.anchorNode;

            ac_node.parentNode.insertBefore(scroll_container, ac_node);
            scroll_container.appendChild(n_table);

            let cn_table=iframe_doc.querySelector('#'+ table_id);
            let t_style='<style class="'+ table_id +'">'+ set_css(table_id) +'</style>';
            if(!iframe_doc.querySelector('.'+table_id)){
                cn_table.insertAdjacentHTML('beforeBegin', t_style); }


            remove_mark(); // 選択表示を整形
            show_first(1);
            cn_table.parentNode.classList.add('csv_active');

        } // createTable()

    } // edit_table()



    function set_css(t_id){
        let css=
            '#'+ t_id +' { '+
            'width: 600px; '+
            'margin: 0 auto; '+
            'table-layout: auto; '+
            'border-collapse: collapse; '+
            'border-spacing: 0px; '+
            'border: 0px solid #aaa; '+
            'font: 16px Meiryo; '+
            'word-break: break-all; } '+
            '#'+ t_id +' tbody { background-color: #ffffff; } '+
            '#'+ t_id +' tr:first-child { background-color: #ffffff; } '+
            '#'+ t_id +' tr:not(:first-child) td:first-child { background-color: #ffffff; } '+
            '#'+ t_id +' td { border: 1px solid #aaa; padding: 0.2em 0.6em 0; height: 1.5em; }';
        return css; }



    function new_table_id(){ // 複数tableを生成時に異なるidを付ける
        if(document.querySelector('.cke_wysiwyg_frame') !=null){
            let editor_iframe=document.querySelector('.cke_wysiwyg_frame');
            let iframe_doc=editor_iframe.contentWindow.document;
            for(let k=0; k<100; k++){
                let table_id='ambt'+k;
                if(iframe_doc.getElementById(table_id)==null){
                    return table_id; }}}}



    function remove_t_panel(){
        document.querySelector('#csv_panel').remove(); }



    function remove_mark(){
        if(document.querySelector('.cke_wysiwyg_frame') !=null){ //「通常表示」から実行開始
            let editor_iframe=document.querySelector('.cke_wysiwyg_frame');
            let iframe_doc=editor_iframe.contentWindow.document;

            let item=iframe_doc.querySelectorAll('.csv_active');
            for(let k=0; k<item.length; k++){
                item[k].classList.remove('csv_active'); }}}



    function show_first(n){
        let first=document.querySelector('#csv_first');
        let csv_help1=document.querySelector('.csv_help1');
        if(first){
            if(n==0){
                first.style.display='none'; }
            else{
                first.style.display='block';
                csv_help1.style.display='block'; }}

        let csv_help=document.querySelector('#csv_help');
        if(csv_help){
            csv_help.onclick=function(){
                let url='https://ameblo.jp/personwritep/entry-12842640111.html';
                window.open(url, target="_blank"); }}}



    function before_end(){
        let submitButton=document.querySelectorAll('.js-submitButton');
        submitButton[0].addEventListener('mousedown', all_clear, false);
        submitButton[1].addEventListener('mousedown', all_clear, false);

        function all_clear(){
            let editor_iframe=document.querySelector('.cke_wysiwyg_frame');
            if(!editor_iframe){ //「HTML表示」編集画面の場合
                alert("⛔ Blog Table が処理を終了していません\n\n"+
                      "   通常表示画面に戻り 編集を終了してください");
                event.stopImmediatePropagation();
                event.preventDefault(); }
            if(editor_iframe){ //「通常表示」編集画面の場合
                remove_mark(); } // table編集のマークを削除
        }} // before_end(

} // main()



 

 

 

「Blog Table ⭐ Import」最新版について 

旧いバージョンの JavaScriptツールは、アメーバのページ構成の変更で動作しない場合があり、導入する場合は最新バージョンをお勧めします。

 

●「Blog Table ⭐ Import」の最新バージョンへのリンクは、以下のページのリンクリストから探せます。