Печать сгенерированных QR-кодов в файле PDF - PullRequest
3 голосов
/ 31 января 2020

Я создаю приложение ReactJS, которое использует QR-коды, и я хочу иметь возможность распечатать документ PDF с партией кодов одновременно. В настоящее время я использую реагировать-qr-svg для генерации кодов и @ реагировать-pdf / renderer для создания документа. Проблема в том, что мне не удалось показать эти QR-коды в документе.

Сначала я попытался использовать тег Image из @ response-pdf / renderer следующим образом:

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

Конечно, это не сработало, после этого я попытался преобразовать SVG в буфер данных и не дал результатов.

Есть ли какое-либо простое решение для этого? Должен ли я использовать другие библиотеки для этого проекта?

Ответы [ 2 ]

2 голосов
/ 01 февраля 2020

Непосредственно из документов: https://www.npmjs.com/package/react-qr-svg

Вам не нужно помещать его в тег изображения.

Я предполагаю, что эта библиотека выводит <svg> ... </svg> (Т. Е. Допустимые HTML теги для вывода напрямую)

Вы можете просто вывести тег / элемент напрямую?

  import React from "react";
  import { QRCode } from "react-qr-svg";

  class Demo extends React.Component {
      render() {
          return (
            <QRCode
            bgColor="#FFFFFF"
            fgColor="#000000"
            level="Q"
            style={{ width: 256 }}
            value="some text"
            />
          );
      }
  } 

ОБНОВЛЕНИЕ

Если я правильно понимаю, мы не можем просто вывести <svg>...</svg> на странице, так как библиотека @ реагировать-pdf / renderer не будет работать с тегами svg. Поэтому я предлагаю сериализовать svg в строку base-64, присвоив его sr c тега image, и тогда он будет работать.

Я собрал упрощенную демонстрацию вместе без библиотек: https://codepen.io/Alexander9111/pen/QWweYXO

HTML (упрощенно):

<svg>    
    <ellipse class="ground" fill="##787f6a" cx="283.5" cy="487.5" rx="259" ry="80"/>
    <path class="kiwi" fill="#94d31b" d="M210.333,65.331C104.367,...,203.01z"/>
</svg>
<div id="target">
    <!-- place to put our img tag -->
</div>

JS:

const svg = document.querySelector("svg");
const serializer = new XMLSerializer();
const svgStr = serializer.serializeToString(svg);

const img = document.createElement("img")
img.src = 'data:image/svg+xml;base64,'+ window.btoa(svgStr);

const target = document.querySelector("#target");
target.appendChild(img);
svg.parentNode.removeChild(svg);

Теперь, если мы хотим сделать это в Реакция, я предполагаю, что мы можем сделать это примерно так:

import React from "react";
import { QRCode } from "react-qr-svg";

  class Demo extends React.Component {
      render() {
        const svg = function {
          return (<QRCode
                  level="Q"
                  style={{width: 256, marginBottom: 50 }}
                  value={'hello world'}
              />);
        };
        const serializer = new XMLSerializer();
        const svgStr = serializer.serializeToString(svg);
        const img_src = 'data:image/svg+xml;base64,'+ window.btoa(svgStr);

          return (
            <img src={ img_src }/>
          );
      }
  } 

ИЛИ мы могли бы сделать это с помощью хуков жизненного цикла, таких как componentDidMount()

import React from "react";
import { QRCode } from "react-qr-svg";

  class Demo extends React.Component {
    componentDidMount() {
        const div = this.refs.target;
        const svg = div.querySelector("svg");
        const serializer = new XMLSerializer();
        const svgStr = serializer.serializeToString(svg);
        const img = this.refs.img;
        img.src = 'data:image/svg+xml;base64,'+ window.btoa(svgStr);
        svg.parentNode.removeChild(svg);
      }

    render() {                
      return (<div ref="target">
                <QRCode
                level="Q"
                style={{width: 256, marginBottom: 50 }}
                value={'hello world'}
                />
              <img ref="img"/>
              </div>
            ) 
      }
  } 

ОБНОВЛЕНИЕ - у меня это работает в React на CodePen: https://codepen.io/Alexander9111/pen/GRJKQQK

HTML: <div id="root"></div>

CSS: svg{border: 2px solid black;} img{border: 2px solid blue;}

Реакция JS:

class Demo extends React.Component {
  componentDidMount() {
    const div = this.refs.target;
    const svg = div.querySelector("svg");
    console.log(svg);
    const serializer = new XMLSerializer();
    const svgStr = serializer.serializeToString(svg);
    const img = this.refs.img;
    console.log(img);
    img.src = 'data:image/svg+xml;base64,'+ window.btoa(svgStr);
    svg.parentNode.removeChild(svg);
  }
  render() {                
      return (
        <div ref="target">
          <svg width="400" height="400">
            <circle r="100" cx="200" cy="200" fill="red" />
          </svg>
          <img ref="img"/>
        </div>
      ); 
    }
} 

ReactDOM.render(
  <Demo/>,
  document.getElementById('root')
);
1 голос
/ 30 марта 2020

Я использую qrcode.react с @react-pdf/renderer. Первое, что вам нужно сделать, это преобразовать ваш холст QR в base64

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

Затем передайте строку base64 (qrCodeDataUri) в качестве опоры для вашего PDF-компонента в источнике @react-pdf/renderer тега изображения:

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