ReportLab FAQ

Please send suggested FAQs and requests to the users list, or to info@reportlab.com if you are not on that list.

 

1. General information and availability

    1.1 What is ReportLab?
    1.2 How do I get it?
    1.3 Licensing
    1.3.1 Licensing for contributions
    1.4 System requirements
    1.5 Platforms (Unices, Windows, MacOS)
    1.6 Installation
    1.7 Is there a mailing list?
    1.8 How stable is it?
    1.9 Where is the documentation? How do I learn my way around it?
    1.10 Does ReportLab toolkit work on Java platform?

2. Programming with ReportLab

  2.1 General

    2.1.1 I've never programmed in Python before. Is there a Python tutorial?
    2.1.2 How do I make "Hello World!" PDF file?
    2.1.3 Can I use any images
    2.1.4 What colors can I use and how?
    2.1.5 Does reportlab support reading PDFs?

  2.2 Pdfgen

    2.2.1 What is Pdfgen?

  2.3 Platypus

    2.3.1 What is Platypus?
    2.3.2 How do I create a simple document using Platypus?

  2.4 Graphics and charts

    2.4.1 What is ReportLab Graphics?

  2.5 Pythonpoint

    2.5.1 What is PythonPoint?

  2.6 Fonts

    2.6.1 What fonts can be used with ReportLab?
    2.6.2 How can I use other fonts?

3. Known Bugs and Limitations

    3.1 What do I do if I find a bug?


Answers

1. General information and availability

  1.1 What is ReportLab?

ReportLab Inc. is a company making Open Source and commercial products for generating dynamic documents and graphics. The ReportLab Toolkit is our main Open Source library; it is a collection of open source Python language modules organized and supported by ReportLab. They are primarily concerned with automated methods for generating Portable Document Format (PDF) files, but there is also a cross-platform vector graphics library able to generate bitmap and vector charts and drawings.


  1.2 How do I get the ReportLab Toolkit?

If you have not already done so, you will need to install the Python language from www.python.org. If you want to include bitmap images, you should also install the Python Imaging Library (www.pythonware.com). Thereafter, you need the latest stable version of the reportlab package from our downloads page.

For instructions on how to check out ReportLab's latest code, see the Subversion page.

We also provide a daily snapshot distribution with the latest development code. These packages are available on the downloads page.

  1.3 Licensing

The ReportLab toolkit and most of our other Open Source tools are available under the BSD license. This means that you can basically do anything you want with it, including using it in a commercial package. (We used to use the Python license, but the Python license became historically complicated. We chose the BSD license because it was the shortest and most readable Open Source license).

pyRXP, our XML parser, is under the GNU General Public License. This is because the RXP parser underneath it is under this license. If you want to use pyRXP in a closed source project, you have to negotiate with us.


  1.3.1 Licensing for contributions

What is the deal with copyright/licensing of things contributed to reportlab? In particular, for something to eventually make its way into the core reportlab libraries, does one need to assign copyright over to ReportLab Inc, or simply release it under the same style of license as reportlab?

The open source is under a BSD compatible license. Anything contributed presumably would be better under that. We're fairly sure that other open source licenses would be acceptable provided they don't effect the toolkit itself.

  1.4 System requirements

A full source Python installation requires about 50Mb of disk space, and a Python process needs about 4Mb of memory. Compact distributions as small as 1-2Mb are possible. On top of this, ReportLab toolkit and all dependent libraries could use between 2 and 10 Mb (assuming you build all the manuals and run all the tests).

Memory allocation depends heavily on the type of document. A book-type job hundreds of pages long might allocate 100Mb of memory. We do very demanding financial documents with 6 point text about 20 pages long in 2-3 seconds on a Pentium 1000; these allocate about 9Mb per job.


  1.5 Platforms (Unices, Windows, MacOS)

The ReportLab toolkit runs everywhere Python runs, which means everywhere with an ANSI C compiler.


  1.6 Installation

See the first chapter of the ReportLab User Guide here.


  1.7 Is there a mailing list?

The group mailing list is at http://two.pairlist.net/mailman/listinfo/reportlab-users.


  1.8 How stable is it?

The library has been in production use for over 5 years with some of the world's largest financial institutions, delivering real-time documents and charts; and has been widely deployed by members of our user group in a wide variety of environments.

New features are sometimes introduced on an experimental basis and might contain bugs or undergo changes in the first few release cycles.

For an impartial opinion on stability, feel free to join our user group and ask them directly.


  1.9 Where is the documentation? How do I learn my way around it?

There is preliminary documentation in the Reference Manual and User Guide

The best place to start is by looking at the output of the test scripts, testpdfgen.pdf and testplatypus.pdf, which are also available on this site. These are 'mini-tutorials' as well as tests, and the source code makes it clear how to create any effects you want.

After looking at that, check out the demos directories, and look at the scripts which produced them.


  1.10 Does ReportLab toolkit work on Java platform?

At the moment, the only way to work with ReportLab toolkit using Java is to use Java implementation of python called Jython (www.jython.org). Currently we are in the testing phase and it seems that most of ReportLab toolkit features do work under Jython. However, things that need OS specific features, like os.chdir() will not work, because they're not supported by Java. This is especially true for the set of test suites.
ReportLab toolkit has been tested under Sun's J2SDK 1.3.1. It is known that under J2SDK 1.4.0_01 test_pdfbase_ttfonts.py fails horribly with an outOfMemory exception, probably caused by a JVM bug. For information on how to install ReportLab toolkit to work with Jython, see the user guide.


2. Programming with ReportLab

  2.1 General

    2.1.1 I've never programmed in Python before. Is there a Python tutorial?

The best place to start learning Python is http://www.python.org/doc/Newbies.html.


    2.1.2 How do I make "Hello World!" PDFfile?

The pdfgen package is the lowest level interface for generating PDF documents and the best place to start learning. A pdfgen program is essentially a sequence of instructions for "painting" a document onto a sequence of pages. The interface object which provides the painting operations is the pdfgen canvas.
The canvas should be thought of as a sheet of white paper with points on the sheet identified using Cartesian (X,Y) coordinates which by default have the (0,0) origin point at the lower left corner of the page. Furthermore the first coordinate x goes to the right and the second coordinate y goes up, by default.
A simple example program that uses a canvas follows:

		from reportlab.pdfgen import canvas
		from reportlab.lib.units import cm
		c = canvas.Canvas("hello.pdf")
		c.drawString(9*cm, 22*cm, "Hello World!")
		c.showPage()
		c.save()

This example outputs 'hello.pdf' file in the current directory.


    2.1.3 Can I use any images?

To use images other than JPEGs, you need to have the Python Imaging Library http://www.pythonware.com installed. And to compress pages (which is not done by default), you need zlib. zlib is included on Windows, but is an optional extension on Unix and Mac; you need to rebuild Python with it included. We'll try to add better installation instructions shortly.

It is possible that some scripts which need images may error at present if PIL is not present; we aim to tighten this up so that it degrades gracefully when these extensions are not present.


    2.1.4 What colors can I use and how?

There are five ways to specify colors in pdfgen:

  1. by name (using the color module)
  2. by red/green/blue (additive, RGB) value
  3. by cyan/magenta/yellow/darkness (subtractive, CMYK)
  4. by gray level.
  5. by using class PCMYKColor from reportlab.lib.colors module. It is similar to CMYKColor, but instead of being 0-1 based, the values are range from 0 to 100.

The colors function below exercises the first four methods.

		def colors(canvas):
			 from reportlab.lib import colors
			 from reportlab.lib.units import inch
			 black = colors.black
			 y = x = 0; dy=inch*3/4.0; dx=inch*5.5/5; w=h=dy/2
			 rdx=(dx-w)/2; rdy=h/5.0; texty=h+2*rdy
			 canvas.setFont("Helvetica",10)
			 for [namedcolor, name] in (
				  [colors.lavenderblush, "lavenderblush"],
				  [colors.lawngreen, "lawngreen"],
				  [colors.lemonchiffon, "lemonchiffon"],
				  [colors.lightblue, "lightblue"],
				  [colors.lightcoral, "lightcoral"]):
			 canvas.setFillColor(namedcolor)
			 canvas.rect(x+rdx, y+rdy, w, h, fill=1)
			 canvas.setFillColor(black)
			 canvas.drawCentredString(x+dx/2, y+texty, name)
			 x = x+dx
			 y = y + dy; x = 0
			 for rgb in [(1,0,0), (0,1,0), (0,0,1),
						  (0.5,0.3,0.1), (0.4,0.5,0.3)]:
				 r,g,b = rgb
				 canvas.setFillColorRGB(r,g,b)
			  canvas.rect(x+rdx, y+rdy, w, h, fill=1)
			  canvas.setFillColor(black)
			  canvas.drawCentredString(x+dx/2, y+texty,
									   "r%s g%s b%s"%rgb)
			  x = x+dx
		  y = y + dy; x = 0
		  for cmyk in [(1,0,0,0), (0,1,0,0), (0,0,1,0),
								  (0,0,0,1), (0,0,0,0)]:
			  c,m,y1,k = cmyk
			  canvas.setFillColorCMYK(c,m,y1,k)
			  canvas.rect(x+rdx, y+rdy, w, h, fill=1)
			  canvas.setFillColor(black)
			  canvas.drawCentredString(x+dx/2, y+texty,
									"c%s m%s y%s k%s"%cmyk)
			  x = x+dx
		  y = y + dy; x = 0
		  for gray in (0.0, 0.25, 0.50, 0.75, 1.0):
			  canvas.setFillGray(gray)
			  canvas.rect(x+rdx, y+rdy, w, h, fill=1)

The RGB or additive color specification follows the way a computer screen adds different levels of the red, green, or blue light to make any color, where white is formed by turning all three lights on full (1,1,1).
The CMYK or subtractive method follows the way a printer mixes three pigments (cyan, magenta, and yellow) to form colors. Because mixing chemicals is more difficult than combining light there is a fourth parameter for darkness. For example a chemical combination of the CMY pigments generally never makes a perfect black -- instead producing a muddy color -- so, to get black printers don't use the CMY pigments but use a direct black ink. Because CMYK maps more directly to the way printer hardware works it may be the case that colors specified in CMYK will provide better fidelity and better control when printed.

Also in addition to all the above CMYKColors have three extra constructor possibilities:

  1. spotName (default None)
    This is a printer friendly name that may be used under certain circumstances to select an ink etc. This is normally only useful when we're doing EPS graphics to allow separation of colour plates.
  2. density (default 1 or 100 PCMYKColor)
    The CMYK model allows us to put more or less ink on the paper without changing the color. 0 means no ink, 1 (or 100) means slap it on maximally. This feature allows a three plate print say black and two named spot colors to have many variants of the individual colors without changing the definition of the colors.
    CMYKColor(0.5,0.25,0.25,0,density=1) is not treated the same by the printer as CMYKColor(1.0,0.5,0.5,0,density=0.5) as there are no spot names. Since densities have to lie below 1 to get the required effect, you need something like CMYKColor(1.0,0.5,0.5,0,spotName='dingo_ink',density=0.5)
  3. knockout (default None)
    In printing it's important to realize that the second colour goes on top of the first without erasing what's underneath. Since we may need to have this erasing mode (especially for colour separation EPS) we have the knockout parameter.
    A (P)CMYKColor with knockout set will attempt to erase what's underneath it when drawn (irrespective of the ink order). This may in fact cause registration problems when black knockout lines are drawn onto other colors effectively we create a white line first and when the black line doesn't quite hit the right place (because of mis-positioning) we see the white line partially covered by the black.

    2.1.5 Does reportlab support reading PDFs?

No, the Open Source package doesn't do this.

That's what our commercial PageCatcher product does. There are very simple Python functions/methods to add in pages from other documents, and some text extraction and info-gathering APIs. It's main goal is to accelerate development of reporting projects by letting you reuse content developed in other tools.

But we don't have anything free.

(This is normally only shipped as part of our "Enterprise Solutions" framework, but we're happy to make it available for more modest prices to members of our Developer Network, provided it is not a massive use. Let us know what you want to use it for if you are interested in a price).


  2.2 Pdfgen

    2.2.1 What is Pdfgen?

The pdfgen package is the lowest level interface for generating PDF documents. A pdfgen program is essentially a sequence of instructions for "painting" a document onto a sequence of pages. The interface object which provides the painting operations is the pdfgen.Canvas.

  2.3 Platypus

    2.3.1 What is Platypus?

Platypus stands for "Page Layout and Typography Using Scripts". It is a high level page layout library which lets you programmatically create complex documents with a minimum of effort.
The design of Platypus seeks to separate "high level" layout decisions from the document content as much as possible. Thus, for example, paragraphs are constructed using paragraph styles and pages are constructed using page templates with the intention that hundreds of documents with thousands of pages can be reformatted to different style specifications with the modifications of a few lines in a single shared file which contains the paragraph styles and page layout specifications.


    2.3.2 How do I create a simple document using Platypus?

The overall design of Platypus can be thought of has having several layers.
Top down, these are:

  • DocTemplates - the outermost container for the document.
  • PageTemplates - specifications for layouts of pages of various kinds
  • Frames - specifications of regions in pages that can contain flowing text or graphics.
  • Flowables - text or graphic elements that should be "flowed into the document (i.e. things like images, paragraphs and tables, but not things like page footers or fixed page graphics).
  • pdfgen.Canvas - the lowest level which ultimately receives the painting of the document from the other layers.

Consider the following code sequence which provides a very simple "hello world" example for Platypus.

		from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer
		from reportlab.lib.styles import getSampleStyleSheet
		from reportlab.rl_config import defaultPageSize
		from reportlab.lib.units import inch
		PAGE_HEIGHT=defaultPageSize[1]
		PAGE_WIDTH=defaultPageSize[0]
		styles = getSampleStyleSheet()

First we import some constructors, some paragraph styles and other conveniences from other modules.

		Title = "Hello world"
		pageinfo = "platypus example"
		def myFirstPage(canvas, doc):
			canvas.saveState()
			canvas.setFont('Times-Bold',16)
			canvas.drawCentredString(PAGE_WIDTH/2.0,
									PAGE_HEIGHT-108, Title)
			canvas.setFont('Times-Roman',9)
			canvas.drawString(inch, 0.75 * inch,
							"First Page / %s" % pageinfo)
			canvas.restoreState()

We define the fixed features of the first page of the document with the function above.

		def myLaterPages(canvas, doc):
			canvas.saveState()
			canvas.setFont('Times-Roman', 9)
			canvas.drawString(inch, 0.75 * inch,
					"Page %d %s" % (doc.page, pageinfo))
			canvas.restoreState()

Since we want pages after the first to look different from the first we define an alternate layout for the fixed features of the other pages. Note that the two functions above use the pdfgen level canvas operations to paint the annotations for the pages.

		def go():
			 doc = SimpleDocTemplate("phello.pdf")
			 Story = [Spacer(1,2*inch)]
			 style = styles["Normal"]
			 for i in range(100):
				bogustext = ("Paragraph number %s. " % i) *20
				p = Paragraph(bogustext, style)
				Story.append(p)
				Story.append(Spacer(1,0.2*inch))
			 doc.build(Story, onFirstPage=myFirstPage,
						   onLaterPages=myLaterPages)

Finally, we create a story and build the document. Note that we are using a "canned" document template here, which comes pre-built with page templates. We are also using a pre-built paragraph style. We are only using two types of flowables here -- Spacers and Paragraphs. The first Spacer ensures that the Paragraphs skip past the title string.

To see the output of this example program run the module docs/userguide/examples.py (from the ReportLab docs distribution) as a "top level script". The script interpretation python examples.py will generate the Platypus output phello.pdf.

  2.4 Graphics and charts

    2.4.1 What is ReportLab Graphics?

ReportLab Graphics is one of the sub-packages to the ReportLab library. It is a integrated part of the ReportLab toolkit that allows you to use its powerful charting and graphics features to improve your PDF forms and reports.


  2.5 Pythonpoint

    2.5.1 What is PythonPoint?

PythonPoint is a library for creating presentation slides. PythonPoint lets you create attractive and consistent presentation slides on any platform. It is built on top of the PDFgen PDF library and the PLATYPUS Page Layout library. Essentially, it converts slides in an XML format to PDF.


    2.5.2 Where can I get Pythonpoint??

It's included in the standard distribution of the ReportLab library -- look in the reportlab/tools/pythonpoint directory.


  2.6 Fonts

    2.6.1 What fonts can be used with ReportLab?

Every copy of Acrobat Reader comes with 14 standard fonts built in. Therefore, the ReportLab PDF Library only needs to refer to these by name. If you want to use other fonts, they must be embedded in the PDF document. You also need to make sure your strings are in the same encoding as the font you have selected.

You can use the mechanism described below to include arbitrary fonts in your documents.


    2.6.2 How can I use other fonts?

Right now font-embedding relies on font description files in the Adobe AFM ('Adobe Font Metrics') and PFB ('Printer Font Binary') format. The former is an ASCII file and contains information about the characters ('glyphs') in the font such as height, width, bounding box info and other 'metrics', while the latter is a binary file that describes the shapes of the font.

Just van Rossum has kindly donated a font named LettErrorRobot-Chrome which we may use for testing and/or documenting purposes (and which you may use as well). It comes bundled with the ReportLab distribution in the directory reportlab/fonts.

In the following example locate the folder containing the test font and register it for future use with the pdfmetrics module, after which we can use it like any other standard font.

		import os
		import reportlab
		from reportlab.pdfbase import pdfmetrics
		from reportlab.pdfgen.canvas import Canvas

		folder = os.path.dirname(reportlab.__file__) +
								  os.sep + 'fonts'
		afmFile = os.path.join(folder, 'LeERC___.AFM')
		pfbFile = os.path.join(folder, 'LeERC___.PFB')
		justFace = pdfmetrics.EmbeddedType1Face(afmFile, pfbFile)
		faceName = 'LettErrorRobot-Chrome' # pulled from AFM file
		pdfmetrics.registerTypeFace(justFace)
		justFont = pdfmetrics.Font('LettErrorRobot-Chrome',
									faceName, 'WinAnsiEncoding')
		pdfmetrics.registerFont(justFont)

		canvas = Canvas('TestFonts.pdf')
		canvas.setFont('LettErrorRobot-Chrome', 32)
		canvas.drawString(10, 150, 'This should be in')
		canvas.drawString(10, 100, 'LettErrorRobot-Chrome')
		canvas.showPage()
		canvas.save()

This example outputs 'TestFonts.pdf' file in the current directory.


3. Known Bugs and Limitations

  3.1 What do I do if I find a bug?

Bug reports should posted to the mailing list (reportlab-users@reportlab.com).

Please give enough detail to adequately describe the bug - and a code snippet which illustrates it (if possible).



 

 

Documentation

Full documentation for our Open Source code

documentation page