This past summer I had a heck of a time getting ReactFlow to export as a PFD in the browser, especially in one step - but we got there. BUT! The result relied on rasterizing the content as a PNG - which didn't graphically scale well, and it turned out a lot of our diagrams are extremely big and detailed, so if you can't preserve clarity on zoom in, the game is kind of lost. (And also, they tended to be huuuge files, many Mbs when the corresponding SVG was tiny, like 100K)
Well, I went a little crazy trying to find different methods of getting the export to work. I learned that SVGs are kind of unevenly supported in a lot of ways in browsers and toolkits, and that many tools that will capture DOM stuff and export it as PDF do so by rasterizing it... even if you try to export an SVG, it will turn into a pixel'd mess close up. Here is a table I made to track my progress and keep track of what permutations I had already done:
(Note, you don't see options for downloading an svg (like from html-to-image toSvg) directly as a link - that's because one absolutely firm requirement was to wrap the reactflow content in a frame, providing metadata about the content (people and place involved, company logo, etc))
So you can see this table almost makes its own little map (maybe I should have used ReactFlow to diagram it out! ) as many of the steps would have to build on previous steps.
Well, I went a little crazy trying to find different methods of getting the export to work. I learned that SVGs are kind of unevenly supported in a lot of ways in browsers and toolkits, and that many tools that will capture DOM stuff and export it as PDF do so by rasterizing it... even if you try to export an SVG, it will turn into a pixel'd mess close up. Here is a table I made to track my progress and keep track of what permutations I had already done:
(Note, you don't see options for downloading an svg (like from html-to-image toSvg) directly as a link - that's because one absolutely firm requirement was to wrap the reactflow content in a frame, providing metadata about the content (people and place involved, company logo, etc))
So you can see this table almost makes its own little map (maybe I should have used ReactFlow to diagram it out! ) as many of the steps would have to build on previous steps.
| # | Method | Result | Notes |
|---|---|---|---|
| A | KendoPDF PDFExport (wrap ReactFlow directly) | PDF w/o Edge lines | (also likely not zoomable) |
| B | html-to-image toSvg => dataUrl => jsPdf.addImage | Fail | (unsupported image type) |
| C | html-to-image toPng => dataUrl => jsPdf.addImage | PDF (not zoomable) | (also large file size) |
| D | html-to-image toSvg => dataUrl | SVG content | intermediate step w/ huge content size) |
| E | D => download .svg via link | Zoomable .SVG file | not desired goal file type, and large file |
| F | E => .SVG file to browser print dialog to .PDF | PDF (zoomable) | also good file size… but how to automate |
| G | E => .SVG file to various online tools and .NET approaches | Fail | (Many pdf/svg wranglers cannot cope with E SVG) |
| H | D => on-page SVG | SVG content | Intermediate step |
| I | H => KendoPDF PDFExport | PDF (not zoomable) | (seems like KendoPDF always rasterizes) |
| J | H => jsPdf w/ svg2pdf .svg() | Fail | Can’t deal with D SVG (but smaller files work) |
| K | E => >SVG file to svgo optimizer | Fail | “Error: Pseudo-elements are not supported by css-select” |
| L | H => html2pdf.js | PDF (not zoomable) | renderizes (interestingly is wrapper to html-to-canvas and jsPdf) |
| M | html-to-image toSvg(of Scaled Flow Elem) => dataUrl | Large PNG, no frame | reverting to Download Image - React Flow for scaling |
| N | D => new window, button to open up print dialog | Scalable PDF! | manual steps to hit “print” and “print to pdf” |
So sadly, there wasn't a perfect end result. The only thing I found that could reliably output a clean PDF was the browser's own "Print" dialog, with its save to pdf action. And that worked a treat in making a tiny PDF that was totally scalable.
So the solution is a button that does a "print preview" mode (the frame and content) and fires off the print dialog, though we weren't able to automate past that point (adjusting scaling, destination as to PDF and not a printer, etc)
So the solution is a button that does a "print preview" mode (the frame and content) and fires off the print dialog, though we weren't able to automate past that point (adjusting scaling, destination as to PDF and not a printer, etc)
No comments:
Post a Comment