PR

ExcelデータをJavaScriptでHTMLに反映【JSON】

ExcelデータをJavaScriptでHTMLに反映【JSON】 HTML/CSS

先日、ある静的サイトの新規ページを作成する中で、クライアントから支給されたExcelデータをHTMLに反映しないといけないという場面に遭いました。

そのExcelデータは100行以上に渡るボリュームで、工夫なくHTMLに反映していくと一生終わらない量です。

そこでJSONについて調べてJavaScriptでHTMLを生成させることにしました。

今回はそのときの備忘録と後日作ったデモ制作について紹介していきます。

ExcelデータをHTMLに反映

ExcelデータをHTMLに反映させる方法は以下の3つ。

  • 手作業でHTMLに反映する
  • Excelのオートフィル関数を使ってHTMLを作成する
  • JavaScriptでHTMLを生成させる

上記3つの方法のうち、「JavaScriptでHTMLを生成させる」を選びました。

JavaScriptでHTMLを生成させるメリット

「JavaScriptでHTMLを生成させる」を選ぶ理由は、構造を作るHTMLとテキストデータを持つJSONを分けられるからです。

  • 構造を作るHTML
  • テキストデータを持つJSON

JSONについては後で説明します

基本的にWebページは「構造を作るHTML」と「見た目を整えるCSS」を分離することで作り上げられますよね。

  • 構造を作るHTML
  • 見た目を整えるCSS

それと同じようにHTMLとJSONで分けてテキストデータを反映させると、編集のしやすさが格段に上がることが見込めます。

支給されたExcelデータのテキストが変更になったとしても、テキストデータ情報を持つJSONを編集するだけで済みます。ラクです。

以上を踏まえ、HTMLとJSONで分けてテキストデータを反映ために「JavaScriptでHTMLを生成させる」という手法を選びました。

JSONデータとは

先ほどJSONの話が出てきましたが、そもそもJSONって何なのかフワっとしか分かっていない自分のためにも調べてまとめてみました。

JSONとはJavaScript Object Notation の略で、データ記述言語の1つだそう。Notationは「表記」という意味。

例を挙げると以下のようなデータ形式のことを指します。

1	{
2	    "firstName": "John",
3	    "lastName": "Smith",
4	    "address": {
5	        "streetAddress": "21 2nd Street",
6	        "city": "New York",
7	        "state": "NY",
8	        "postalCode": 10021
9	    },
10	    "phoneNumbers": [
11	        "212-732-1234",
12	        "646-123-4567"
13	    ]
14	}

参考記事の説明とかをざっくりまとめると以下のような感じです。

  • 人にとって読みやすく書きやすい形式
  • マシンにとっても解析しやすく生成しやすい形式
  • JavaScript のオブジェクト構文に基づいている
  • ウェブアプリケーションでデータを転送する場合によく使われている

デモページ作成

mdn web docsの「JavaScriptオブジェクト入門」を参考にデモ制作しました。

完成ページ

今回実際に作ってみたデモページはこちらです。

Excel(スプシ)データ

今回のデモ制作では下記のスプレッドシートのデータをCSV形式でダウンロードし、ツールを使ってJSONデータに変換しました。

デモ制作ではGoogleスプレッドシートのデータを用いましたが、Microsoft Excelデータでも同様のことができます。

繰り返し使いたいHTML

下記のようなHTMLに入れ込んで出力したい。

<dl class="outer">
  <dt class="no"></dt>
  <dd>
    <dl class="inner open">
      <dt>9:30~10:00</dt>
      <dd>
        <p class="title">受付</p>
        <p class="small">null null null</p>
      </dd>
    </dl>
    <div class="detail">
      <dl class="inner">
        <dt class="no"></dt>
        <dd>
          <div class="document_area">
            <p class="small">ここに文章が入ります。ここに文章が入ります。ここに文章が入ります。</p>
          </div>
        </dd>
      </dl>
    </div>
  </dd>
</dl>

コピペで複製したりExcelのオートフィルでゴリゴリ作ったりするのは、手作業が多く変更修正がめんどくさい。

なのでHTMLとJSONを分けて作成する方がラクです。

スクリプトについて

今回作成したJavaScriptソースコードを下記の3つに分けて詳しく見ていきます。

  • for…of ループを使って反復処理
  • フェッチでJSON を取得
  • 定義した関数を呼び出す

for…of ループを使って反復処理

function populateIndex(obj) {
  const data = document.querySelector(".data");

  for (const index of obj) {

〜中略〜

  }
}

ここでは populateIndex関数を作ります。関数「populateIndex」と引数「obj」の名前は任意でオッケーです。

引数「obj」が後で取得するデータを受け取り、それらをfor…of ループで反復処理していきます。

for…of ループを使って配列のそれぞれのオブジェクトを反復処理します。それぞれの次のようなことを行います。

https://developer.mozilla.org/ja/docs/Learn/JavaScript/Objects/JSON

for…of ループの中ではひたすらDOM操作をするのですが、自力で書くのは面倒なので生成AIに書いてもらうのが良いでしょう。

「繰り返し使いたいHTML」を生成AIに投げると良い感じに書いてくれる。

JSON を取得するにはフェッチ

async function populate() {
  const requestURL = "index.json";
  const request = new Request(requestURL);

  const response = await fetch(request);
  const dateIndex = await response.json();

  populateIndex(dateIndex);
} 

上記ではpopulate関数を作成しています。関数名は任意です。

populate関数の中で、フェッチというAPIを使ってJSONデータを取得しています。

JSON を取得するには、フェッチという API を使用しています。 この API では、JavaScript を介してサーバーからリソースを取得するためのネットワークリクエストを行うことができます(画像、テキスト、JSON、HTML スニペットなど)。つまり、ページ全体を再読み込みしなくても、コンテンツの小さなセクションを更新できるのです。

https://developer.mozilla.org/ja/docs/Learn/JavaScript/Objects/JSON

asyncとawaitをセットで使うことによって、非同期処理に。他の処理(同期処理)を済ませてからフェッチでデータ取得します。

以下ではpopulate関数の中身をもう少し詳しく見ていきます。

const requestURL = "index.json";

まずは上記のように、取得したいJSONファイルを変数にする。

 const request = new Request(requestURL);

次に上記のように、Request() コンストラクターで新しい Request オブジェクトを生成。

const response = await fetch(request);

そのRequest オブジェクトをフェッチで取得します。

const dateIndex = await response.json();

json() メソッドを使って、取得したresponse変数をJSONとして解釈。

populateIndex(dateIndex);

最後に、JSONとして解釈したテキスト情報を引数として、先ほど定義した関数「populateIndex」を呼び出す。

これでJSONデータを取得する関数「populate」の定義が完成です。

定義した関数を呼び出す

populate();

定義した関数を最後に呼び出すことで、JSONデータを反映したHTMLを生成します。

これでスクリプトが完成です。

全スクリプト

下記に全スクリプトを掲載しておきます。

function populateIndex(obj) {
  const data = document.querySelector(".data");

  for (const index of obj) {
    const dlOuter = document.createElement("dl");
    dlOuter.className = "outer";

    const dtNo = document.createElement("dt");
    dtNo.className = "no";

    const ddOuter = document.createElement("dd");

    const dlInner = document.createElement("dl");
    dlInner.className = "inner open";

    const dtTime = document.createElement("dt");
    dtTime.textContent = index.時間;

    const ddInner = document.createElement("dd");

    const pTitle = document.createElement("p");
    pTitle.className = "title";
    pTitle.textContent = index.講演タイトル;

    const pSmall = document.createElement("p");
    pSmall.className = "small";
    pSmall.textContent = `${index.社名・団体名} ${index.部署名} ${index.講演者氏名}`;

    ddInner.appendChild(pTitle);
    ddInner.appendChild(pSmall);

    dlInner.appendChild(dtTime);
    dlInner.appendChild(ddInner);

    const divDetail = document.createElement("div");
    divDetail.className = "detail";

    const dlDetailInner = document.createElement("dl");
    dlDetailInner.className = "inner";

    const dtDetailNo = document.createElement("dt");
    dtDetailNo.className = "no";

    const ddDetail = document.createElement("dd");

    const divDocumentArea = document.createElement("div");
    divDocumentArea.className = "document_area";

    const pDetailSmall = document.createElement("p");
    pDetailSmall.className = "small";
    pDetailSmall.textContent = index["講演概要"] || "ここに文章が入ります。ここに文章が入ります。ここに文章が入ります。";

    divDocumentArea.appendChild(pDetailSmall);
    ddDetail.appendChild(divDocumentArea);
    dlDetailInner.appendChild(dtDetailNo);
    dlDetailInner.appendChild(ddDetail);
    divDetail.appendChild(dlDetailInner);

    ddOuter.appendChild(dlInner);
    ddOuter.appendChild(divDetail);

    dlOuter.appendChild(dtNo);
    dlOuter.appendChild(ddOuter);

    data.appendChild(dlOuter);
  }
}

async function populate() {
  const requestURL = "index.json";
  const request = new Request(requestURL);

  const response = await fetch(request);
  const dateIndex = await response.json();

  populateIndex(dateIndex);
}        

populate();

まとめ

以上が「ExcelデータをJavaScriptでHTMLに反映」の紹介でした。

この記事を投稿して数ヶ月経って読み返すと、自分の理解が浅かった箇所が多かったので、追記編集しております。

また読み返して思ったのは、生のJavaScript(vanilla.js)だとDOM操作がややこしすぎるということ。

生のJavaScriptのような「命令的」な書き方より、Reactのような「宣言的」な書き方の方がわかりやすい。なぜ理解しやすいのかは下記記事が詳しい。

「宣言的」な書き方をするフレームワークの方が開発の幅が広がりスピードが上がりそうなので、当分はそちらで書いていきたいなと思います。

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