• 活用ブログTOP
  • 【カスタムブロック】エクセルを読み込んでテーブルで表示する
hayase hayase

【カスタムブロック】エクセルを読み込んでテーブルで表示する

カスタムブロックでは独自のブロックを追加できますが、今回はエクセルファイルをアップロードすると自動的にテーブルに変換してくれるブロックを作成してみます。

実用的に使えるので是非お試しください。
※ ブラウザ Safari ではセキュリティ上の制限により動作しません。

カスタムブロックの作成

カスタムブロックは左メニューのカスタムブロック>新規から作成できます。今回は以下で設定してください。

カスタムブロックの編集ページの右上の読み込むボタンから以下のファイルを読み込んでも同じものが作成できます。(zipを展開してjsonファイルを読み込んでください)

  • 名前:エクセル
  • 識別子:excel
  • ブロック:何もしない
  • ブロックの追加と削除:チェックを外す

カスタムスクリプトには以下を挿入してください。

<script src="https://cdnjs.cloudflare.com/ajax/libs/xlsx/0.15.2/xlsx.full.min.js" integrity="sha256-SOeQ8yqDi+NlDLrc0HMhyEdsXn+Z/TPVSjhAukwBiyU=" crossorigin="anonymous"></script>
<script>
function sheetToTable(table) {
  var html = "<table>";

  html += "<thead><tr>";
  table.shift().forEach(function (v) {
    html += "<th>" + v + "</th>";
  });
  html += "</tr></thead>";

  html += "<tbody>";
  table.forEach(function (row) {
    html += "<tr>";
    row.forEach(function (v) {
      html += "<td>" + v + "</td>";
    });
    html += "</tr>";
  });
  html += "</tbody></table>";

  return html;
}

async function parseExcel(file) {
  const map = {};
  const reader = new FileReader();
  return new Promise((resolve, reject) => {
    reader.onload = function (e) {
      var data = e.target.result;
      var workbook = XLSX.read(data, {
        type: "binary",
      });

      workbook.SheetNames.forEach(function (name) {
        map[name] = XLSX.utils.sheet_to_row_object_array(
          workbook.Sheets[name],
          { header: 1 }
        );
      });

      resolve(map);
    };

    reader.onerror = function (e) {
      reject(e);
    };

    reader.readAsBinaryString(file);
  });
}

document.addEventListener("DOMContentLoaded", async () => {
  if (!document.body.dataset.hasCompiledHtml) {
    document.body.textContent = "エクセルファイルをドロップしてください";
    Object.assign(document.body.style, {
      textAlign: "center",
      paddingTop: "40px",
    });
  }

  MTBlockEditorAddDroppable(async (ev) => {
    let sheets = {};
    const files =
      ev.type === "change" ? ev.target.files : ev.dataTransfer.files;
    for (let i = 0; i < files.length; i++) {
      sheets = { ...(await parseExcel(files[i])), ...sheets };
    }

    const names = Object.keys(sheets);
    if (names.length === 0) {
      return;
    } else if (names.length === 1) {
      MTBlockEditorSetCompiledHtml(sheetToTable(sheets[names[0]]));
    } else {
      document.body.innerHTML = "";
      Object.assign(document.body.style, {
        textAlign: "",
        paddingTop: "",
      });

      const container = document.createElement("div");
      Object.assign(container.style, {
        textAlign: "center",
      });
      document.body.appendChild(container);

      const select = document.createElement("select");
      container.appendChild(select);
      select.addEventListener("click", (ev) => {
        ev.stopPropagation();
      });
      select.addEventListener("change", (ev) => {
        MTBlockEditorSetCompiledHtml(sheetToTable(sheets[ev.target.value]));
      });

      const defaultOption = document.createElement("option");
      defaultOption.textContent = "シートを選択してください";
      select.appendChild(defaultOption);

      names.forEach((name) => {
        const option = document.createElement("option");
        option.value = name;
        option.textContent = name;
        select.appendChild(option);
      });
    }
  });
});
</script>

以上の設定で保存すれば作成完了です。

実際に記事・ウェブページ内で利用する方法

記事やウェブページの編集画面のブロックエディタのブロックを追加ボタンを押すと、先程作成したエクセルも表示されるのでそれを選択します。

選択すると以下のようにブロックが追加されるので、エクセルファイルをドラッグ&ドロップ(もしくはクリック)で設定します。

そうすると、以下のようにテーブル(表)として表示されます。

※ もしシートが複数ある場合は、以下のようにシートを選択するメニューが表示されます。

実際に出力したページは以下になります。tableに関して適宜CSSでデザインを調整してください。

以上、是非お試しいただければと思います!