【Googleスプレッドシート、GAS】選択した範囲をHTMLのtableタグとしてテキスト出力する

Code

はじまり

リサちゃん
リサちゃん

HTMLって作るのめんどいよなあ〜。

スプレッドシートとかで編集したのをそのままHTMLで表記できれば楽なのに。

135ml
135ml

じゃあ、今行ったことをそのまま実現できてしまうツールを紹介しましょう。

リサちゃん
リサちゃん

おお・・・! ぜひ、授けたまえ!

今回のソース

以下が、今回のソースになります。

/**
 * @param {string[]} values
 * @param {string} textReplacingIfBlank
 * @return {string}
*/
function getHtmlByValues(values, textReplacingIfBlank="💩"){
  let prefix = "<table>";
  let suffix = "</table>";
  let html = `${prefix}\n`;
  let tmp_tr = "";
  let isTh = false;
  for(let i = 0; i < values.length; i++){
    isTh = false;
    if(i === 0){
      isTh = true;
    }
    tmp_tr = getTrByRow(values[i], isTh, textReplacingIfBlank);
    html += `${tmp_tr}\n`;
  }
  html += suffix;
  return html;
}

/**
 * @param {string[]} row
 * @param {boolean} isTh
 * @param {string} textReplacingIfBlank
 * @return {string}
*/
function getTrByRow(row, isTh, textReplacingIfBlank="💩"){
  let element;
  let tr = "";
  let tagTd = "td";
  if(isTh){
    tagTd = "th";
    textReplacingIfBlank = "";
  }
  const tagTr = "tr";
  for(let i = 0; i< row.length; i++){
    element = closeByTag(tagTd, row[i], textReplacingIfBlank);
    tr += element;
  }
  tr = closeByTag(tagTr, tr, "");
  return tr;
}

/**
 * @param {string} tag without < and >
 * @param {string} innerText
 * @param {string} textReplacingIfBlank
 * @return {string}
*/
function closeByTag(tag, innerText, textReplacingIfBlank="💩"){
  if(tag[0] === "<"){
    throw Error("Initial of tag mustn't be \"<\".");
  }
  if(tag[tag.length - 1] === ">"){
    throw Error("End of tag mustn't be \">\".");
  }

  let initialOfTag = "<";
  let endOfTag = ">";
  let formerTag = `${initialOfTag}${tag}${endOfTag}`;
  let latterTag = `${initialOfTag}/${tag}${endOfTag}`;
  let displayText = innerText;
  if(displayText === ""){
    displayText = textReplacingIfBlank;
  }
  let element = `${formerTag}${displayText}${latterTag}`;
  return element;
}

function getValuesBySelectedArea(){
  const ss = SpreadsheetApp.getActive().getSheetByName(sheetName1st);
  const activeValues = ss.getActiveRange().getValues();
  console.log(activeValues);
  return activeValues;
}

function main(){
  const values = getValuesBySelectedArea();
  const html = getHtmlByValues(values, "");
  console.log(html);
}

テストコード

以下が、僕が作ったGoogle Apps Script用のテストツール「TestGAS」で使えるテストコードになります。

// let tester = new TestGAS.TestGasExecutor();
let tester = TestGAS.createExecutor();

class Test_main{
  test_getHtmlByValues_1_1(){
    const values = [ [ '', 'Python', 'GAS', 'GitHub', 'JavaScript' ]
                    , [ '', '', '', '', '' ]
                  ];
    const textReplacingIfBlank = "";
    const actual = getHtmlByValues(values, textReplacingIfBlank);
    const expected = `<table>
<tr><th></th><th>Python</th><th>GAS</th><th>GitHub</th><th>JavaScript</th></tr>
<tr><td></td><td></td><td></td><td></td><td></td></tr>
</table>`;
    tester.assertEquals(actual, expected);
  }

  test_getHtmlByValues_1_2(){
    const values = [ [ '', 'Python', 'GAS', 'GitHub', 'JavaScript' ] ];
    const textReplacingIfBlank = "";
    const actual = getHtmlByValues(values, textReplacingIfBlank);
    const expected = `<table>
<tr><th></th><th>Python</th><th>GAS</th><th>GitHub</th><th>JavaScript</th></tr>
</table>`;
    tester.assertEquals(actual, expected);
  }

  test_getHtmlByValues_1_3(){
    const values = [ [ '' ] ];
    const textReplacingIfBlank = "";
    const actual = getHtmlByValues(values, textReplacingIfBlank);
    const expected = `<table>
<tr><th></th></tr>
</table>`;
    tester.assertEquals(actual, expected);
  }

  test_getHtmlByValues_2_1(){
    const values = [ [ '', 'Python', 'GAS', 'GitHub', 'JavaScript' ]
                    , [ '', '', '', '', '' ]
                  ];
    const actual = getHtmlByValues(values);
    const expected = `<table>
<tr><th></th><th>Python</th><th>GAS</th><th>GitHub</th><th>JavaScript</th></tr>
<tr><td>💩</td><td>💩</td><td>💩</td><td>💩</td><td>💩</td></tr>
</table>`;
    tester.assertEquals(actual, expected);
  }

  test_getTrByRow_1_1(){
    const row = [1, 2, 3];
    const isTh = false;
    const textReplacingIfBlank = "";
    const actual = getTrByRow(row, isTh, textReplacingIfBlank);
    const expected = "<tr><td>1</td><td>2</td><td>3</td></tr>";
    tester.assertEquals(actual, expected);
  }

  test_getTrByRow_1_2(){
    const row = [1, 2, 3];
    const isTh = true;
    const textReplacingIfBlank = "";
    const actual = getTrByRow(row, isTh, textReplacingIfBlank);
    const expected = "<tr><th>1</th><th>2</th><th>3</th></tr>";
    tester.assertEquals(actual, expected);
  }

  test_closeByTag_1_1(){
    const tag = "a";
    const innerText = "test";
    const textReplacingIfBlank = "";
    const actual = closeByTag(tag, innerText, textReplacingIfBlank);
    const expected = "<a>test</a>";
    tester.assertEquals(actual, expected);
  }

  test_closeByTag_1_2(){
    const tag = "a";
    const innerText = "test";
    const textReplacingIfBlank = "";
    const actual = closeByTag(tag, innerText, textReplacingIfBlank);
    const expected = "<a>test<//a>";
    tester.assertNotEquals(actual, expected);
  }

  test_closeByTag_2_1(){
    const tag = "<a href=";
    const innerText = "test";
    const textReplacingIfBlank = "";
    tester.assertError(closeByTag, [tag, innerText, textReplacingIfBlank], Error);
  }

  test_closeByTag_2_2(){
    const tag = "<a href=";
    const innerText = "test";
    tester.assertError(closeByTag, [tag, innerText], Error);
  }

  test_closeByTag_3_1(){
    const tag = "a href=\"\">";
    const innerText = "test";
    const textReplacingIfBlank = "";
    tester.assertError(closeByTag, [tag, innerText, textReplacingIfBlank], Error);
  }

  test_closeByTag_3_2(){
    const tag = "a href=\"\">";
    const innerText = "test";
    tester.assertError(closeByTag, [tag, innerText], Error);
  }

}

function execute_Test_main(){
  let failureFuncs = tester.executeTestGas(Test_main);
}

ちなみに、TestGASのリポジトリはこちらになります。

GitHub - landmaster135/TestGAS
Contribute to landmaster135/TestGAS development by creating an account on GitHub.

解説

以下、今回のソースの解説になります。

その1:スプレッドシートの選択範囲を取得する

まず、getValuesBySelectedArea関数でスプレッドシートで選択した範囲を取得します。

function getValuesBySelectedArea(){
  const ss = SpreadsheetApp.getActive().getSheetByName(sheetName1st);
  const activeValues = ss.getActiveRange().getValues();
  console.log(activeValues);
  return activeValues;
}

その2:thタグとtdタグ、そして、trタグを作成する

まず、thタグとtdタグを作成します。

その処理を行う関数は、closeByTag関数になっています。

選択した範囲の1行目に対してはthタグを、それ以外の行にはtdタグを付与します。

そして、最後にtrタグで囲います。getTrByRow関数です。

/**
 * @param {string[]} row
 * @param {boolean} isTh
 * @param {string} textReplacingIfBlank
 * @return {string}
*/
function getTrByRow(row, isTh, textReplacingIfBlank="💩"){
  let element;
  let tr = "";
  let tagTd = "td";
  if(isTh){
    tagTd = "th";
    textReplacingIfBlank = "";
  }
  const tagTr = "tr";
  for(let i = 0; i< row.length; i++){
    element = closeByTag(tagTd, row[i], textReplacingIfBlank);
    tr += element;
  }
  tr = closeByTag(tagTr, tr, "");
  return tr;
}

/**
 * @param {string} tag without < and >
 * @param {string} innerText
 * @param {string} textReplacingIfBlank
 * @return {string}
*/
function closeByTag(tag, innerText, textReplacingIfBlank="💩"){
  if(tag[0] === "<"){
    throw Error("Initial of tag mustn't be \"<\".");
  }
  if(tag[tag.length - 1] === ">"){
    throw Error("End of tag mustn't be \">\".");
  }

  let initialOfTag = "<";
  let endOfTag = ">";
  let formerTag = `${initialOfTag}${tag}${endOfTag}`;
  let latterTag = `${initialOfTag}/${tag}${endOfTag}`;
  let displayText = innerText;
  if(displayText === ""){
    displayText = textReplacingIfBlank;
  }
  let element = `${formerTag}${displayText}${latterTag}`;
  return element;
}

その3:thタグとtdタグを作成するとき、ブランクの代替文字を決める

tableを作る時に、ブランクのセルが存在する場合があるかと思います。

その場合は、closeByTag関数のtextReplacingIfBlankの引数に代替文字を指定するとその文字に置き換わります。デフォルトは「💩」です。

代替文字を””で指定した場合のHTMLの描画。(GitHubのリポジトリ)

代替文字を指定せずにデフォルト値の場合のHTMLの描画。(GitHubのリポジトリ)

その4:tableタグで囲む

そして、沢山生成したtrタグに対して、tableタグで囲みます。

その処理を、getHtmlByValues関数で行っています。

/**
 * @param {string[]} values
 * @param {string} textReplacingIfBlank
 * @return {string}
*/
function getHtmlByValues(values, textReplacingIfBlank="💩"){
  let prefix = "<table>";
  let suffix = "</table>";
  let html = `${prefix}\n`;
  let tmp_tr = "";
  let isTh = false;
  for(let i = 0; i < values.length; i++){
    isTh = false;
    if(i === 0){
      isTh = true;
    }
    tmp_tr = getTrByRow(values[i], isTh, textReplacingIfBlank);
    html += `${tmp_tr}\n`;
  }
  html += suffix;
  return html;
}

その5:出力

こちらが、今まで解説した前処理の呼び出し部分と最終的な出力部分になります。

function main(){
  const values = getValuesBySelectedArea();
  const html = getHtmlByValues(values, "💩");
  console.log(html);
}

例えば、このように選択した場合に、

このように出力されます。

おしまい

135ml
135ml

これで、スプレッドシートで楽々編集しながら、好きな時にHTMLに変換できるなあ。

リサちゃん
リサちゃん

うん、これはかなり助かるなあ!

以上になります!

コメント

タイトルとURLをコピーしました