Zenn
Open3

pdf出力系のライブラリをnuxt3で使った記録

kamaguchikamaguchi

[html2pdf.js]

const generatePDF = () => {
  html2pdf().from(distHTML.value).set({
    margin: 10,
    filename: "document.pdf",
    image: { type: "jpeg", quality: 0.98 },
    html2canvas: { scale: 2 },
    jsPDF: { unit: "mm", format: "a4", orientation: "portrait" }
  }).save();
};
<template>
  <div>
    content PDF
    <div ref="distHTML" class="dist-pdf p-4 shadow">
      <h2 contenteditable="true">{{ title }}</h2>
      <p contenteditable="true" class="p-2">
        {{ detail }}
      </p>
      <p contenteditable="true" class="p-2">
        {{ detail }}
      </p>
      <p class="p-2">
        {{ goal }}
      </p>
    </div>
    <button
        class="bg-indigo-700 font-semibold text-white py-2 px-4 rounded"
        @click="generatePDF"
      >PDFを生成</button>
  </div>
</template>

html2pdf.jsの読み込みとtypescriptの相性が良くなく、調整に時間のコストがかかる

kamaguchikamaguchi

[html2canvas]
[jspdf]

import html2canvas from 'html2canvas';
import jsPDF from 'jspdf';
import { ref } from "vue";

const distHTML = ref<HTMLDivElement>()

const title = ref('1. 契約の目的');
const detail = ref("");
const goal = ref('本契約の目的は、双方の合意に基づく業務を遂行することです。');

const generatePDF = async () => {
  if (distHTML.value) {
    const canvas = await html2canvas(distHTML.value);
    const imgData = canvas.toDataURL('image/png');
    const pdf = new jsPDF();
    const imgProps = pdf.getImageProperties(imgData);
    const pdfWidth = pdf.internal.pageSize.getWidth();
    const pdfHeight = (imgProps.height * pdfWidth) / imgProps.width;
    pdf.addImage(imgData, 'PNG', 0, 0, pdfWidth, pdfHeight);
    pdf.save('sample.pdf');
  }
}
<template>
  <div>
    content PDF
    <div ref="distHTML" class="dist-pdf p-4 shadow">
      <h2 contenteditable="true">{{ title }}</h2>
      <p contenteditable="true" class="p-2">
        {{ detail }}
      </p>
      <p contenteditable="true" class="p-2">
        {{ detail }}
      </p>
      <p class="p-2">
        {{ goal }}
      </p>
    </div>
    <button
        class="bg-indigo-700 font-semibold text-white py-2 px-4 rounded"
        @click="generatePDF"
      >PDFを生成</button>
  </div>
</template>

contenteditable="true"を使っていくとバリエーションも増えそうです。設計が課題かもしれません。

ログインするとコメントできます