diegomura / react-pdf

📄 Create PDF files using React
https://react-pdf.org
MIT License
14.4k stars 1.14k forks source link

QR code component in React-PDF #2419

Open web-shoharab-pk opened 8 months ago

web-shoharab-pk commented 8 months ago

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.

jb-thery commented 8 months ago

Hello, to show a QR code, you need to create a base64 representation of your QR code and present it using an 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} />
web-shoharab-pk commented 8 months ago

@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?

antokhio commented 6 months ago

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;
glody007 commented 6 months ago

@antokhio thanks

DoWhileGeek commented 2 weeks ago

@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>
antokhio commented 2 weeks ago

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 :)