Skip to content

Instantly share code, notes, and snippets.

@dumy
Last active November 3, 2023 10:50
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dumy/482d3b2c9736fc1544dd62b50778d8d9 to your computer and use it in GitHub Desktop.
Save dumy/482d3b2c9736fc1544dd62b50778d8d9 to your computer and use it in GitHub Desktop.
grafana dashboard export in pdf

Grafana dashboard export pdf

In setting dashboard go to the module link and set link from Node-Red ❤️

http://localhost:1880/grafana/${__dashboard.uid}/${__dashboard.name}

Build Status

Resulted:

Build Status

When click btton executed this flow:

In node at function it'is to need add 3 parameters:

// URL to load should be passed as first parameter const url = 'http://localhost:3000/d/' + msg.req.params.uid + '/' + msg.req.params.name +'?orgId=1&kiosk';

// Username and password (with colon separator) should be second parameter const auth_string = ':!';

// Output file name should be third parameter const outfile = '';

Build Status

After call the link resulted in pdf

Build Status

I use this node: node-red-contrib-string - https://flows.nodered.org/node/node-red-contrib-string

it simple method export from grafna in pdf,

Thank you ✌️

[{"id":"6443db385c6f693c","type":"function","z":"bba055f91ed61523","name":"exportToPDF","func":"// @ts-nocheck\n\n// const puppeteer = require('puppeteer');\nconst puppeteer = global.get(\"puppeteer\");\n// const odbc = global.get(\"odbc\");\n\n// URL to load should be passed as first parameter\nconst url = 'http://zabbix.xxx.md:3000/d/' + msg.req.params.uid + '/' + msg.req.params.name +'?orgId=1&kiosk';\n// Username and password (with colon separator) should be second parameter\n\nconst auth_string = '<username>:<password>';\n// Output file name should be third parameter\nconst outfile = '' + msg.req.params.uid+'.pdf';\n\n\n// TODO: Output an error message if number of arguments is not right or arguments are invalid\n\n// Set the browser width in pixels. The paper size will be calculated on the basus of 96dpi,\n// so 1200 corresponds to 12.5\".\nconst width_px = 1200;\n// Note that to get an actual paper size, e.g. Letter, you will want to *not* simply set the pixel\n// size here, since that would lead to a \"mobile-sized\" screen (816px), and mess up the rendering.\n// Instead, set e.g. double the size here (1632px), and call page.pdf() with format: 'Letter' and\n// scale = 0.5.\n\n// Generate authorization header for basic auth\n// @ts-ignore\nconst auth_header = 'Basic ' + new Buffer.from(auth_string).toString('base64');\n\n\n const browser = await puppeteer.launch();\n const page = await browser.newPage();\n\n // Set basic auth headers\n await page.setExtraHTTPHeaders({ 'Authorization': auth_header });\n\n // Increase timeout from the default of 30 seconds to 120 seconds, to allow for slow-loading panels\n await page.setDefaultNavigationTimeout(120000);\n\n // Increasing the deviceScaleFactor gets a higher-resolution image. The width should be set to\n // the same value as in page.pdf() below. The height is not important\n await page.setViewport({\n width: width_px,\n height: 5000,\n deviceScaleFactor: 2,\n isMobile: false\n })\n\n // Wait until all network connections are closed (and none are opened withing 0.5s).\n // In some cases it may be appropriate to change this to {waitUntil: 'networkidle2'},\n // which stops when there are only 2 or fewer connections remaining.\n await page.goto(url, { waitUntil: 'networkidle0' });\n\n // Hide all panel description (top-left \"i\") pop-up handles and, all panel resize handles\n // Annoyingly, it seems you can't concatenate the two object collections into one\n await page.evaluate(() => {\n let infoCorners = document.getElementsByClassName('panel-info-corner');\n for (el of infoCorners) { el.hidden = true; };\n let resizeHandles = document.getElementsByClassName('react-resizable-handle');\n for (el of resizeHandles) { el.hidden = true; };\n });\n\n // Get the height of the main canvas, and add a margin\n var height_px = await page.evaluate(() => {\n return document.getElementsByClassName('react-grid-layout')[0].getBoundingClientRect().bottom;\n }) + 20;\n \n const pdf = await page.pdf({\n // path: outfile,\n width: width_px + 'px',\n height: height_px + 'px',\n // format: 'A4',\n // landscape: true,\n // format: 'Letter', <-- see note above for generating \"paper-sized\" outputs\n scale: 1,\n displayHeaderFooter: false,\n margin: {\n top: 0,\n right: 0,\n bottom: 0,\n left: 0,\n },\n });\n \n await browser.close();\n\nmsg.payload = pdf;\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":710,"y":340,"wires":[["c16afcdef4d666f9"]]},{"id":"055d92ff53f6a113","type":"http in","z":"bba055f91ed61523","name":"","url":"/grafana/:uid/:name","method":"get","upload":false,"swaggerDoc":"","x":370,"y":340,"wires":[["358aef36352d4467"]]},{"id":"c16afcdef4d666f9","type":"change","z":"bba055f91ed61523","name":"Set Headers","rules":[{"t":"set","p":"headers","pt":"msg","to":"{}","tot":"json"},{"t":"set","p":"headers.content-type","pt":"msg","to":"application/pdf","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":870,"y":340,"wires":[["9f0a947e6bf771a7"]]},{"id":"9f0a947e6bf771a7","type":"http response","z":"bba055f91ed61523","name":"","x":1030,"y":340,"wires":[]},{"id":"358aef36352d4467","type":"string","z":"bba055f91ed61523","name":"replace","methods":[{"name":"replaceAll","params":[{"type":"str","value":" "},{"type":"str","value":"-"}]},{"name":"toLowerCase","params":[]}],"prop":"req.params.name","propout":"req.params.name","object":"msg","objectout":"msg","x":560,"y":340,"wires":[["6443db385c6f693c"]]}]
@karan369
Copy link

karan369 commented Dec 1, 2022

After loading show type error in node-red

TypeError: Cannot read properties of undefined (reading 'launch')

export to pdf

// URL to load should be passed as first parameter
const url = 'http://localhost:3000/d/' + msg.req.params.uid + '/' + msg.req.params.name +'orgId=1&refresh=15m';
// Username and password (with colon separator) should be second parameter

const auth_string = ' < username >:<password>';
// Output file name should be third parameter
const outfile = '';

@dumy
Copy link
Author

dumy commented Dec 7, 2022

@karan369 install in your project this packet npm i puppeteer after write in settings

this code:
functionGlobalContext: { // os:require('os'), puppeteer:require('puppeteer') },

@ikaranmali
Copy link

Hi, could you help me with the replace node, it isn't available in the manage-palette sections node-red-contrib-replace?

@dumy
Copy link
Author

dumy commented Feb 17, 2023

@ikaranmali You can find in manage-palette this node: node-red-contrib-string
Link: https://flows.nodered.org/node/node-red-contrib-string

@ikaranmali
Copy link

Thanks, it worked!
Also i had to download the new version of puppeteer@19.2.0 with new version of chromium via: node node_modules/puppeteer/install.js.

Flow works smoothly.

@dumy
Copy link
Author

dumy commented Feb 17, 2023

@ikaranmali Good job! 👍

@Tadeu240
Copy link

@karan369 instale em seu projeto este pacote npm i puppeteerdepois de escrever nas configurações

este código: functionGlobalContext: { // os:require('os'), puppeteer:require('puppeteer') },

Hello, when I click on the dashboard button (export PDF), a page opens that keeps loading infinitely, and in the workflows the message appears ("typeError: Cannot read properties of undefined (reading 'launch')")
And I don't understand how to do that...
I hope you can help me, thanks.

@Yusseiin
Copy link

@karan369 instale em seu projeto este pacote npm i puppeteerdepois de escrever nas configurações
este código: functionGlobalContext: { // os:require('os'), puppeteer:require('puppeteer') },

Hello, when I click on the dashboard button (export PDF), a page opens that keeps loading infinitely, and in the workflows the message appears ("typeError: Cannot read properties of undefined (reading 'launch')") And I don't understand how to do that... I hope you can help me, thanks.

I can help with that.
I was facing the same problem and i fixed like this
You need to install puppetter with the cmd npm i puppeteer. Than you go on your Node-red installation folder, on windows the default is "C:\Users\xxx.node-red" and you have to change the "settings.js" file modifing the functionGlobalContext like this:
functionGlobalContext: { // os:require('os'), puppeteer:require('puppeteer') }, after it will work

@fruchtee
Copy link

fruchtee commented Nov 3, 2023

Hello I am running in this ERROR:

"TypeError: Cannot read properties of undefined (reading 'launch')"

I did npm i puppeteer in my node-red-docker console, but it didnt help.

I cant configure my settings.js, because I have no clue where to find this file, and did not found any help in the web. Is anyone running into the same issue?

@fruchtee
Copy link

fruchtee commented Nov 3, 2023

Hello I am running in this ERROR:

"TypeError: Cannot read properties of undefined (reading 'launch')"

I did npm i puppeteer in my node-red-docker console, but it didnt help.

I cant configure my settings.js, because I have no clue where to find this file, and did not found any help in the web. Is anyone running into the same issue?

I even hardcoded the Parameters to:

const url = 'http://192.168.16.250:3000/d/ab151208-341c-42ca-9c9e-40cf27ddb930/test?orgId=1&kiosk';

const auth_string = 'admin:kafka';

const outfile = 'test.pdf';

and placed an Inject infront of the exportToPDF Code

@fruchtee
Copy link

fruchtee commented Nov 3, 2023

Hello I am running in this ERROR:

"TypeError: Cannot read properties of undefined (reading 'launch')"

I did npm i puppeteer in my node-red-docker console, but it didnt help.

I cant configure my settings.js, because I have no clue where to find this file, and did not found any help in the web. Is anyone running into the same issue?

I found the settings.js and edited it to functionGlobalContext: { // os:require('os'), puppeteer:require('puppeteer') },

still have the same Error

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment