My main goal is to have all the Image flowables on a page to act as though they are clickable links. In order to do this, I would create a canvas.linkRect() and place it over the rendered Image. Here's an example of how I use canvas.linkRect():
canvas.linkURL(
url='url_goes_here',
rect=(x1, y1, x2, y2), #(x1, y1) is the bottom left coordinate of the rectangle, (x2, y2) is the top right
thickness=0, relative=1
)
After looking in the BaseDocTemplate class, I found a method called afterFlowable(self, flowable). I overrode that method and called dir() on the flowable passed in, resulting in this:
['__call__', '__doc__', '__init__', '__module__', '_doctemplateAttr',
'_drawOn', '_fixedHeight', '_fixedWidth', '_frameName', '_hAlignAdjust',
'_showBoundary', '_traceInfo', 'action', 'apply', 'draw', 'drawOn', 'encoding',
'getKeepWithNext', 'getSpaceAfter', 'getSpaceBefore', 'hAlign', 'height',
'identity', 'isIndexing', 'locChanger', 'minWidth', 'split', 'splitOn', 'vAlign',
'width', 'wrap', 'wrapOn', 'wrapped']
It has a width and height attribute I could use to determine how big the linkRect() should be (what x2 and y2 should be), but no information on where the flowable starts (what should x1 and y1 be?).
If all else fails, I thought of somehow pairing a Frame and an Image Flowable together since a Frame has the information I want to create a linkRect(). However, it seems it would be a hassle to know when and how to order a list of Frames with it's respective list of Flowables, on top of having to know exactly where to put those Frames for Images. Is there another way to achieve this or is it not possible?
Thanks!
After working on this all day today, I finally figured out a nice way to do this! Here's how I did it for anyone else who would like this feature of hyperlinked Image flowables in their PDFs.
Basically, reportlab.platypus.flowables
has a class called Flowable
that Image
inherits from. Flowable has a method called drawOn(self, canvas, x, y, _sW=0)
that I override in a new class I created called HyperlinkedImage
.
from reportlab.platypus import Image
class HyperlinkedImage(Image, object):
# The only variable I added to __init__() is hyperlink. I default it to None for the if statement I use later.
def __init__(self, filename, hyperlink=None, width=None, height=None, kind='direct', mask='auto', lazy=1):
super(HyperlinkedImage, self).__init__(filename, width, height, kind, mask, lazy)
self.hyperlink = hyperlink
def drawOn(self, canvas, x, y, _sW=0):
if self.hyperlink: # If a hyperlink is given, create a canvas.linkURL()
x1 = self.hAlignAdjust(x, _sW) # This is basically adjusting the x coordinate according to the alignment given to the flowable (RIGHT, LEFT, CENTER)
y1 = y
x2 = x1 + self._width
y2 = y1 + self._height
canvas.linkURL(url=self.hyperlink, rect=(x1, y1, x2, y2), thickness=0, relative=1)
super(HyperlinkedImage, self).drawOn(canvas, x, y, _sW)
Now instead of creating a reportlab.platypus.Image as your image flowable, use the new HyperlinkedImage instead :)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With