react-pdf icon indicating copy to clipboard operation
react-pdf copied to clipboard

QR code component in React-PDF

Open web-shoharab-pk opened this issue 2 years ago • 7 comments

Is your feature request related to a problem? Please describe. Last time I was working on one invoice solution system. I used the React-PDF package for PDF creation, printing, and downloading. I faced one issue when using a QR code on my pdf. However, I didn't get any solution to using QR code in the React-PDF component. My request is If possible please create a component link View or Text for the QR code.

Thank you

Describe the solution you'd like I think we need a component in this package and a component named QRCode

Describe alternatives you've considered A clear and concise description of any alternative solutions or features you've considered.

Additional context Add any other context or screenshots about the feature request here.

web-shoharab-pk avatar Oct 22 '23 08:10 web-shoharab-pk

Hello, to show a QR code, you need to create a base64 representation of your QR code and present it using an <Image /> component.

Example :

import QRCode from "qrcode"

export const generateSessionPDFQrCode = async (
  baseUrl: string,
  locale: Locales,
  monthWorkout: string,
  sessionIndex: number,
): Promise<string> => {
  return await QRCode.toDataURL(
    generateSessionLink(baseUrl, locale, monthWorkout, sessionIndex),
    {
      errorCorrectionLevel: "H",
    },
  )
}
  const QRCode = generateSessionPDFQrCode(
    baseUrl,
    locale,
    monthWorkout,
    sessionCount,
  )

and in your jsx

<Image style={{ width: 120 }} src={QRCode} />

jb-thery avatar Oct 22 '23 11:10 jb-thery

@jb-thery thank you so much for your response it's work for me. I need another help, how can I implement print functionality with out open new window in react-pdf package?

web-shoharab-pk avatar Oct 24 '23 07:10 web-shoharab-pk

To whom it may concern:

import React, { useMemo } from "react";
import { Rect, Svg } from "@react-pdf/renderer";
import { getMatrix } from "qr-code-generator-lib";

interface QRProps {
  url: string;
  level?: keyof typeof EcLevels;
  width?: number;
  foreground?: string;
  background?: string;
}

enum EcLevels {
  L = 0,
  M = 1,
  Q = 2,
  H = 3,
}

const QR = ({
  url,
  level = "H",
  width = 64,
  foreground = "#000",
  background = "#fff",
}: QRProps): JSX.Element => {
  // EcLevels seems to not do anything...
  // @ts-expect-error qr-code-generator-lib-misstype
  const matrix = useMemo(() => getMatrix(url), EcLevels[level], [url, level]);
  const factor = useMemo(() => width / matrix.length, [matrix, width]);

  return (
    <Svg width={width} height={width} viewBox={`0 0 ${width} ${width}`}>
      {matrix.map((row, x) =>
        row.map((cell, y) => (
          <Rect
            x={x * factor}
            y={y * factor}
            width={1 * factor}
            height={1 * factor}
            // gives better visual result then cell & <Rect .../>
            // due to rounding errors with factor 
            fill={cell ? foreground : background}
          />
        ))
      )}
    </Svg>
  );
};

export default QR;

antokhio avatar Dec 19 '23 14:12 antokhio

@antokhio thanks

glody007 avatar Jan 03 '24 08:01 glody007

@antokhio I ran into an issue where renderPath from qr-code-generator-lib resulted in a valid qr code, whereas your implementation did not. After a bit of squinting at the two different outputs, it seems like your algo has rows and columns swapped.

your algo: Screenshot 2024-06-17 at 5 10 51 PM

renderPath Screenshot 2024-06-17 at 5 10 59 PM

simply swapping the x and y values fixes this

    <Svg width={width} height={width} viewBox={`0 0 ${width} ${width}`}>
      {matrix.map((row, y) =>
        row.map((cell, x) => (
          <Rect
            x={x * factor}
            y={y * factor}
            width={1 * factor}
            height={1 * factor}
            // gives better visual result then cell & <Rect .../>
            // due to rounding errors with factor
            fill={cell ? foreground : background}
          />
        ))
      )}
    </Svg>

DoWhileGeek avatar Jun 18 '24 00:06 DoWhileGeek

Hey, nice find, guess issue in underlying lib, to be honest it was first lib I found that outputs as bool[][], fun part it's still scans properly :)

antokhio avatar Jun 19 '24 20:06 antokhio

@antokhio ec levels aren't working because of this typo:

-  const matrix = useMemo(() => getMatrix(url), EcLevels[level], [url, level]);
+  const matrix = useMemo(() => getMatrix(url, EcLevels[level]), [url, level]);

thgh avatar Sep 25 '24 00:09 thgh

nice

theskillwithin avatar Oct 28 '24 21:10 theskillwithin

Hello Team, I am having issues showing a barcode in the pdf renderer. whereas the qr from the code provided above works super fine, the bar code has completely failed. is there a work around to make it show? Has anyone faced this before and figured it out? kindly support

Max-256 avatar Apr 03 '25 23:04 Max-256