(151) HTML要素を画像ファイルとして保存したい。

投稿者: | 2024年2月15日

32 views

【1】やりたいこと

Webページ上で表示している table要素を、画像ファイルとして保存したい。

【2】やってみる

1) 利用するライブラリ

所望の機能を JavaScriptで実装する。
今回の実装では html2canvas を使わせていただく。

今回は、GitHub上で公開されている最新リリース版 を使わせていただく。 2024年2月15日時点
https://github.com/niklasvh/html2canvas

2) 実装した結果

実装仕様は以下の通り。
1. ボタン押下で tableを画像ファイルとして自動保存する。
2. 画像ファイル名には、現在時刻値を使用する。
3. 画像ファイル生成時には、Webページ上の表示とは異なるデザインに変更する。

実際に動作しているページはこちらです。
https://www.dogrow.net/hp/sample/00151

(1) index.html

<!DOCTYPE html>
<html>

<head>
  <meta charset="utf-8">
  <title>Blog 151</title>
  <link rel="stylesheet" href="style.css" />
  <script src="html2canvas.min.js"></script>
  <script src="script.js"></script>
</head>

<body>
  <div id="convToImg">
    <table>
        <tr>
            <th>月</th><th>火</th><th>水</th><th>木</th><th>金</th><th>土</th><th>日</th>
        </tr>
        <tr>
            <td>1</td><td>2</td><td>3</td><td>4</td><td>5</td><td>6</td><td>7</td>
        </tr>
        <tr>
            <td>8</td><td>9</td><td>10</td><td>11</td><td>12</td><td>13</td><td>14</td>
        </tr>
    </table>
  </div>

  <div>
    <button id="btn">画像に変換</button>
  </div>
</body>

</html>

(2) script.js

// Webブラウザが DOM生成完了時に起動するイベントハンドラ
document.addEventListener('DOMContentLoaded', function() {
  const cssClassForImg = 'forImg';
  const objConvToImg   = document.getElementById('convToImg');
  const objBtn         = document.getElementById('btn');

  // [画像に変換]ボタンを押下時のイベントハンドラを登録
  objBtn.addEventListener('click', function(){
    // 画像化対象領域をラップする要素に、画像化時用の CSSクラスを追加
    objConvToImg.classList.add(cssClassForImg);
    // 画像化対象領域をラップする要素の配下を PNG画像化する。
    html2canvas(objConvToImg).then(canvas => {
      // canvasをPNG画像としてエンコード
      const imgData = canvas.toDataURL('image/png');
      // 生成した画像をファイルとしてダウンロード
      const downloadLink    = document.createElement('a');
      downloadLink.href     = imgData;
      downloadLink.download = `img_${getCurrentDateTimeString()}.png`;
      document.body.appendChild(downloadLink);    // 一時的にリンクを作成し、
      downloadLink.click();                       //  → それをクリックしてダウンロードを実行し、
      document.body.removeChild(downloadLink);    //   → 一時的に作成したリンクを削除する。
    });
    // 画像化対象領域をラップする要素から、画像化時用の CSSクラスを除去
    objConvToImg.classList.remove(cssClassForImg);
  });
});

// 現在日時の文字列を作成 (※ファイル名の作成に使用しているだけ)
function getCurrentDateTimeString() {
    const now = new Date();
    // 年、月、日、時、分、秒を取得
    const year    = now.getFullYear();
    const month   = String(now.getMonth() + 1).padStart(2, '0'); // 月は0から始まるため、1を足す
    const day     = String(now.getDate()).padStart(2, '0');
    const hours   = String(now.getHours()).padStart(2, '0');
    const minutes = String(now.getMinutes()).padStart(2, '0');
    const seconds = String(now.getSeconds()).padStart(2, '0');
    // フォーマットに従って結合
    const dateTimeString = `${year}_${month}_${day}_${hours}_${minutes}_${seconds}`;
    return dateTimeString;
}

(3) style.css

*{
    box-sizing: border-box;
}
html{
    font-size: 2vw;
}
table{
    border-collapse: collapse;
    border-spacing: 0;
    background-color: #fff;
}
table th,
table td{
    border: 2px #000 solid;
}
table td{
    text-align: center;
}
button{
    cursor: pointer;
}
div#convToImg{
    padding: 1rem;
    display: inline-block;
}

/* ↓↓↓ 以下、画像生成時にテーブルに適用する CSS ↓↓↓*/
div.forImg{
    background-color: #ff0;
}
div.forImg table{
    border: 4px #00f solid;
}
div.forImg th,
div.forImg td{
    font-size: 2rem;
    border: 4px #00f solid;
}

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です


日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)