PDF from dashboard

Hello there!
need your help!

How we can data in pdf format as exactly shown on the dashboard?
can we get grid table written in template node as pdf?
is it possible to do such thing?

try

node-red-contrib-pdfmake

it has got build in examples also

Might be worth looking at this thread as it might give you some ideas of using the pdfmake node...

1 Like

PDFmake is for creating PDF's direct from data. It isn't for outputting a Dashboard to PDF.

If you want to output to PDF, either use PDFmake with the origin data or use your browser to save/print to PDF depending on the OS.

Better still, get people to use the web page directly and save everyone the hassle of working with PDF's. :grin:

i believe the OP wants the data in pdf format, just as it is shown on dashboard.
but i do agree, why make a pdf when you can see the same thing in dashboard. but i do convert few of my reports in pdf for e-mail circulation and record keeping.

1 Like

OK, I didn't quite read it that way but OK.

I'm deep into trying to get our organisation to stop using so many PDF's - or Word documents and PowerPoints for that matter! So I may be somewhat skewed in my viewpoint!

PDF's have very poor accessibility and we rightly regularly get hauled over the coals for producing so many of the wretched things. They are also a pain to use.

(You might have also noticed a while back that I shared an example that showed using uibuilder in a similar way to PDFmake for producing HTML-based reports. Urm, did I mention that my thinking might be a bit skewed! :grin: )

2 Likes

I am attaching SS and flow of my table. In the table, there is some fix data, and some will be come from flow. I have used grid table.

Now, I am stuck at, how can I adjust data for PDF in a same manner using function node or anything and then convert it to pdf?

Please help me Geniuses
Screenshot (71)

[{"id":"fc50e996.d6dc98","type":"ui_template","z":"d79ec1d.70ac04","group":"765ef6a9.5846b8","name":"Grid table","order":0,"width":"25","singleBrowser":false,"height":"32","format":"<!DOCTYPE html>\n<html>\n<head>\n<style>\n\n\n.grid-container {\n  display: grid;\n  justify-content: center;\n  align-content: center;\n  grid-template-columns:30px 400px 100px  100px 100px 100px 100px 100px 100px  100px;\n  grid-template-rows: 40px 40px 40px 40px 40px 40px 40px 40px 40px;\n  gap: 5px;\n  background-color: #2196F3;\n  padding: 20px;\n}\n\n.grid-container > div {\n  background-color: rgba(255, 255, 255, 0.8);\n  text-align: center;\n  padding: 5px 0;\n  font-size: 20px;\n}\n\n.item3 {\n  grid-column: 3 / span 8;\n}\n\n.item6 {\n  grid-column: 3 / span 8;\n}\n\n.item9 {\n  grid-column: 3 / span 8;\n}\n\n.item12 {\n  grid-column: 3 / span 8;\n}\n\n.item13 {\n  grid-area: 5 / 1 / 9 / 2;\n  }\n.item14 {\n  grid-area: 5 / 2 / 9 / 3;\n}\n\n.item16 {\n  grid-column: 4 / span 2;\n}\n\n.item17 {\n  grid-column: 6 / span 2;\n}\n\n.item18 {\n  grid-column: 8 / span 2;\n}\n\n.item21 {\n  grid-column: 4 / span 2;\n}\n\n.item28 {\n  grid-column: 4 / span 2;\n}\n\n.item35 {\n  grid-column: 4 / span 2;\n}\n\n.item41 {\n  grid-area: 9 / 1 / 15 / 2;\n}\n\n.item42 {\n  grid-area: 9 / 2 / 12 / 3;\n}\n\n\n.item43 {\n  grid-column: 3 / span 8;\n}\n\n.item44 {\n  grid-column: 3 / span 6;\n}\n\n.item45 {\n  grid-column: 9 / span 2;\n}\n\n.item46 {\n  grid-column: 3 / span 8;\n}\n\n.item47 {\n  grid-area: 12 / 2 / 15 / 3;\n}\n\n.item62 {\n  grid-area: 15 / 1 / 21 / 2;\n}\n\n.item63 {\n  grid-area: 15 / 2 / 21 / 3;\n}\n\n.item112 {\n  grid-area: 21 / 1 / 23 / 2;\n}\n\n.item113 {\n  grid-area: 21 / 2 / 23 / 3;\n}\n\n.item63 {\n  grid-area: 15 / 2 / 21 / 3;\n}\n\n.item132 {\n  grid-column: 3 / span 8;\n}\n\n.item133 {\n  grid-area: 24 / 1 / 30 / 2;\n}\n\n.item134 {\n  grid-area: 24 / 2 / 30 / 3;\n}\n\n.item136 {\n  grid-column: 4 / span 2;\n}\n\n.item143 {\n  grid-column: 4 / span 2;\n}\n\n.item150 {\n  grid-column: 4 / span 2;\n}\n\n.item157 {\n  grid-column: 4 / span 2;\n}\n\n.item164 {\n  grid-column: 4 / span 2;\n}\n\n.item171 {\n  grid-column: 4 / span 2;\n}\n\n.item179 {\n  grid-column: 3 / span 8;\n}\n\n</style>\n</head>\n<body>\n\n\n\n<div class=\"grid-container\">\n  <div class=\"item1\"> </div>\n  <div class=\"item2\"> </div>\n  <div class=\"item3\"> </div>  \n  <div class=\"item4\"> </div>\n  <div class=\"item5\"> </div>\n  <div class=\"item6\"> </div>\n  <div class=\"item7\"> </div>\n  <div class=\"item8\"> </div>  \n  <div class=\"item9\"> </div>\n  <div class=\"item10\"> </div>\n  <div class=\"item11\"> </div>\n  <div class=\"item12\"> </div>\n  <div class=\"item13\"> </div>\n  <div class=\"item14\"> </div>\n  <div class=\"item15\"> </div>\n  <div class=\"item16\"> </div>\n  <div class=\"item17\"> </div>\n  <div class=\"item18\"> </div>\n  <div class=\"item19\"> </div>\n  <div class=\"item20\">   </div>\n  <div class=\"item21\"> </div>\n  <div class=\"item22\">   </div>\n  <div class=\"item23\"> </div>\n   <div class=\"item25\">  </div>\n  <div class=\"item26\"> </div> \n  <div class=\"item27\">1</div>\n  <div class=\"item28\"> </div>  \n  <div class=\"item29\"> </div>\n  <div class=\"item30\"> </div>\n  <div class=\"item31\"> </div>\n  <div class=\"item32\"> </div>\n  <div class=\"item33\"> </div>\n  \n  <div class=\"item34\">2</div>\n  <div class=\"item35\"> </div>  \n  <div class=\"item36\"> </div>\n  <div class=\"item37\"> </div>\n  <div class=\"item38\"> </div>\n  <div class=\"item39\"> </div>\n  <div class=\"item40\"> </div>\n  \n  <div class=\"item41\">6</div>\n  <div class=\"item42\">   </div>\n  \n  <div class=\"item43\"> </div>\n  <div class=\"item44\"> </div>\n  <div class=\"item45\"> </div>\n  <div class=\"item46\"> </div>\n  <div class=\"item47\"> </div>\n  \n  <div class=\"item48\"> </div>\n  <div class=\"item49\"> </div>\n  <div class=\"item50\"> </div>\n  <div class=\"item51\"> </div>\n  <div class=\"item52\"> </div>\n  <div class=\"item53\"> </div>  \n  <div class=\"item52\"> </div>\n  <div class=\"item53\">     </div>\n  \n  <div class=\"item48\"> </div>\n  <div class=\"item49\"> </div>\n  <div class=\"item50\"> </div>\n  <div class=\"item51\"> </div>\n  <div class=\"item52\"> </div>\n  <div class=\"item53\"> </div>  \n  <div class=\"item52\"> </div>\n  <div class=\"item53\"> </div>\n  \n  <div class=\"item54\"> </div>\n  <div class=\"item55\"> </div>\n  <div class=\"item56\"> </div>\n  <div class=\"item57\"> </div>\n  <div class=\"item58\"> </div>\n  <div class=\"item59\"> </div>  \n  <div class=\"item60\"> </div>\n  <div class=\"item61\"> </div>\n  \n  \n  <div class=\"item62\">7</div>\n  <div class=\"item63\">  </div>\n   <div class=\"item64\"> </div>\n   <div class=\"item65\"> </div>\n  <div class=\"item66\"> </div>\n  <div class=\"item67\"> </div>\n  <div class=\"item68\"> </div>\n  <div class=\"item69\"> </div>\n  <div class=\"item70\"> </div>\n  <div class=\"item71\"> </div>\n  \n  <div class=\"item72\"> </div>\n  <div class=\"item73\">  </div>\n  <div class=\"item74\"> </div>\n  <div class=\"item75\"> </div>\n  <div class=\"item76\"> </div>\n  <div class=\"item77\"> </div>\n  <div class=\"item78\"> </div>\n  <div class=\"item79\"> </div>\n\n  <div class=\"item80\"> </div>\n  <div class=\"item81\"> </div>\n  <div class=\"item82\"> </div>\n  <div class=\"item83\"> </div>\n  <div class=\"item84\"> </div>\n  <div class=\"item85\"> </div>\n  <div class=\"item86\"> </div>\n  <div class=\"item87\"> </div>\n  \n  <div class=\"item88\">2</div>\n  <div class=\"item89\"> </div>\n  <div class=\"item90\"> </div>\n  <div class=\"item91\"> </div>\n  <div class=\"item92\"> </div>\n  <div class=\"item93\"> </div>\n  <div class=\"item94\"> </div>\n  <div class=\"item95\"> </div>\n  \n  <div class=\"item96\">3</div>\n  <div class=\"item97\"> </div>\n  <div class=\"item98\"> </div>\n  <div class=\"item99\"> </div>\n  <div class=\"item100\"> </div>\n  <div class=\"item101\"> </div>\n  <div class=\"item102\"> </div>\n  <div class=\"item103\"> </div>\n  \n  <div class=\"item104\">4</div>\n  <div class=\"item105\"> </div>\n  <div class=\"item106\"> </div>\n  <div class=\"item107\"> </div>\n  <div class=\"item108\"> </div>\n  <div class=\"item109\"> </div>\n  <div class=\"item110\"> </div>\n  <div class=\"item111\"> </div>\n\n  <div class=\"item112\">8</div>\n  <div class=\"item113\"> </div>\n  <div class=\"item114\">1</div>\n  <div class=\"item115\"> </div>\n  <div class=\"item116\">-</div>\n  <div class=\"item117\">  </div>\n  <div class=\"item118\"> </div>\n  <div class=\"item119\"> </div>\n  <div class=\"item120\"> </div>\n  <div class=\"item121\"> </div>\n  \n  <div class=\"item122\"> </div>\n  <div class=\"item123\"> </div>\n  <div class=\"item124\"> </div>\n  <div class=\"item125\">  </div>\n  <div class=\"item126\"> </div>\n  <div class=\"item127\"> </div>\n  <div class=\"item128\"> </div>\n  <div class=\"item129\"> </div>\n\n\n  <div class=\"item130\">9</div>\n  <div class=\"item131\"> </div>\n  <div class=\"item132\"> </div>\n  \n  \n  <div class=\"item133\">10</div>\n  <div class=\"item134\"> </div>\n  <div class=\"item135\"> </div>\n  <div class=\"item136\">  </div>\n  <div class=\"item137\">  </div>\n  <div class=\"item138\"> </div>\n  <div class=\"item139\"> </div>\n  <div class=\"item140\"> </div>\n  <div class=\"item141\"> </div>\n  \n  <div class=\"item142\">1</div>\n  <div class=\"item143\">  </div>\n  <div class=\"item144\"> </div>\n  <div class=\"item145\"> </div>\n  <div class=\"item146\"> </div>\n  <div class=\"item147\"> </div>\n  <div class=\"item148\"> </div>\n  \n  <div class=\"item149\">2</div>\n  <div class=\"item150\">   </div>\n  <div class=\"item151\"> </div>\n  <div class=\"item152\"> </div>\n  <div class=\"item153\"> </div>\n  <div class=\"item154\"> </div>\n  <div class=\"item155\"> </div>\n  \n  <div class=\"item156\">3</div>\n  <div class=\"item157\">  </div>\n  <div class=\"item158\"> </div>\n  <div class=\"item159\"> </div>\n  <div class=\"item160\"> </div>\n  <div class=\"item161\"> </div>\n  <div class=\"item162\"> </div>\n  \n  <div class=\"item163\">4</div>\n  <div class=\"item164\">  </div>\n  <div class=\"item165\"> </div>\n  <div class=\"item166\"> </div>\n  <div class=\"item167\"> </div>\n  <div class=\"item168\"> </div>\n  <div class=\"item169\"> </div>\n  \n  <div class=\"item170\">5</div>\n  <div class=\"item171\">  </div>\n  <div class=\"item172\"> </div>\n  <div class=\"item173\"> </div>\n  <div class=\"item174\"> </div>\n  <div class=\"item175\"> </div>\n  <div class=\"item176\"> </div>\n  \n  <div class=\"item177\">11</div>\n  <div class=\"item178\"> </div>\n  <div class=\"item179\"> </div>\n</div>\n\n</body>\n</html>\n","storeOutMessages":true,"fwdInMessages":true,"templateScope":"local","x":660,"y":500,"wires":[[]],"_type":"node"},{"id":"765ef6a9.5846b8","type":"ui_group","z":"","name":"Closing,Opening and use data for Current Month","tab":"e5757a65.dac708","order":6,"disp":true,"width":"32","collapse":false,"_type":"config"},{"id":"e5757a65.dac708","type":"ui_tab","z":"","name":"Flowmeter","icon":"dashboard","publicAccess":"true","fmAccess":"none","fmAccessType":"private","assetType":"","asset":"","assetName":"","assetText":"","image":"","description":"","hideTitleBar":false,"_type":"config"}]

Here maybe lies a solution.

NOTE! - I don't use dashboard, so not sure what is/not possible, so this might not work for you, but it's all I have.

I have set this to landscape for this example

  1. include a reference to this browser based library
    https://cdnjs.cloudflare.com/ajax/libs/html2pdf.js/0.10.1/html2pdf.bundle.min.js

  2. Run this code (say on a click of a button)
    element is the target div/element that you want to render to PDF

   function savePDF() {
	const PDFWorker = html2pdf();
	const element = document.getElementById('MetaDataContent');
	const opt = {
		margin: [5, 0, 5, 0],
		filename: 'MyPDF.pdf',
		image: { type: 'jpeg', quality: 0.3 },
		html2canvas: { scale: 2.0 },
		jsPDF: { orientation: 'landscape' },
		pagebreak: {
			mode: ['avoid-all']
		}
	};

	PDFWorker.set(opt)
		.from(element)
		.save()
}

I used this in our official device support database that I maintain - unrelated, but a good example of its use.

Link to source web page https://devices.zwave-js.io/?jumpTo=0x0086:0x0003:0x0062:0.0

Click on Save PDF

EDIT
The dashboard uses a dynamic DOM - so you will need to 'inspect' the main DOM element to ascertain its selector path

2 Likes

That does, of course, turn the table into a JPG that is embedded in the PDF - which is even less accessible and pretty much prevents anyone from easily copying any data back out (which might be good or bad depending on your use-case).

I just hope that none of your users have accessibility issues - for example, if they are partially or non-sighted, it would, I believe, be useless to them.

And just a reminder that accessibility is a legal requirement in many countries.

1 Like

Oh! its fisher price indeed :nerd_face:

And agreed, if copyable data is required - not the solution.
It retains the layout well - just access to the text content is prevented.

It will works well for graphs/charts - but not so much tabular data as the text not being copyable

1 Like

This topic was automatically closed 60 days after the last reply. New replies are no longer allowed.