📄

Reactでreact-pdfとqrcodeを使って、PDFにQRコードを乗せてダウンロードできるようにする

2023/10/14に公開

目的

URLからQRコードを生成し、それを印刷してどっかに貼り付けるってことはよくあると思う。
複数のURLを用意して、QRコードに変換し、PDFに乗せる。そのPDFをボタン1つでダウンロードできるようにする。
これらの処理はクライアントサイドで完結すること。

すぐわかる

  • qrcodeでURLからQRコードの画像をbase64にエンコードして取得
  • ソースをreact-pdfのImageに置く

完成品

これ
https://github.com/omuni1234/react-qrcode-pdf

URLを変数においておくと、pdfに出力してくれる!

解説

インストール

npm i @react-pdf/renderer qrcode

コードの解説

PDFQR.jsx
import React from 'react'
import MyDocument from './MyDocument'
import QRCode from 'qrcode'
import {PDFViewer, PDFDownloadLink} from '@react-pdf/renderer';
import {Button} from '@mui/material'


const fakeURLs = [
    'https://www.google.com',
    'https://www.yahoo.co.jp',
    'https://www.bing.com',
    'https://www.amazon.co.jp',
    'https://www.rakuten.co.jp'
]

const PDFQR = () => {
    const images = fakeURLs.map((url) => {
        return QRCode.toDataURL(url, {type: "png"})
    })

    return (
        <>
            <PDFDownloadLink
                document={<MyDocument imageSrc={images}/>}
                fileName="QR.pdf"
            >
                <Button variant='contained'>
                    QRコードをダウンロード
                </Button>
            </PDFDownloadLink>

            <PDFViewer>
                <MyDocument imageSrc={images}/>
            </PDFViewer>
        </>
    )
}

export default PDFQR
  • fakeURLsにQRコード化したいURLを乗せる
    const images = fakeURLs.map((url) => {
        return QRCode.toDataURL(url, {type: "png"})
    })
  • ここでQRコードのURLをQRコードにする
  • ミソはtoDataURLで、これがpngでQRコードをbase64にエンコードする
	    <PDFDownloadLink
                document={<MyDocument imageSrc={images}/>}
                fileName="QR.pdf"
            >
                <Button variant='contained'>
                    QRコードをダウンロード
                </Button>
            </PDFDownloadLink>

            <PDFViewer>
                <MyDocument imageSrc={images}/>
            </PDFViewer>

ここで、PDFダウンロードのリンクと、PDFのビューワーがある

MyDocument.jsx
import { Page, Text, View, Document, StyleSheet, Image } from '@react-pdf/renderer';

const styles = StyleSheet.create({
    page: {
        flexDirection: 'row',
        backgroundColor: 'white'
    },
    image: {
        // 縦横比を維持したまま、横幅を100%にする
        width: '100%',
        height: '100%',
        // 中央寄せ
        textAlign: 'center',
        // 余白を設定
        paddingTop: 30,
        paddingLeft: 30,
        paddingRight: 30,
        // 文字サイズ
        fontSize: 60
    }
});

const MyDocument = ({ imageSrc }) => {
    return (
        <Document>
            <Page size="A4" style={styles.page} >
                {
                    imageSrc.map((image, index) => {
                        return (
                            <View key={index} style={styles.image}>
                                <Image src={image}></Image>
                            </View >
                        )
                    })
                }
            </Page>
        </Document>
    )
}

export default MyDocument;
  • react-pdfはImageにsrcタグを追加することができる
  • ここに先程生成したbase64のデータをいれるだけ

まとめ

  • なんかツールとかにつかえそう!

Discussion