schoero / swissqrbill

Swiss QR Bill generation in Node.js and browsers
MIT License
156 stars 29 forks source link

Add support to render as SVG #343

Closed uwolfer closed 2 years ago

uwolfer commented 3 years ago

It would be nice to render the QR Bill to an SVG which would allow simple display in-browser (instead of using a roundtrip with something like PDF.js).

Do you see an easy way to do it?

I've found a non-maintained lib called svgkit which might could help.

schoero commented 3 years ago

I don't think there is an easy and fast way to implement this, that would actually make sense. To render just an SVG file, you wouldn't need PDFKit, on which this library relies on heavily. An SVG file would also not support all the features, and probably only be able to generate the QR-Bill part, and not a complete invoice. I may be going to explore this idea in the next few days/weeks, but I think this might just be out of scope.

uwolfer commented 3 years ago

One random idea would be to generate the QR-Bill part as an SVG (as far as I've seen you are already doing this for the QR code), and then embed this SVG into the PDF. For my usecase, that would be perfectly fine, as I'd only need the bill part as an SVG. I've seen the following (non-open-source) implementation which also does generate the QR-Bill part as an SVG: https://generator.qrmodul.ch/

schoero commented 3 years ago

Unfortunately you can't just throw in a whole SVG file because it only works with SVG paths. And since the QR-Bill is mostly text, this basically means that the entire rendering has to be recreated using SVG. This wouldn't be too hard to do, but requires a lot of refactoring to be able to reuse internal functions and support tree shaking.

I definitely want to try this, but this may take a while to finish.

schoero commented 2 years ago

Hey @uwolfer

It was a lot more work than I have expected, but v3 with SVG support is almost ready. I've released a beta version on npm that you can install using npm i swissqrbill@3.0.0-beta.4.

If you were using swissqrbill previously, you may need to change the way the library is imported. Please take a look at the importing the library section in the new readme for further details.

In addition of that, there are a few breaking changes. Take a look at the changelog for details.

With v3, you can create a QR Bill as an SVG using the following code:

import { SVG } from "swissqrbill/svg";

const data = {
  currency: "CHF",
  amount: 1199.95,
  reference: "210000000003139471430009017",
  creditor: {
    name: "Robert Schneider AG",
    address: "Rue du Lac 1268",
    zip: 2501,
    city: "Biel",
    account: "CH4431999123000889012",
    country: "CH"
  },
  debtor: {
    name: "Pia-Maria Rutschmann-Schnyder",
    address: "Grosse Marktgasse 28",
    zip: 9400,
    city: "Rorschach",
    country: "CH"
  }
};

const svg = new SVG(data);

//-- Node.js

console.log(svg.toString());

//-- Browser (example)

window.onload = () => {
  const svg = new SVG(data);
  document.body.appendChild(svg.element)
}

I'll be testing the new version in my own implementations over the next few days, and if all goes well, I intend to release v3 by the end of the week.

If you have a chance to test it in the meantime, I'd appreciate your feedback.

uwolfer commented 2 years ago

@schoero Wow, nice work! Just took a short glimpse, and I like it so far. Thanks.

schoero commented 2 years ago

SwissQRBill v3.0.0 with support for SVG rendering is now released on npm.