2

I'm trying to use the reportlab library to write an 'annotation' on a pdf. I've successfully written new data to a pdf using reportlab, but I can't find any information on how I would create an annotation.

When I say annotation I am referring to TCPDF's annotate function. This creates a clickable and movable text object in the pdf.

https://tcpdf.org/examples/example_036/

There has to be a way to do this in python, but so far I haven't been able to find any information.

I've looked at this post and the related links posted in the accepted answer.

Add text to existing PDF document in Python

I've seen this tool for using php in python, but I can't get it to work correctly and It doesn't seem to have any support.

https://github.com/dnet/ppcg/blob/master/tcpdf_example.py

When I run the example I get a unreadable pdf with the text shown below:

<?
include('tcpdf/config/lang/eng.php');
include('tcpdf/tcpdf.php');
$v0 = new TCPDF('PDF_PAGE_ORIENTATION', 'PDF_UNIT', 'PDF_PAGE_FORMAT', 'true', 'UTF-8', 'false');
$v0->setFontSubsetting(False);
$v0->setAuthor('VSzA');
$v0->setCreator('PPCG');
$v0->setTitle('TCPDF in Python!?');
$v0->setPrintHeader(False);
$v0->setMargins(10, 10);
$v0->AddPage();
$v0->SetFont('dejavusans', 'B', 12);
$v0->Cell(0, 0, 'Hello Python');
$v0->Ln();
$v2 = $v0->GetX();
$v1 = $v0->GetY();
$v0->setXY(30, 30);
$v0->Cell(0, 0, 'GOTOs are bad');
$v3 = $v1 + 2.5;
$v0->setXY($v2, $v3);
$v0->Cell(0, 0, 'I can has PHP variables');
$v0->Output();
?>

This looks like the correct php code to create a pdf using TCPDF, but the code is being saved to the pdf file instead of being ran.

The conclusion I've came to as of now is to just send all my data from a python script over to a http server using php and creating my pdf on the server using TCPDF, and then sending the new pdf back to my python script to serve it to the end user. This just sounds unefficient so I'd prefer not to do it this way.

Any help would be appreciated! -Jake

Community
  • 1
  • 1
Jake Randall
  • 57
  • 1
  • 9

1 Answers1

1

There is good news and bad news about annotation in , the good news is it is possible to annotate in . Bad news it is a pain in the ass as it isn't documented properly and it limits your options pretty hard.

The function you will need canavas.textAnnotation which is used in the following way:

canvas.textAnnotation("Your content", Rect=[x_begin, y_begin, x_end, y_end], relative=1)

This will place the annotation at (x_begin, y_begin) relative to the current canvas, or if you turn off relative relative to the bottom left corner.

You might notice that the Reportlab annotations look different from those adobe generates, this has to do with the SubType of the annotation which in Reportlab is fixed to Text while Adobe uses something else (See 8.4.5 of the PDF reference).

This can be changed by overloading the Canvas object and the Annotation object but doing so is a lot of work for just changing an icon. So I wouldn't recommend it.

B8vrede
  • 4,432
  • 3
  • 27
  • 40
  • This is really helpful, for the annotation I'm looking to have it display a number instead of that annotation sticky note object. I cant post pictures yet but imagine a simple square with a number inside of it, that's still movable. Is this possible? In TCPDF it was pretty simple – Jake Randall Aug 12 '16 at 18:11
  • It should be possible, as it is basically the `canavas.freeTextAnnotation` function that is in the source code, but I can't get it to work right now. :( (note: DA = default appearance string) – B8vrede Aug 12 '16 at 18:59
  • I couldn't get it to work either. I tried adding my own dictionary fields to the freeTextAnnotation function too and got no result. I was able to just change the subtype of textannotation to "/FreeText" and it works for me now. Now my next question would be how do you format the color if you can't change the 'DA' string? The normal setfillcolor and setstrokecolor don't work for annotations. – Jake Randall Aug 12 '16 at 19:21
  • Also, is there anyway to use layers with reportlab? – Jake Randall Aug 12 '16 at 19:59
  • Sorry for the late response, but most likely you're reaching the limits of Reportlab.. The only solution I could think of is adding `DA` to the permitted dictionary values, but again that would involve creating new version of all kinds of objects.. – B8vrede Aug 18 '16 at 10:26
  • Regarding the layers question, I don't know. But my best guess is no based on the lack of responses on this https://pairlist2.pair.net/pipermail/reportlab-users/2012-October/010500.html – B8vrede Aug 18 '16 at 10:29