1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【React】html2canvas と jsPDF を使ってWebページのデザインをそのままPDF化

Last updated at Posted at 2025-02-17

はじめに

この記事では、html2canvas と jsPDF を使ってWebページのデザインをそのままPDF化する方法を記載します。

以下の記事では、React-pdf を使ったPDF作成方法を記載していますが、React-pdf では独自のコンポーネントを利用して、PDFのUIを実装する必要があります。

一方、今回紹介する html2canvas と jsPDF を使えば、WebページのデザインをそのままPDF化できます。
各ライブラリの役割は以下の通りです。

  • html2canvas: ブラウザ上のHTML要素を画像としてキャプチャできるライブラリ
  • jsPDF: 画像をPDFとして保存できるJavaScriptライブラリ

この2つを組み合わせることで、現在のWebページをそのままPDF化し、ユーザーにダウンロードさせることが簡単にできます。

各ライブラリの直近1年間のダウンロード数は以下の通りです。

image.png

開発環境

開発環境は以下の通りです。

  • html2canvas 1.4.1
  • jspdf 2.5.2
  • Windows11
  • React 18.3.1
  • TypeScript 5.7.3
  • Node.js 22.13.1
  • npm 11.0.0

インストール

まずは html2canvas と jsPDF をインストールします。

npm install html2canvas jspdf

PDF化対象のWebページのデザイン実装

次にPDF化対象のWebページのデザインを実装します。
今回は useRef を渡した範囲のエリアをPDF化します。

PdfExportSample.tsx
import { useRef } from "react";

export function PdfExportSample() {
  /** PDF化する対象の要素を参照するための useRef */
  const contentRef = useRef<HTMLDivElement>(null);

  return (
    <div>
      {/* PDFに変換する対象のエリア */}
      <div ref={contentRef} style={{ padding: 24, backgroundColor: "blue" }}>
        <h2>PDF化するコンテンツ</h2>
        <p>この部分がPDFとして出力されます。</p>
      </div>

      {/* PDFダウンロードボタン */}
      <button style={{ backgroundColor: "blue" }}>PDFをダウンロード</button>
    </div>
  );
}

image.png

PDF化処理の実装

最後に先ほど実装した箇所をPDF化する処理を実装します。
完成形は以下の通りです。処理順に解説していきます。

PdfExportSample.tsx
import html2canvas from "html2canvas";
import jsPDF from "jspdf";
import { useRef } from "react";

export function PdfExportSample() {
  /** PDF化する対象の要素を参照するための useRef */
  const contentRef = useRef<HTMLDivElement>(null);

  /** PDFダウンロード処理 */
  const handleDownloadPdf = async () => {
    if (!contentRef.current) return;

    try {
      // 1️⃣ 指定した要素をキャプチャしてCanvasに変換
      const canvas = await html2canvas(contentRef.current);

      // 2️⃣ Canvasを画像として取得(Base64のPNGデータ)
      const imageData = canvas.toDataURL("image/png");

      // 3️⃣ jsPDF インスタンスを作成(A4縦向き)
      const pdf = new jsPDF({ orientation: "p", unit: "mm", format: "a4"});

      // 4️⃣ PDFの幅を取得し、アスペクト比を維持した高さを計算
      const pdfWidth = pdf.internal.pageSize.getWidth();
      const pdfHeight = (canvas.height * pdfWidth) / canvas.width;

      // 5️⃣ 画像をPDFに追加(左上から配置)
      pdf.addImage({
        imageData: imageData,
        format: "PNG",
        x: 0,
        y: 0,
        width: pdfWidth,
        height: pdfHeight,
      });

      // 6️⃣ PDFをダウンロード
      pdf.save("document.pdf");
    } catch (error) {
      console.error("PDF生成中にエラーが発生しました:", error);
    }
  };

  return (
    <div>
      {/* PDFに変換する対象のエリア */}
      <div ref={contentRef} style={{ padding: 24, backgroundColor: "blue" }}>
        <h2>PDF化するコンテンツ</h2>
        <p>この部分がPDFとして出力されます。</p>
      </div>

      {/* PDFダウンロードボタン */}
      <button onClick={handleDownloadPdf} style={{ backgroundColor: "blue" }}>
        PDFをダウンロード
      </button>
    </div>
  );
}

1️⃣ 指定した要素をキャプチャしてCanvasに変換

PdfExportSample.tsx
const canvas = await html2canvas(contentRef.current);

html2canvas(contentRef.current) を呼び出すことで、指定した要素(contentRef)を Canvas(画像データ)に変換します。言い換えると、HTMLDivElementHTMLCanvasElement に変換します。
この処理により、Webページのデザインをそのまま画像として取得 できます。

2️⃣ Canvasを画像として取得(Base64のPNGデータ)

PdfExportSample.tsx
const imgData = canvas.toDataURL("image/png");

canvas.toDataURL("image/png") を使うことで、CanvasをPNG画像としてエンコード(Base64形式) できます。

imgData には "data:image/png;base64,...." のような文字列が入ります。

3️⃣ jsPDF インスタンスを作成(A4縦向き)

PdfExportSample.tsx
const pdf = new jsPDF({ orientation: "p", unit: "mm", format: "a4"});

new jsPDF({ orientation: "p", unit: "mm", format: "a4"}) で A4サイズのPDF(縦向き) を作成します。

  • "p" : 縦向き("portrait" のショートカット)
    • 横向きは "l" or "landscape"
  • "mm" : 単位をミリメートル に指定
  • "a4" : A4サイズ(210mm × 297mm)

4️⃣ PDFの幅を取得し、アスペクト比を維持した高さを計算

PdfExportSample.tsx
const pdfWidth = pdf.internal.pageSize.getWidth();
const pdfHeight = (canvas.height * pdfWidth) / canvas.width;

画像をPDFの幅いっぱいに拡大し、アスペクト比を保持するために高さを計算します。

5️⃣ 画像をPDFに追加(左上から配置)

PdfExportSample.tsx
pdf.addImage({
  imageData: imgData,
  format: "PNG",
  x: 0,
  y: 0,
  width: pdfWidth,
  height: pdfHeight,
});

pdf.addImage({ imageData: imgData, format: "PNG", x: 0, y: 0, width: pdfWidth, height: pdfHeight}) で、左上 (0,0) に画像を追加します。

6️⃣ PDFをダウンロード

PdfExportSample.tsx
pdf.save("document.pdf");

pdf.save("document.pdf") を呼び出すことで、PDFをダウンロード できます。"document.pdf" はPDFファイル名になります。

動作確認

動作確認をします。「PDFをダウンロード」ボタンをクリックすると、実装時に指定した範囲のWebページがPDFファイルとして出力されます。

Screen-Recording-2025-02-12-095920.gif

Webページを一度画像に変換してからPDF化しているため、PDFファイル内の文字検索等はできません。

まとめ

この記事では、html2canvas と jsPDF を使ってWebページのデザインをそのままPDF化する方法を記載しました。この方法を使えば、どんなWebページでも手軽にPDF化できます。
今後はページ分割方法やPDFファイルの容量が増えた時の対応法なども試していきたいです。

参考

1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?