'Printing generated QR codes on a PDF file

I'm creating a ReactJS app that uses QR codes and I want to be able to print a PDF document with a batch of codes at once. I'm currently using both react-qr-svg to generate the codes and @react-pdf/renderer to create the document. The problem is that I haven't been able to show these QR Codes on the document.

First I tried using the Image tag from @react-pdf/renderer like this:

<Image
  src={<QRCode
    level="Q"
    style={{width: 256, marginBottom: 50 }}
    value={'hello world'}
  />}
/>

Whick of course didn't work, after that I tried to convert the SVG to a Data Buffer and had no results.

Is there any straightforward solution for this? Should I use other libraries for this project?



Solution 1:[1]

I use qrcode.react with @react-pdf/renderer. First thing you need to do is to convert your QR canvas to base64

const qrCodeCanvas = document.querySelector('canvas');
const qrCodeDataUri = qrCodeCanvas.toDataURL('image/jpg', 0.3);

Then, pass base64 string (qrCodeDataUri) as a prop to your PDF component in source of @react-pdf/renderer image tag:

<Image source={ {uri: props.yourBase64Image} } />

Solution 2:[2]

My solution does not write the initial svg to the DOM, instead it converts the react component to static markup. Then I parse that markup to use its properties in the Svg component that @react-pdf/renderer supports.

import React from 'react';
import { Text, View, Svg, Path } from '@react-pdf/renderer';
import { renderToStaticMarkup } from 'react-dom/server';
import ReactHtmlParser from 'react-html-parser';
import QRCode from 'qrcode.react';

const PdfWithQrCode = () => {
    const qrCodeComponent = (
        <QRCode
            value={ssf_id}
            renderAs="svg"
            size={80}
        />
    );

    const qrCodeComponentStaticMarkup = renderToStaticMarkup(qrCodeComponent);

    const parsedQrCodeSvg = parseQrCodeMarkup(qrCodeComponentStaticMarkup);
    if (! parsedQrCodeSvg) {
        return null;
    }

    return (
        <View>
            <Svg
                style={{ width: 50, height: 50 }}
                viewBox="0 0 29 29"
            >
                {parsedQrCodeSvg.props.children.filter(c => c.type === 'path').map((child, index) => (
                    <Path
                        key={index}
                        d={child.props.d}
                        fill={child.props.fill}
                    />
                ))}
            </Svg>
        </View>
    );
}

const parseQrCodeMarkup = (markup) => {
    let parsedQrCodeSvg = null;

    ReactHtmlParser(markup).forEach(el => {
        const { type } = el;
        if (type === 'svg') {
            parsedQrCodeSvg = el;
        }
    });

    return parsedQrCodeSvg;
};

export default PdfWithQrCode;

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 sergei