Braian Mellor
Braian Mellor

Reputation: 1954

Print react native text and QR generated

Hello I need to generate a PDF o HTML view to print a document from an Android device. So I started to use Print from 'expo-print'. I can make this

Print.printAsync({
  html: "<h3>Hello World</h3>"
});

And works just fine. But I want to generate and include a QR code inside that HTML, I wanted to use react-native-qrcode but I don't know how to include it inside that.

clarification: the QR code needs to be created without connection too

Thanks

Upvotes: 3

Views: 4298

Answers (3)

Gev
Gev

Reputation: 882

You can use rn-qr-generator module (https://www.npmjs.com/package/rn-qr-generator). You need to pass value to the lib and it will return you uri and base64 data of the generated QRCode

import RNQRGenerator from 'rn-qr-generator';

componentDidMount() {
    RNQRGenerator.generate({
      value: 'otpauth://totp/Example:[email protected]?secret=JBSWY3DPEHPK3PXP&issuer=Example', // required
      height: 300,
      width: 300,
      base64: false, // default 'false'
      backgroundColor: 'black', // default 'white'
      color: 'white', // default 'black'
    })
      .then(response => {
        const { uri, width, height, base64 } = response;
        this.setState({ imageUri: uri });
      })
      .catch(error => console.log('Cannot create QR code', error));
  }

Upvotes: 1

GTHell
GTHell

Reputation: 628

I just came across the same problem and here's my solution.

I use react-native-qrcode-svg because it has a getRef props for you to further work with the QR data. Below, you can find my rough implementation (My main code is on another computer). You can further customize it to hide QRCode component or using Redux to store QRData but it should work fine.

import QRCode from 'react-native-qrcode-svg';

...

constructor(props) {
    super(props)
    this.state = { qrData: "" }
}

componentDidMount () {
  this.getDataURL(); // => Calling this in here to make sure the QRCode component did mount
}

... more code ...
print = () => {
  Print.printAsync({
    html: `
       <h3>Hello World</h3>
       <img src="data:image/jpeg;base64,${this.state.qrData}"/>
     `
  });
}
...

getDataURL() {
  this.svg.toDataURL(this.callback);
}
callback(dataURL) {
  this.setState({qrData: dataURL});
}
render() {
  return (
    <QRCode
      value="Just some string value"
      getRef={(c) => (this.svg = c)}
    />
    <Button title="Print QR to HTML" onPress={this.print} />
  );
}

Upvotes: 4

hong developer
hong developer

Reputation: 13906

If the html code can be printed, it appears that the code used in html can be used. You will be able to use an img tag.

const htmlcode = '<html>'
    + '<head>'
    + '<title>Testing QR code</title>'
    + '</head>'
    + '<body>'
    +  '<img id='barcode' src="https://api.qrserver.com/v1/create-qr-code/?data=HelloWorld&amp;size=100x100" alt="" title="HELLO" width="50" height="50" />'
    + '</body>'
    + '</html>';
...
Print.printAsync({
  html: htmlcode
});


Additional answers due to edited questions:

If you want to use QRCODE, you can't solve it with the module you want to use. Instead, you can solve this through 'React-native-web.' I will attach the link to the official document of Expo for the web setup. Once the setup is complete, use the existing app development method. However, the QRcode module does not currently work on the Web. The solution to this problem is to set QRCODE as an image file path, not as a web path in my first answer, and to show it when it's offline.

QRcode Example

import React, { Component } from 'react';
import QRCode from 'react-native-qrcode';

import { StyleSheet, View, TextInput } from 'react-native';

export default class HelloWorld extends Component {
  state = {
    text: 'testQRcode',
  };

  render() {
    return (
      <View style={styles.container}>
        <TextInput
          style={styles.input}
          onChangeText={(text) => this.setState({text: text})}
          value={this.state.text}
        />
        <QRCode
          value={this.state.text}
          size={200}
          bgColor='purple'
          fgColor='black'/>
      </View>
    );
  }
}

const styles = StyleSheet.create({
    container: {
        flex: 1,
        backgroundColor: 'white',
        alignItems: 'center',
        justifyContent: 'center'
    },

    input: {
        height: 40,
        borderColor: 'gray',
        borderWidth: 1,
        margin: 10,
        borderRadius: 5,
        padding: 5,
    }
});

Upvotes: 0

Related Questions