birt icon indicating copy to clipboard operation
birt copied to clipboard

Qrcode feature

Open wimjongman opened this issue 3 years ago • 2 comments

@hvbtup let's work on this branch. I could not push back to the PR.

wimjongman avatar Oct 13 '22 17:10 wimjongman

ATM I am off sick and I try to understand how to add scripting support to an extended item. The only example I could find is the Chart item, but that's way too complicated.

Does anyone know how this is supposed to work?

hvbtup avatar Nov 11 '22 12:11 hvbtup

I decided to give up trying to support the usual events (onCreate in particular).

But without the ability to use scripting events, I think it is not good enough to meet users' expectations (IMHO this also applies to the RotatedTextItem).

Thus I'll withdraw this PR.

Anyone who understands the internals of the scripting better than me may try to continue this work.

It is possible to create a QR Code without the plugin as follows:

The idea is to use a dynamic Image item and Javascript (most of which should go into a separate *.js library, preferrably). We also need the ZXing libraries (core-3.5.0.jar and javase-3.5.0.jar) which have to be added to the Reports Class Path so that they can be accessed from Javascript at design time and at run time.

The following script should be in a *.js library referenced by the report. The second best solution would be to put it into the initialize event of the report.

var barcode = {

/**
 * Generate image data for a QR code (2D) barcode representation of the given text.
 * Create the image width the given width and height (in pixel units), which
 * should be big enough to contain the whole barcode and usually should be equal
 * (a QR code is usually a square).
 * Watch out not to crop the code!
 *
 * The margin can be given in QR code squares (not pixels as with width and height).
 * The default value is 4.
 *
 * QR code offers several error correction levels:
 * - barcode.qrErrorCorrectionLevel.L: low ------>  7% of codewords can be restored
 * - barcode.qrErrorCorrectionLevel.M: medium ---> 15% of codewords can be restored
 * - barcode.qrErrorCorrectionLevel.Q: quartile -> 25% of codewords can be restored
 * - barcode.qrErrorCorrectionLevel.H: high -----> 30% of codewords can be restored
 *
 * The default error correction level is L (low).
 *
 * If you don't want UTF-8 to be used for encoding, you can give an alternative
 * character set (e.g. "iso-8859-1").
 */
qrCode: function (text, width, height, margin, error_correction_level, character_set) {
    var margin                 = (typeof(margin)                 == "undefined") ? 4                             : margin;
    var error_correction_level = (typeof(error_correction_level) == "undefined") ? this.qrErrorCorrectionLevel.L : error_correction_level;
    var character_set          = (typeof(character_set)          == "undefined") ? "utf-8"                       : character_set;

    return this.qrCodeNoDefaults(text, width, height, margin, error_correction_level, character_set);
},

/**
 * Generate image data for a QR code (2D) barcode representation of the given text.
 * Create the image width the given width and height (in pixel units), which
 * should be big enough to contain the whole barcode and usually should be equal
 * (a QR code is usually a square).
 * Watch out not to crop the code!
 *
 * The margin can be given in QR code squares (not pixels as with width and height).
 * The default value is 4.
 *
 * QR code offers several error correction levels:
 * - barcode.qrErrorCorrectionLevel.L: low ------>  7% of codewords can be restored
 * - barcode.qrErrorCorrectionLevel.M: medium ---> 15% of codewords can be restored
 * - barcode.qrErrorCorrectionLevel.Q: quartile -> 25% of codewords can be restored
 * - barcode.qrErrorCorrectionLevel.H: high -----> 30% of codewords can be restored
 *
 * The default error correction level is L (low).
 *
 * If you don't want UTF-8 to be used for encoding, you can give an alternative
 * character set (e.g. "iso-8859-1").
 */
qrCodeNoDefaults: function (text, width, height, margin, error_correction_level, character_set) {
    var qr        = new com.google.zxing.qrcode.QRCodeWriter();
    var enc_hints = new java.util.HashMap();

    enc_hints.put(com.google.zxing.EncodeHintType.CHARACTER_SET,    character_set);
    enc_hints.put(com.google.zxing.EncodeHintType.ERROR_CORRECTION, error_correction_level);
    enc_hints.put(com.google.zxing.EncodeHintType.MARGIN,           String(margin));

}

    var matrix = qr.encode(text, com.google.zxing.BarcodeFormat.QR_CODE, width, height, enc_hints);
    var baos   = new java.io.ByteArrayOutputStream();

    com.google.zxing.client.j2se.MatrixToImageWriter.writeToStream(matrix, "PNG", baos);

    return baos.toByteArray();
},

};

Inside the report, use a dynamic image item referencing an expression like this:

barcode.qrCode(row["TEXT"], 200, 200, 4, barcode.qrErrorCorrectionLevel.M, "utf-8")

where row["TEXT"] is the text that you want to encode as QR Code. The type of the binding must be Java object.

BIRT will automatically detect that the bytes describe a PNG image.

hvbtup avatar Jan 09 '23 08:01 hvbtup