You completely nerd-sniped me with this topic - I definitely shouldn’t have spent as much time on this as I did. But, this is actually possible with the existing reporting module. We’ll definitely have to see about adding this capability in a better way.
Basically, the workaround I came up with relies on the fact that objects in reporting can be copied to the clipboard and show up as XML representations of the underlying Java object. So, to use this (extremely janky) workaround:
0. Paste the script below into the script console and execute it. Nothing will happen - that’s intentional.
- Copy the desired component (I’ve only really tested text shapes) to the clipboard.
- Go back to the script console, and in the interactive interpreter, run
addURLToClipboardObject(<someURL>)
. To link to a specific page, useaddURLToClipboardObject("Page:3")
. You can also usePage:Next
andPage:Back
. - Click back to the reporting workspace, and specifically click into the editor/visible page. Then paste your modified object.
If everything went correctly, the hyperlink should be active on the preview tab:
And, without further ado, the hacky monstrosity that will do all this. It’s pretty unlikely this will break any existing report, but it may throw all kinds of errors into the console. I would recommend copying your report to a new project, going through this process to add the links, and once you’ve verified it works copy the report back to your original project.
def addURLToClipboardObject(url):
from java.awt import Toolkit
from java.awt.datatransfer import DataFlavor, Transferable
from java.io import ByteArrayInputStream
from java.lang import String
import re
class MockReportMillClipboard(Transferable):
RMDataFlavor = DataFlavor("application/reportmill", "ReportMill Shape Data")
def __init__(self, data):
self.data = String(data).getBytes()
def isDataFlavorSupported(self, flavor):
return flavor == self.RMDataFlavor
def getTransferData(self, flavor):
if flavor == self.RMDataFlavor:
return ByteArrayInputStream(self.data)
def getTransferDataFlavors(self):
return self.RMDataFlavor.getTransferDataFlavors()
clip = Toolkit.getDefaultToolkit().getSystemClipboard()
dataflavor = None
for df in clip.getAvailableDataFlavors():
if df.mimeType == 'application/x-java-serialized-object; class=java.lang.String':
dataflavor = df
break
if dataflavor:
data = clip.getData(dataflavor)
regex = r"<text(.*)>"
subst = r'<text\g<1> url="%s">' % url
result = re.sub(regex, subst, data, re.MULTILINE)
print "Added URL to clipboard object"
clip.setContents(MockReportMillClipboard(result), None)