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:
- by name (using the color module)
- by red/green/blue (additive, RGB) value
- by cyan/magenta/yellow/darkness (subtractive, CMYK)
- by gray level.
- 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:
- 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.
- 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)
- 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).
|