All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.codecrete.qrbill.generator.QRBill Maven / Gradle / Ivy

There is a newer version: 3.3.1
Show newest version
//
// Swiss QR Bill Generator
// Copyright (c) 2017 Manuel Bleichenbacher
// Licensed under MIT License
// https://opensource.org/licenses/MIT
//
package net.codecrete.qrbill.generator;

import net.codecrete.qrbill.canvas.ByteArrayResult;
import net.codecrete.qrbill.canvas.Canvas;
import net.codecrete.qrbill.canvas.PDFCanvas;
import net.codecrete.qrbill.canvas.PNGCanvas;
import net.codecrete.qrbill.canvas.SVGCanvas;

import java.io.IOException;

/**
 * Generates Swiss QR bill payment part.
 * 

* Can also validate the bill data and encode and decode the text embedded in the QR code. *

*/ public class QRBill { /** * The width of an A4 sheet in portrait orientation, in mm * * @see OutputSize#A4_PORTRAIT_SHEET */ public static final double A4_PORTRAIT_WIDTH = 210; /** * The height of an A4 sheet in portrait orientation, in mm * * @see OutputSize#A4_PORTRAIT_SHEET */ public static final double A4_PORTRAIT_HEIGHT = 297; /** * The width of a QR bill (payment part and receipt), in mm * * @see OutputSize#QR_BILL_ONLY */ public static final double QR_BILL_WIDTH = 210; /** * The height of a QR bill (payment part and receipt), in mm * * @see OutputSize#QR_BILL_ONLY */ public static final double QR_BILL_HEIGHT = 105; /** * The width of the output format with extra space for horizontal separator line * (payment part and receipt plus space for line and scissors), in mm * * @see OutputSize#QR_BILL_EXTRA_SPACE */ public static final double QR_BILL_WITH_HORI_LINE_WIDTH = 210; /** * The height of the output format with extra space for horizontal separator line * (payment part and receipt plus space for line and scissors), in mm * * @see OutputSize#QR_BILL_EXTRA_SPACE */ public static final double QR_BILL_WITH_HORI_LINE_HEIGHT = 110; /** * The width of the QR code, in mm * * @see OutputSize#QR_CODE_ONLY */ public static final double QR_CODE_WIDTH = 46; /** * The height of the QR code, in mm * * @see OutputSize#QR_CODE_ONLY */ public static final double QR_CODE_HEIGHT = 46; private QRBill() { // do not instantiate } /** * Validates and cleans the bill data. *

* The validation result contains the error and warning messages (if any) and * the cleaned bill data. *

*

* For details about the validation result, see Bill data * validation *

* * @param bill bill data * @return validation result */ public static ValidationResult validate(Bill bill) { return Validator.validate(bill); } /** * Generates a QR bill (payment part and receipt) or QR code as an SVG image or PDF document. *

* If the bill data is not valid, a {@link QRBillValidationError} is * thrown, which contains the validation result. For details about the * validation result, see Bill data * validation *

*

* The graphics format is specified with {@code bill.getFormat().setGraphicsFormat(...)}. * This method only supports the generation of SVG images and PDF files. For other graphics * formats (in particular PNG), use {@link #draw} *

* * @param bill the bill data * @return the generated QR bill (as a byte array encoded in the specified graphics format) * @throws QRBillValidationError thrown if the bill data does not validate * @see #draw */ public static byte[] generate(Bill bill) { try (Canvas canvas = createCanvas(bill.getFormat())) { validateAndGenerate(bill, canvas); return ((ByteArrayResult)canvas).toByteArray(); } catch (IOException e) { throw new QRBillGenerationException(e); } } /** * Draws the QR bill (payment part and receipt) or QR code for the specified bill data onto the specified canvas. *

* The QR bill or code are drawn at position (0, 0) extending to the top and to the right. * Typically, the position (0, 0) is the bottom left corner of the canvas. *

*

* This methods ignores the formatting properties {@code bill.getFormat().getFontFamily()} * and {@code bill.getFormat().getGraphicsFormat()}. * They can be set when the canvas instance passed to this method is created. *

*

* If the bill data does not validate, a {@link QRBillValidationError} is * thrown, which contains the validation result. For details about the * validation result, see Bill data * validation *

*

* The canvas will be initialized with {@code Canvas#setupPage} and it will be * closed before returning the generated QR bill *

* * @param bill the bill data * @param canvas the canvas to draw to * @throws QRBillValidationError thrown if the bill data does not validate */ public static void draw(Bill bill, Canvas canvas) { try { validateAndGenerate(bill, canvas); } catch (IOException e) { throw new QRBillGenerationException(e); } } /** * Draws the separator line(s) to the specified canvas. *

* The separator lines are drawn assuming that the QR bill starts at position (0, 0) * and extends the top and right. So position (0, 0) should be in the bottom left corner. *

*

* This method allows to add separator lines to an existing QR bill, * e.g. on to an archived QR bill document. *

* * @param separatorType type of separator lines * @param withHorizontalLine {@code true} if both the horizontal or vertical separator should be drawn, * {@code false} for the vertical separator only * @param canvas the canvas to draw to */ public static void drawSeparators(SeparatorType separatorType, boolean withHorizontalLine, Canvas canvas) { BillFormat format = new BillFormat(); format.setSeparatorType(separatorType); format.setOutputSize(withHorizontalLine ? OutputSize.QR_BILL_EXTRA_SPACE : OutputSize.QR_BILL_ONLY); Bill bill = new Bill(); bill.setFormat(format); BillLayout layout = new BillLayout(bill, canvas); try { layout.drawBorder(); } catch (IOException e) { throw new QRBillGenerationException(e); } } private static void validateAndGenerate(Bill bill, Canvas canvas) throws IOException { ValidationResult result = Validator.validate(bill); Bill cleanedBill = result.getCleanedBill(); if (result.hasErrors()) throw new QRBillValidationError(result); if (bill.getFormat().getOutputSize() == OutputSize.QR_CODE_ONLY) { QRCode qrCode = new QRCode(cleanedBill); qrCode.draw(canvas, 0, 0); } else { BillLayout layout = new BillLayout(cleanedBill, canvas); layout.draw(); } } /** * Encodes the text embedded in the QR code from the specified bill data. *

* The specified bill data is first validated and cleaned. *

*

* If the bill data does not validate, a {@link QRBillValidationError} is * thrown, which contains the validation result. For details about the * validation result, see Bill data * validation *

* * @param bill the bill data to encode * @return the QR code text * @throws QRBillValidationError thrown if the bill data does not validate */ public static String encodeQrCodeText(Bill bill) { ValidationResult result = Validator.validate(bill); Bill cleanedBill = result.getCleanedBill(); if (result.hasErrors()) throw new QRBillValidationError(result); return QRCodeText.create(cleanedBill); } /** * Decodes the text embedded in the QR code and fills it into a {@link Bill} * data structure. *

* A subset of the validations related to embedded QR code text is run. It the * validation fails, a {@link QRBillValidationError} is thrown, which contains * the validation result. See the error messages marked with a dagger in * Bill data * validation. *

* * @param text the text to decode * @return the decoded bill data * @throws QRBillValidationError thrown if the bill data does not validate */ public static Bill decodeQrCodeText(String text) { return QRCodeText.decode(text); } @SuppressWarnings("deprecation") private static Canvas createCanvas(BillFormat format) throws IOException { double drawingWidth; double drawingHeight; // define page size switch (format.getOutputSize()) { case QR_BILL_ONLY: drawingWidth = QR_BILL_WIDTH; drawingHeight = QR_BILL_HEIGHT; break; case QR_BILL_EXTRA_SPACE: case QR_BILL_WITH_HORIZONTAL_LINE: drawingWidth = QR_BILL_WITH_HORI_LINE_WIDTH; drawingHeight = QR_BILL_WITH_HORI_LINE_HEIGHT; break; case QR_CODE_ONLY: drawingWidth = QR_CODE_WIDTH; drawingHeight = QR_CODE_HEIGHT; break; case A4_PORTRAIT_SHEET: default: drawingWidth = A4_PORTRAIT_WIDTH; drawingHeight = A4_PORTRAIT_HEIGHT; break; } Canvas canvas; switch (format.getGraphicsFormat()) { case SVG: canvas = new SVGCanvas(drawingWidth, drawingHeight, format.getFontFamily()); break; case PDF: canvas = new PDFCanvas(drawingWidth, drawingHeight); break; case PNG: canvas = new PNGCanvas(drawingWidth, drawingHeight, format.getResolution(), format.getFontFamily()); break; default: throw new QRBillGenerationException("Invalid graphics format specified"); } return canvas; } /** * Returns this library's version * * @return version in semantic versioning format (major.minor.patch). */ public static String getLibraryVersion() { return QRBill.class.getPackage().getImplementationVersion(); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy