Reactのコンポーネントをそのままpdf表示したいときあると思います。
動的なuiをそのまま変換できるので便利。
次の手順で進める。
1.componentをcanvasに変換
2.canvasをpdfに変換
1. package install
$ npm i html2canvas jspdf
2. pdf表示ロジック
usePdf
import html2canvas from 'html2canvas'
import { jsPDF } from 'jspdf'
import { useRef } from 'react'
const usePdf = () => {
const targetRef = useRef<HTMLDivElement>(null)
const pdfOpenHandler = () => {
if (targetRef.current === null) return
html2canvas(targetRef.current).then((canvas) => {
const pdf = new jsPDF({ format: 'a4' })
pdf.addImage(canvas, 'canvas', 15, 10, canvas.width / 18, canvas.height / 18)
window.open(pdf.output('bloburl'))
})
}
return {
targetRef,
pdfOpenHandler,
}
}
export default usePdf
解説
targetRefにはReact componentが入る想定です。
componentをcanvasに変換
html2canvas(targetRef.current)
canvasをjspdfに突っ込む
const pdf = new jsPDF({ format: 'a4' })
pdf.addImage(canvas, 'canvas', 15, 10, canvas.width / 18, canvas.height / 18)
pdf.addImage(引数)
canvas: pngや他のフォーマットでもいけます。
'canvas': ファイルフォーマット
15: xの始点
10: yの始点
canvas.width / 18: 横幅(canvas.widthだと長すぎるので割ってます)
canvas.height / 18: 縦幅
pdfを表示
window.open(pdf.output('bloburl'))
ちなみにwindow使わず
pdf.output('dataurlnewwindow')
でも開きますがabout:blankで開くのでなんとなくやめました。
ダウンロードしたい場合は
pdf.save(faile名)
3. UIにセット
page.tsx
const page = () = {
const {targetRef, pdfOpenHandler} = usePdf()
return (
<>
<Component ref={targetRef}>
<Button onClick={pdfOpenHandler}>pdfで開く</Button>
</>
)
}
参考