在 PDF 文件上打印生成的二维码

Edd*_*rre 7 javascript svg qr-code reactjs react-pdf

我正在创建一个使用 QR 码的 ReactJS 应用程序,我希望能够一次打印包含一批代码的 PDF 文档。我目前正在使用react-qr-svg来生成代码和@react-pdf/renderer来创建文档。问题是我无法在文档上显示这些二维码。

首先,我尝试使用来自 @react-pdf/renderer 的 Image 标签,如下所示:

<Image
  src={<QRCode
    level="Q"
    style={{width: 256, marginBottom: 50 }}
    value={'hello world'}
  />}
/>
Run Code Online (Sandbox Code Playgroud)

Whick 当然不起作用,之后我尝试将 SVG 转换为数据缓冲区,但没有结果。

有什么直接的解决方案吗?我应该为此项目使用其他库吗?

Mak*_*hyk 8

我用qrcode.react@react-pdf/renderer。您需要做的第一件事是将您的 QR 画布转换为 base64

const qrCodeCanvas = document.querySelector('canvas');
const qrCodeDataUri = qrCodeCanvas.toDataURL('image/jpg', 0.3);
Run Code Online (Sandbox Code Playgroud)

然后,将 base64 字符串 ( qrCodeDataUri) 作为道具传递给@react-pdf/renderer图像标签源中的 PDF 组件:

<Image source={ {uri: props.yourBase64Image} } />
Run Code Online (Sandbox Code Playgroud)

  • 更好的解决方案!(如果我们可以直接从 qrccode 组件转到 base64 数据而不需要写入 DOM,感觉会更干净一些 - 但这仍然很棒!) (3认同)

Ale*_*x L 3

直接来自文档: https: //www.npmjs.com/package/react-qr-svg

\n\n

您不需要\xe2\x80\x99t 将其放入图像标签中。

\n\n

我的假设是这个库输出<svg> ... </svg>(即直接输出的有效 HTML 标签)

\n\n

你可以直接输出标签/元素吗?

\n\n
  import React from "react";\n  import { QRCode } from "react-qr-svg";\n\n  class Demo extends React.Component {\n      render() {\n          return (\n            <QRCode\n            bgColor="#FFFFFF"\n            fgColor="#000000"\n            level="Q"\n            style={{ width: 256 }}\n            value="some text"\n            />\n          );\n      }\n  } \n
Run Code Online (Sandbox Code Playgroud)\n\n

更新

\n\n

如果我理解正确的话,我们不能简单地<svg>...</svg>在页面上输出,因为库@react-pdf/renderer不适用于 svg 标签。所以我建议我们将 svg 序列化为 base-64 字符串,将其分配给图像标签的 src,然后它应该可以工作。

\n\n

我在没有库的情况下将简化的演示放在一起:https ://codepen.io/Alexander9111/pen/QWweYXO

\n\n

HTML(简化):

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

JS:

\n\n
const svg = document.querySelector("svg");\nconst serializer = new XMLSerializer();\nconst svgStr = serializer.serializeToString(svg);\n\nconst img = document.createElement("img")\nimg.src = \'data:image/svg+xml;base64,\'+ window.btoa(svgStr);\n\nconst target = document.querySelector("#target");\ntarget.appendChild(img);\nsvg.parentNode.removeChild(svg);\n
Run Code Online (Sandbox Code Playgroud)\n\n

现在,如果我们想在 React 中做到这一点,我想我们可以这样做:

\n\n
import React from "react";\nimport { QRCode } from "react-qr-svg";\n\n  class Demo extends React.Component {\n      render() {\n        const svg = function {\n          return (<QRCode\n                  level="Q"\n                  style={{width: 256, marginBottom: 50 }}\n                  value={\'hello world\'}\n              />);\n        };\n        const serializer = new XMLSerializer();\n        const svgStr = serializer.serializeToString(svg);\n        const img_src = \'data:image/svg+xml;base64,\'+ window.btoa(svgStr);\n\n          return (\n            <img src={ img_src }/>\n          );\n      }\n  } \n
Run Code Online (Sandbox Code Playgroud)\n\n

或者我们可以使用生命周期钩子来做到这一点,例如componentDidMount()

\n\n
import React from "react";\nimport { QRCode } from "react-qr-svg";\n\n  class Demo extends React.Component {\n    componentDidMount() {\n        const div = this.refs.target;\n        const svg = div.querySelector("svg");\n        const serializer = new XMLSerializer();\n        const svgStr = serializer.serializeToString(svg);\n        const img = this.refs.img;\n        img.src = \'data:image/svg+xml;base64,\'+ window.btoa(svgStr);\n        svg.parentNode.removeChild(svg);\n      }\n\n    render() {                \n      return (<div ref="target">\n                <QRCode\n                level="Q"\n                style={{width: 256, marginBottom: 50 }}\n                value={\'hello world\'}\n                />\n              <img ref="img"/>\n              </div>\n            ) \n      }\n  } \n
Run Code Online (Sandbox Code Playgroud)\n\n

更新- 我在 CodePen 上的 React 中工作:https://codepen.io/Alexander9111/pen/GRJKQQK

\n\n

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

\n\n

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

\n\n

反应JS:

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