[0004]クライアント側(JS)でHTMLをPDFや画像で作成

■JS

HTML→PDFは帳票などは良いが複雑なstyleのPDFを変換するのは至難と改めて感じたこの頃。

まずはHMTLをそのままPDFへ変換するには「html2pdf」を利用。

              
//html2pdfのCDNを利用
<script src="https://cdnjs.cloudflare.com/ajax/libs/html2pdf.js/0.12.1/html2pdf.bundle.min.js"></script>
//コード
sethtml = "セットしたい要素のセット、書き込みたいHTMLコードなど";
html2pdf(sethtml).save("test.pdf");
              
            

これだけでローカルにPDFがダウンロードされる。作成されたPDFの文字も認識でき問題ないが1点だけ懸念が。。。

複雑なstyleでは画像が伸びたり広がったりPaddingが狭くなっていたり完全にHTMLの通りではなかった

次にHMTLを画像へ変換して画像をそのままダウンロードするには「html2canvas」を利用。

              
//画像変換はhtml2canvasのCDNを利用
<script src="https://cdn.jsdelivr.net/npm/html2canvas@1.3.2/dist/html2canvas.min.js"></script>

//コード 表示したいHTMLを画面で開き、画像を作成
const printWindow = window.open('https://XXX.jp/pdf/test.html', '_blank');

printWindow.onload = () => {
    // 別ウィンドウのコンテンツを取得
    const element = printWindow.document.documentElement;

    // オプションオブジェクトを第2引数に渡します
    const options = {
        scale: 2,           // 解像度
        useCORS: true,      // 外部画像がある場合に必要
        logging: false,     // コンソールログを非表示に
    };
    html2canvas(element,options).then(function(canvas) {
    	const link = document.createElement('a');
        link.download = 'screenshot.png';
        link.href = canvas.toDataURL('image/png');
        link.click();
    });
}
              
            

次にHMTLを画像へ変換。画像からPDFへ変換してからダウンロードするには「html2canvas」と「jspdf」を利用。

              
//画像変換はhtml2canvasのCDNを利用
<script src="https://cdn.jsdelivr.net/npm/html2canvas@1.3.2/dist/html2canvas.min.js"></script>
//画像からPDF変換はjspdfのCDNを利用
<script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/3.0.1/jspdf.umd.min.js"></script>
//コード 表示したいHTMLを画面で開き、PDFを作成
const printWindow = window.open('https://XXX.jp/pdf/test.html', '_blank');

printWindow.onload = () => {
    // 別ウィンドウのコンテンツを取得
    const element = printWindow.document.documentElement;

    html2canvas(element,options).then(function(canvas) {
        // ここで初めて canvas が実体化します
        const imgData = canvas.toDataURL('image/png');

        const pdf = new jspdf.jsPDF('p', 'mm', 'a4');

    	const pdfWidth = pdf.internal.pageSize.getWidth();

    	const pdfHeight = (canvas.height * pdfWidth) / canvas.width;

    	pdf.addImage(imgData, 'PNG', 0, 0, pdfWidth, pdfHeight);
    	pdf.save('download.pdf');
	});
}
              
            

画像にするとstyle崩れはないが、文字列が画像になっているのでPDFから文字が抜き出せないのとsizeが大きくなるデメリットあり。。