6 ms·
Just recently I had to put together a web-based UI for editing vector graphics (clothing tags) and export them to pdf for printing. In order to avoid writing an
by jonstaab 9y ago
Just recently I had to put together a web-based UI for editing vector graphics (clothing tags) and export them to pdf for printing. In order to avoid writing and maintaining two separate codebases, I re-used the client side code as my rendering code.
So I ended up with a server serving the editor frontend, as well as api endpoints that would use puppeteer and headless chrome to make a request (to itself) to load the frontend, import a given label file, render it, take a screenshot and save it to a file, then reply to the api request with the contents. So kind of a recursive api.
I had so much fun with this but I still can't believe I had to write my own svg editor and bake my own pdf generation and merging code to get the job done. It should not require two languages (node and python) and a headless browser to get the job done.
- mrskitch 9y agoI’ve literally just helped someone do similar in their own product. If you run into issues with puppeteer’s blank or missing pages of a screenshot (for high-res images), just forgo that for canvases base64 export. It’ll save you a world of hurt!
- mlevental 9y agowut. why did you do this? why didn't you just handle all of it in the frontend? jspdf makes PDFs in browser.
- jonstaab 9y agoI would have loved to, but one of the sticking points was that the label file had to be serialized, saved, and later interpolated with data from a bunch of different records, which is why I used svg over canvas, wrote my own editor, etc. jsPDF seems great for imperatively generating a pdf, but not for editing/loading template files. Plus, since the pdf generation had to happen server side, I would have needed a headless browser anyway. It's super weird, and I've been over it from every direction but I don't know how I could have done it differently.
- mlevental 9y ago>Plus, since the pdf generation had to happen server side this is exactly my question: why did the pdf generation need to be server side?
- jonstaab 9y ago1. Client creates a custom label and we store it in s3 2. They select x inventory items + click print 3. We retrieve and send the label file + inventory data to a service that interpolates the data into each template, renders to pdf, merges them, and forwards it to our printing service. We certainly could do the work on the client, but they're making this request in a context where neither the label nor the libraries need to be loaded; in fact, in our server-side implementation, it could be done with a single api call. Doing it all client side would strongly couple the client to the technology. Also, we re-used this api in two applications, one of which never loaded the editor (along with its dependencies). TLDR; a weird hack was better than violating separation of conerns.
- mlevental 9y ago>forwards it to our printing service. is the printing service a real physical service? anyway i'm doing basically exactly this same thing except all client side (i send the serialized "label file" and data to the client) but printing is being done using the user's printer
- jonstaab 9y agoYep, the printing service is a third-party api (PrintNode) that routes the request to one of any number of desktop clients. The reason we did it this way is 1. we have a web app so we can't print directly to their printer without a print dialog, and 2. we want to print to potentially a different device than the user is on.
- camtarn 9y agoHa. My team implemented something very similar. We were writing a browser-based animation editor, and we needed to render a 'film strip' of frames. But we were targeting tablets, and loading a new canvas filled with heavyweight vector assets for each frame took forever. Since the animations were auto-saved to the server, it proved quicker just to spin up the app in a headless browser on the server, render all the frames, and have the client download them!