[This is one of those posts where I am going to show you something cool and useful, and then advise you that this is something you shouldn’t do. The URL in this post is undocumented and unsupported (by Tableau and by me) so if you are not comfortable with that, go no further. Here, there be dragons…]
Below is a conversation I have semi-regularly with customers:
Customer: Hey Alan! We love our dashboards and we’d like to use them in some printed materials we produce. Can we do that?
Alan: Of course you can. You just copy or export an image file and you have a nice PNG, JPG or BMP to work with. Whack that in there and away you go!
Customer: Yeah, we tried that. But the image file formats are produced at screen resolution and become fuzzy when printed as part of a document. Can we get something better?
Alan: OK – then try using a vector file format. You can export to EMF or PDF which produce nice scalable output?
Customer: Again, we tried that. It’s pretty good, but it doesn’t work well for embedded bitmap content like map backgrounds, and we can’t export to EMF from Tableau Server so we can’t automate the process very well. What else can we try?
Alan: Hmm… let me have a think about it.
[Walks over to the marketing team…]
Alan: Hey guys! How do you produce the nice looking images you use in your handouts and printed materials?
Marketing: We open them in Tableau Desktop on a Mac and take a screenshot to get a retina-resolution image.
So I started looking for a way to have Tableau produce a high resolution image in a way that could be automated, and an idea came to mind. With the new Tableau mobile applications on iOS we have offline snapshots – these are high resolution images of the dashboards/views/stories/etc. They are rendered at retina resolution so is there any way we could use these?
I started digging around and eventually I found that these applications are using a special URL to request these images:
The view ID is the internal Tableau ID from the repository. You can query it from there, or you can find it by browsing to the view in Tableau Server and then searching the HTML of the page for “current_view_id”. In Chrome, just open the developer tools (F12 or CTRL-SHIFT-I) and then CTRL-F to search:
By adjusting the :pixelratio parameter we can generate higher resolution images:
This is the standard resolution for most devices.
This is the resolution we generate automatically for retina devices.
But we can take this higher…
Much, much higher.
This allows us to create high-resolution images of our dashboards. Playing around with this I’ve discovered a few traps for young players:
- You need to be logged in to a Tableau Server session to hit this URL. If you aren’t then you get the following error message:
- If your dashboard contains maps, using a :pixelratio greater than 2 won’t help as the maps are generated at :pixelratio=1 and blown up so they become grainy. Using :pixelratio=2 tells Tableau to use the hi-dpi map tiles like we would on a retina device.
The final step was to find a way to automate the production of the images via script. Because this is an internal URL it isn’t part of the traditionally scriptable interfaces such as TABCMD or the REST API. However using cURL, a command-line URL transfer tool, and trusted authentication we can create a simple script to emulate a user logging in and then fetching an image from this URL:
REM – Obtain a trusted authentication ticket and load it into an environment variable. curl http://<server>/trusted -d "username=alan" > ticket.txt set /P ticket=<ticket.txt REM – Use the ticket to log in using any workable URL. The session cookie is persisted to a file. curl "http://<server>/trusted/%ticket%/workbook.xml" -L -c cookie.txt REM – Fetch the image file from the new URL using session data from the cookie file. curl "http://<server>/vizql/sheetimage/1?:pixelratio=2" -b cookie.txt -o image.png
Note that this requires trusted authentication to be configured with unrestricted tickets enabled.
Enjoy – but remember this is unsupported and the URL structure could change at any time. Make hay while the sun shines, friends!