--- a/reportlab/platypus/tables.py Thu Jul 06 12:40:38 2000 +0000
+++ b/reportlab/platypus/tables.py Thu Jul 06 12:41:47 2000 +0000
@@ -2,8 +2,8 @@
#
# ReportLab Public License Version 1.0
#
-# Except for the change of names the spirit and intention of this
-# license is the same as that of Python
+# Except for the change of names the spirit and intention of this
+# license is the same as that of Python
#
# (C) Copyright ReportLab Inc. 1998-2000.
#
@@ -31,16 +31,19 @@
#
###############################################################################
# $Log: tables.py,v $
-# Revision 1.13 2000/06/29 17:55:19 aaron_watters
+# Revision 1.14 2000/07/06 12:41:47 rgbecker
+# First try at auto sizing
+#
+# Revision 1.13 2000/06/29 17:55:19 aaron_watters
# support explicit \n line splitting in cells
-#
-# Revision 1.12 2000/06/13 13:03:31 aaron_watters
+#
+# Revision 1.12 2000/06/13 13:03:31 aaron_watters
# more documentation changes
#
-# Revision 1.11 2000/06/01 15:23:06 rgbecker
+# Revision 1.11 2000/06/01 15:23:06 rgbecker
# Platypus re-organisation
#
-# Revision 1.10 2000/05/26 09:49:23 rgbecker
+# Revision 1.10 2000/05/26 09:49:23 rgbecker
# Color fixes; thanks to J Alet
#
# Revision 1.9 2000/05/16 16:15:16 rgbecker
@@ -68,7 +71,7 @@
# Revision 1.2 2000/02/15 15:47:09 rgbecker
# Added license, __version__ and Logi comment
#
-__version__=''' $Id: tables.py,v 1.13 2000/06/29 17:55:19 aaron_watters Exp $ '''
+__version__=''' $Id: tables.py,v 1.14 2000/07/06 12:41:47 rgbecker Exp $ '''
__doc__="""
Tables are created by passing the constructor a tuple of column widths, a tuple of row heights and the data in
row order. Drawing of the table can be controlled by using a TableStyle instance. This allows control of the
@@ -86,444 +89,500 @@
_stringtype = type('')
class CellStyle(PropertySet):
- defaults = {
- 'fontname':'Times-Roman',
- 'fontsize':10,
- 'leading':12,
- 'leftPadding':6,
- 'rightPadding':6,
- 'topPadding':3,
- 'bottomPadding':3,
- 'firstLineIndent':0,
- 'color':colors.black,
- 'alignment': 'LEFT',
- 'background': (1,1,1),
- }
+ defaults = {
+ 'fontname':'Times-Roman',
+ 'fontsize':10,
+ 'leading':12,
+ 'leftPadding':6,
+ 'rightPadding':6,
+ 'topPadding':3,
+ 'bottomPadding':3,
+ 'firstLineIndent':0,
+ 'color':colors.black,
+ 'alignment': 'LEFT',
+ 'background': (1,1,1),
+ }
class TableStyle:
- def __init__(self, cmds=None):
- self._cmds = cmds
- if cmds is None:
- self._cmds = []
- def add(self, *cmd):
- self._cmds.append(cmd)
- def getCommands(self):
- return self._cmds
-
+ def __init__(self, cmds=None):
+ self._cmds = cmds
+ if cmds is None:
+ self._cmds = []
+ def add(self, *cmd):
+ self._cmds.append(cmd)
+ def getCommands(self):
+ return self._cmds
+
class Table(Flowable):
- def __init__(self, colWidths, rowHeights, data):
- if not colWidths:
- raise ValueError, "Table must have at least 1 column"
- if not rowHeights:
- raise ValueError, "Table must have at least 1 row"
- nrows = self._nrows = len(rowHeights)
- if len(data) != nrows:
- raise ValueError, "Data error - %d rows in data but %d in grid" % (len(data), nrows)
- ncols = self._ncols = len(colWidths)
- for i in range(nrows):
- if len(data[i]) != ncols:
- raise ValueError, "Not enough data points in row %d!" % i
- self._rowHeights = rowHeights
- self._colWidths = colWidths
- self._cellvalues = data
- dflt = CellStyle('<default>')
- self._cellstyles = [None]*nrows
- for i in range(nrows):
- self._cellstyles[i] = [dflt]*ncols
- self._bkgrndcmds = []
- self._linecmds = []
- height = self._height = reduce(operator.add, rowHeights, 0)
- self._rowpositions = [height] # index 0 is actually topline; we skip when processing cells
- for h in rowHeights:
- height = height - h
- self._rowpositions.append(height)
- assert height == 0
- width = 0
- self._colpositions = [0] #index -1 is right side boundary; we skip when processing cells
- for w in colWidths:
- width = width + w
- self._colpositions.append(width)
- self._width = width
- self._curweight = self._curcolor = self._curcellstyle = None
+ def __init__(self, colWidths, rowHeights, data):
+ if not colWidths:
+ raise ValueError, "Table must have at least 1 column"
+ if not rowHeights:
+ raise ValueError, "Table must have at least 1 row"
+ nrows = self._nrows = len(rowHeights)
+ if len(data) != nrows:
+ raise ValueError, "Data error - %d rows in data but %d in grid" % (len(data), nrows)
+ ncols = self._ncols = len(colWidths)
+ for i in range(nrows):
+ if len(data[i]) != ncols:
+ raise ValueError, "Not enough data points in row %d!" % i
+ self._rowHeights = rowHeights
+ self._colWidths = colWidths
+ self._cellvalues = data
+ dflt = CellStyle('<default>')
+ self._cellstyles = [None]*nrows
+ for i in range(nrows):
+ self._cellstyles[i] = [dflt]*ncols
+ self._bkgrndcmds = []
+ self._linecmds = []
+ self._curweight = self._curcolor = self._curcellstyle = None
- def setStyle(self, tblstyle):
- for cmd in tblstyle.getCommands():
- if cmd[0] == 'BACKGROUND':
- self._bkgrndcmds.append(cmd)
- elif _isLineCommand(cmd):
- self._linecmds.append(cmd)
- else:
- (op, (sc, sr), (ec, er)), values = cmd[:3] , cmd[3:]
- if sc < 0: sc = sc + self._ncols
- if ec < 0: ec = ec + self._ncols
- if sr < 0: sr = sr + self._nrows
- if er < 0: er = er + self._nrows
- for i in range(sr, er+1):
- for j in range(sc, ec+1):
- _setCellStyle(self._cellstyles, i, j, op, values)
+ def _calc(self):
+ H = self._rowHeights
+ W = self._colWidths
- def _drawLines(self):
- for op, (sc, sr), (ec, er), weight, color in self._linecmds:
- if sc < 0: sc = sc + self._ncols
- if ec < 0: ec = ec + self._ncols
- if sr < 0: sr = sr + self._nrows
- if er < 0: er = er + self._nrows
- if op == 'GRID':
- self._drawBox( (sc, sr), (ec, er), weight, color)
- self._drawInnerGrid( (sc, sr), (ec, er), weight, color)
- elif op in ('BOX', 'OUTLINE',):
- self._drawBox( (sc, sr), (ec, er), weight, color)
- elif op == 'INNERGRID':
- self._drawInnerGrid( (sc, sr), (ec, er), weight, color)
- elif op == 'LINEBELOW':
- self._drawHLines((sc, sr+1), (ec, er+1), weight, color)
- elif op == 'LINEABOVE':
- self._drawHLines((sc, sr), (ec, er), weight, color)
- elif op == 'LINEBEFORE':
- self._drawVLines((sc, sr), (ec, er), weight, color)
- elif op == 'LINEAFTER':
- self._drawVLines((sc+1, sr), (ec+1, er), weight, color)
- else:
- raise ValueError, "Unknown line style %s" % op
- self._curcolor = None
+ if None in H:
+ H = H[:] #make a copy as we'll change it
+ self._rowHeghts = H
+ while None in H:
+ i = H.index(None)
+ V = self._cellvalues[i]
+ S = self._cellstyles[i]
+ h = 0
+ for v, s in map(None, V, S):
+ if type(v) is not _stringtype: v = str(v)
+ v = string.split(v, "\n")
+ t = s.leading*len(v)+s.bottomPadding+s.topPadding
+ if t>h: h = t #record a new maximum
+ H[i] = h
- def _drawBox(self, (sc, sr), (ec, er), weight, color):
- self._drawHLines((sc, sr), (ec, sr), weight, color)
- self._drawHLines((sc, er+1), (ec, er+1), weight, color)
- self._drawVLines((sc, sr), (sc, er), weight, color)
- self._drawVLines((ec+1, sr), (ec+1, er), weight, color)
- def _drawInnerGrid(self, (sc, sr), (ec, er), weight, color):
- self._drawHLines((sc, sr+1), (ec, er), weight, color)
- self._drawVLines((sc+1, sr), (ec, er), weight, color)
- def _prepLine(self, weight, color):
- if color != self._curcolor:
- self.canv.setStrokeColor(color)
- self._curcolor = color
- if weight != self._curweight:
- self.canv.setLineWidth(weight)
- self._curweight = weight
- def _drawHLines(self, (sc, sr), (ec, er), weight, color):
- self._prepLine(weight, color)
- scp = self._colpositions[sc]
- ecp = self._colpositions[ec+1]
- for rowpos in self._rowpositions[sr:er+1]:
- self.canv.line(scp, rowpos, ecp, rowpos)
- def _drawVLines(self, (sc, sr), (ec, er), weight, color):
- self._prepLine(weight, color)
- srp = self._rowpositions[sr]
- erp = self._rowpositions[er+1]
- for colpos in self._colpositions[sc:ec+1]:
- self.canv.line(colpos, srp, colpos, erp)
+ if None in W:
+ W = W[:]
+ self._colWidths = W
+ while None in W:
+ i = W.index(None)
+ f = lambda x,i=i: operator.getitem(x,i)
+ V = map(f,self._cellvalues)
+ S = map(f,self._cellstyles)
+ w = 0
+ for v, s in map(None, V, S):
+ if type(v) is not _stringtype: v = str(v)
+ v = string.split(v, "\n")
+ t = s.leftPadding+s.rightPadding + max(map(lambda a, b=s.fontname,
+ c=s.fontsize,d=self.canv: d.stringWidth(a,b,c), v))
+ if t>w: w = t #record a new maximum
+ W[i] = w
- def wrap(self, availWidth, availHeight):
- #nice and easy, since they are predetermined size
- self.availWidth = availWidth
- return (self._width, self._height)
-
- def draw(self):
- nudge = 0.5 * (self.availWidth - self._width)
- self.canv.translate(nudge, 0)
- self._drawBkgrnd()
- self._drawLines()
- for row, rowstyle, rowpos, rowheight in map(None, self._cellvalues, self._cellstyles, self._rowpositions[1:], self._rowHeights):
- for cellval, cellstyle, colpos, colwidth in map(None, row, rowstyle, self._colpositions[:-1], self._colWidths):
- self._drawCell(cellval, cellstyle, (colpos, rowpos), (colwidth, rowheight))
+ height = self._height = reduce(operator.add, H, 0)
+ self._rowpositions = [height] # index 0 is actually topline; we skip when processing cells
+ for h in H:
+ height = height - h
+ self._rowpositions.append(height)
+ assert height == 0
+ width = 0
+ self._colpositions = [0] #index -1 is right side boundary; we skip when processing cells
+ for w in W:
+ width = width + w
+ self._colpositions.append(width)
+ self._width = width
- def _drawBkgrnd(self):
- for cmd, (sc, sr), (ec, er), color in self._bkgrndcmds:
- if sc < 0: sc = sc + self._ncols
- if ec < 0: ec = ec + self._ncols
- if sr < 0: sr = sr + self._nrows
- if er < 0: er = er + self._nrows
- color = colors.toColor(color, colors.Color(1,1,1))
- x0 = self._colpositions[sc]
- y0 = self._rowpositions[sr]
- x1 = self._colpositions[ec+1]
- y1 = self._rowpositions[er+1]
- self.canv.setFillColor(color)
- self.canv.rect(x0, y0, x1-x0, y1-y0,stroke=0,fill=1)
+ def setStyle(self, tblstyle):
+ for cmd in tblstyle.getCommands():
+ if cmd[0] == 'BACKGROUND':
+ self._bkgrndcmds.append(cmd)
+ elif _isLineCommand(cmd):
+ self._linecmds.append(cmd)
+ else:
+ (op, (sc, sr), (ec, er)), values = cmd[:3] , cmd[3:]
+ if sc < 0: sc = sc + self._ncols
+ if ec < 0: ec = ec + self._ncols
+ if sr < 0: sr = sr + self._nrows
+ if er < 0: er = er + self._nrows
+ for i in range(sr, er+1):
+ for j in range(sc, ec+1):
+ _setCellStyle(self._cellstyles, i, j, op, values)
+
+ def _drawLines(self):
+ for op, (sc, sr), (ec, er), weight, color in self._linecmds:
+ if sc < 0: sc = sc + self._ncols
+ if ec < 0: ec = ec + self._ncols
+ if sr < 0: sr = sr + self._nrows
+ if er < 0: er = er + self._nrows
+ if op == 'GRID':
+ self._drawBox( (sc, sr), (ec, er), weight, color)
+ self._drawInnerGrid( (sc, sr), (ec, er), weight, color)
+ elif op in ('BOX', 'OUTLINE',):
+ self._drawBox( (sc, sr), (ec, er), weight, color)
+ elif op == 'INNERGRID':
+ self._drawInnerGrid( (sc, sr), (ec, er), weight, color)
+ elif op == 'LINEBELOW':
+ self._drawHLines((sc, sr+1), (ec, er+1), weight, color)
+ elif op == 'LINEABOVE':
+ self._drawHLines((sc, sr), (ec, er), weight, color)
+ elif op == 'LINEBEFORE':
+ self._drawVLines((sc, sr), (ec, er), weight, color)
+ elif op == 'LINEAFTER':
+ self._drawVLines((sc+1, sr), (ec+1, er), weight, color)
+ else:
+ raise ValueError, "Unknown line style %s" % op
+ self._curcolor = None
- def _drawCell(self, cellval, cellstyle, (colpos, rowpos), (colwidth, rowheight)):
- #print "cellstyle is ", repr(cellstyle), id(cellstyle)
- if self._curcellstyle is not cellstyle:
- cur = self._curcellstyle
- if cur is None or cellstyle.color != cur.color:
- #print "setting cell color to %s" % `cellstyle.color`
- self.canv.setFillColor(cellstyle.color)
- if cur is None or cellstyle.leading != cur.leading or cellstyle.fontname != cur.fontname or cellstyle.fontsize != cur.fontsize:
- #print "setting font: %s, %s, %s" % (cellstyle.fontname, cellstyle.fontsize, cellstyle.leading)
- self.canv.setFont(cellstyle.fontname, cellstyle.fontsize, cellstyle.leading)
- self._curcellstyle = cellstyle
- #print "leading is ", cellstyle.leading, "size is", cellstyle.fontsize
- just = cellstyle.alignment
- #print "alignment is ", just
- if just == 'LEFT':
- draw = self.canv.drawString
- x = colpos + cellstyle.leftPadding
- elif just in ('CENTRE', 'CENTER'):
- draw = self.canv.drawCentredString
- x = colpos + colwidth * 0.5
- else:
- draw = self.canv.drawRightString
- x = colpos + colwidth - cellstyle.rightPadding
- y = rowpos + cellstyle.bottomPadding
- if type(cellval) is _stringtype:
- val = cellval
- else:
- val = str(cellval)
- vals = string.split(val, "\n")
- n = len(vals)-1
- leading = cellstyle.leading
- y2 = y+leading*n
- for v in vals:
- draw(x, y2, v)
- y2 = y2-leading
-
+ def _drawBox(self, (sc, sr), (ec, er), weight, color):
+ self._drawHLines((sc, sr), (ec, sr), weight, color)
+ self._drawHLines((sc, er+1), (ec, er+1), weight, color)
+ self._drawVLines((sc, sr), (sc, er), weight, color)
+ self._drawVLines((ec+1, sr), (ec+1, er), weight, color)
+ def _drawInnerGrid(self, (sc, sr), (ec, er), weight, color):
+ self._drawHLines((sc, sr+1), (ec, er), weight, color)
+ self._drawVLines((sc+1, sr), (ec, er), weight, color)
+ def _prepLine(self, weight, color):
+ if color != self._curcolor:
+ self.canv.setStrokeColor(color)
+ self._curcolor = color
+ if weight != self._curweight:
+ self.canv.setLineWidth(weight)
+ self._curweight = weight
+ def _drawHLines(self, (sc, sr), (ec, er), weight, color):
+ self._prepLine(weight, color)
+ scp = self._colpositions[sc]
+ ecp = self._colpositions[ec+1]
+ for rowpos in self._rowpositions[sr:er+1]:
+ self.canv.line(scp, rowpos, ecp, rowpos)
+ def _drawVLines(self, (sc, sr), (ec, er), weight, color):
+ self._prepLine(weight, color)
+ srp = self._rowpositions[sr]
+ erp = self._rowpositions[er+1]
+ for colpos in self._colpositions[sc:ec+1]:
+ self.canv.line(colpos, srp, colpos, erp)
+
+ def wrap(self, availWidth, availHeight):
+ self._calc()
+ #nice and easy, since they are predetermined size
+ self.availWidth = availWidth
+ return (self._width, self._height)
+
+ def draw(self):
+ nudge = 0.5 * (self.availWidth - self._width)
+ self.canv.translate(nudge, 0)
+ self._drawBkgrnd()
+ self._drawLines()
+ for row, rowstyle, rowpos, rowheight in map(None, self._cellvalues, self._cellstyles, self._rowpositions[1:], self._rowHeights):
+ for cellval, cellstyle, colpos, colwidth in map(None, row, rowstyle, self._colpositions[:-1], self._colWidths):
+ self._drawCell(cellval, cellstyle, (colpos, rowpos), (colwidth, rowheight))
+
+ def _drawBkgrnd(self):
+ for cmd, (sc, sr), (ec, er), color in self._bkgrndcmds:
+ if sc < 0: sc = sc + self._ncols
+ if ec < 0: ec = ec + self._ncols
+ if sr < 0: sr = sr + self._nrows
+ if er < 0: er = er + self._nrows
+ color = colors.toColor(color, colors.Color(1,1,1))
+ x0 = self._colpositions[sc]
+ y0 = self._rowpositions[sr]
+ x1 = self._colpositions[ec+1]
+ y1 = self._rowpositions[er+1]
+ self.canv.setFillColor(color)
+ self.canv.rect(x0, y0, x1-x0, y1-y0,stroke=0,fill=1)
+
+ def _drawCell(self, cellval, cellstyle, (colpos, rowpos), (colwidth, rowheight)):
+ #print "cellstyle is ", repr(cellstyle), id(cellstyle)
+ if self._curcellstyle is not cellstyle:
+ cur = self._curcellstyle
+ if cur is None or cellstyle.color != cur.color:
+ #print "setting cell color to %s" % `cellstyle.color`
+ self.canv.setFillColor(cellstyle.color)
+ if cur is None or cellstyle.leading != cur.leading or cellstyle.fontname != cur.fontname or cellstyle.fontsize != cur.fontsize:
+ #print "setting font: %s, %s, %s" % (cellstyle.fontname, cellstyle.fontsize, cellstyle.leading)
+ self.canv.setFont(cellstyle.fontname, cellstyle.fontsize, cellstyle.leading)
+ self._curcellstyle = cellstyle
+ #print "leading is ", cellstyle.leading, "size is", cellstyle.fontsize
+ just = cellstyle.alignment
+ #print "alignment is ", just
+ if just == 'LEFT':
+ draw = self.canv.drawString
+ x = colpos + cellstyle.leftPadding
+ elif just in ('CENTRE', 'CENTER'):
+ draw = self.canv.drawCentredString
+ x = colpos + colwidth * 0.5
+ else:
+ draw = self.canv.drawRightString
+ x = colpos + colwidth - cellstyle.rightPadding
+ y = rowpos + cellstyle.bottomPadding
+ if type(cellval) is _stringtype:
+ val = cellval
+ else:
+ val = str(cellval)
+ vals = string.split(val, "\n")
+ n = len(vals)-1
+ leading = cellstyle.leading
+ y2 = y+leading*n
+ for v in vals:
+ draw(x, y2, v)
+ y2 = y2-leading
+
# for text,
-# drawCentredString(self, x, y, text) where x is center
-# drawRightString(self, x, y, text) where x is right
-# drawString(self, x, y, text) where x is left
+# drawCentredString(self, x, y, text) where x is center
+# drawRightString(self, x, y, text) where x is right
+# drawString(self, x, y, text) where x is left
LINECOMMANDS = (
- 'GRID', 'BOX', 'OUTLINE', 'INNERGRID', 'LINEBELOW', 'LINEABOVE', 'LINEBEFORE', 'LINEAFTER', )
+ 'GRID', 'BOX', 'OUTLINE', 'INNERGRID', 'LINEBELOW', 'LINEABOVE', 'LINEBEFORE', 'LINEAFTER', )
def _isLineCommand(cmd):
- return cmd[0] in LINECOMMANDS
+ return cmd[0] in LINECOMMANDS
def _setCellStyle(cellstyles, i, j, op, values):
- new = CellStyle('<%d, %d>' % (i,j), cellstyles[i][j])
- cellstyles[i][j] = new
- if op == 'FONT':
- new.fontname = values[0]
- new.fontsize = values[1]
- elif op == 'TEXTCOLOR':
- new.color = colors.toColor(values[0], colors.Color(0,0,0))
- elif op in ('ALIGN', 'ALIGNMENT'):
- new.alignment = values[0]
- elif op == 'LEFTPADDING':
- new.leftPadding = values[0]
- elif op == 'RIGHTPADDING':
- new.rightPadding = values[0]
- elif op == 'TOPPADDING':
- new.topPadding = values[0]
- elif op == 'BOTTOMPADDING':
- new.bottomPadding = values[0]
+ new = CellStyle('<%d, %d>' % (i,j), cellstyles[i][j])
+ cellstyles[i][j] = new
+ if op == 'FONT':
+ new.fontname = values[0]
+ new.fontsize = values[1]
+ elif op == 'TEXTCOLOR':
+ new.color = colors.toColor(values[0], colors.Color(0,0,0))
+ elif op in ('ALIGN', 'ALIGNMENT'):
+ new.alignment = values[0]
+ elif op == 'LEFTPADDING':
+ new.leftPadding = values[0]
+ elif op == 'RIGHTPADDING':
+ new.rightPadding = values[0]
+ elif op == 'TOPPADDING':
+ new.topPadding = values[0]
+ elif op == 'BOTTOMPADDING':
+ new.bottomPadding = values[0]
GRID_STYLE = TableStyle(
- [('GRID', (0,0), (-1,-1), 0.25, colors.black),
- ('ALIGN', (1,1), (-1,-1), 'RIGHT')]
- )
+ [('GRID', (0,0), (-1,-1), 0.25, colors.black),
+ ('ALIGN', (1,1), (-1,-1), 'RIGHT')]
+ )
BOX_STYLE = TableStyle(
- [('BOX', (0,0), (-1,-1), 0.50, colors.black),
- ('ALIGN', (1,1), (-1,-1), 'RIGHT')]
- )
+ [('BOX', (0,0), (-1,-1), 0.50, colors.black),
+ ('ALIGN', (1,1), (-1,-1), 'RIGHT')]
+ )
LABELED_GRID_STYLE = TableStyle(
- [('INNERGRID', (0,0), (-1,-1), 0.25, colors.black),
- ('BOX', (0,0), (-1,-1), 2, colors.black),
- ('LINEBELOW', (0,0), (-1,0), 2, colors.black),
- ('LINEAFTER', (0,0), (0,-1), 2, colors.black),
- ('ALIGN', (1,1), (-1,-1), 'RIGHT')]
- )
+ [('INNERGRID', (0,0), (-1,-1), 0.25, colors.black),
+ ('BOX', (0,0), (-1,-1), 2, colors.black),
+ ('LINEBELOW', (0,0), (-1,0), 2, colors.black),
+ ('LINEAFTER', (0,0), (0,-1), 2, colors.black),
+ ('ALIGN', (1,1), (-1,-1), 'RIGHT')]
+ )
COLORED_GRID_STYLE = TableStyle(
- [('INNERGRID', (0,0), (-1,-1), 0.25, colors.black),
- ('BOX', (0,0), (-1,-1), 2, colors.red),
- ('LINEBELOW', (0,0), (-1,0), 2, colors.black),
- ('LINEAFTER', (0,0), (0,-1), 2, colors.black),
- ('ALIGN', (1,1), (-1,-1), 'RIGHT')]
- )
+ [('INNERGRID', (0,0), (-1,-1), 0.25, colors.black),
+ ('BOX', (0,0), (-1,-1), 2, colors.red),
+ ('LINEBELOW', (0,0), (-1,0), 2, colors.black),
+ ('LINEAFTER', (0,0), (0,-1), 2, colors.black),
+ ('ALIGN', (1,1), (-1,-1), 'RIGHT')]
+ )
LIST_STYLE = TableStyle(
- [('LINEABOVE', (0,0), (-1,0), 2, colors.green),
- ('LINEABOVE', (0,1), (-1,-1), 0.25, colors.black),
- ('LINEBELOW', (0,-1), (-1,-1), 2, colors.green),
- ('ALIGN', (1,1), (-1,-1), 'RIGHT')]
- )
+ [('LINEABOVE', (0,0), (-1,0), 2, colors.green),
+ ('LINEABOVE', (0,1), (-1,-1), 0.25, colors.black),
+ ('LINEBELOW', (0,-1), (-1,-1), 2, colors.green),
+ ('ALIGN', (1,1), (-1,-1), 'RIGHT')]
+ )
def test():
- rowheights = (24, 16, 16, 16, 16)
- rowheights2 = (24, 16, 16, 16, 30)
- colwidths = (50, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32)
- data = (
- ('', 'Jan', 'Feb', 'Mar','Apr','May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'),
- ('Mugs', 0, 4, 17, 3, 21, 47, 12, 33, 2, -2, 44, 89),
- ('T-Shirts', 0, 42, 9, -3, 16, 4, 72, 89, 3, 19, 32, 119),
- ('Key Ring', 0,0,0,0,0,0,1,0,0,0,2,13),
- ('Hats', 893, 912, '1,212', 643, 789, 159, 888, '1,298', 832, 453, '1,344','2,843')
- )
- data2 = (
- ('', 'Jan', 'Feb', 'Mar','Apr','May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'),
- ('Mugs', 0, 4, 17, 3, 21, 47, 12, 33, 2, -2, 44, 89),
- ('T-Shirts', 0, 42, 9, -3, 16, 4, 72, 89, 3, 19, 32, 119),
- ('Key Ring', 0,0,0,0,0,0,1,0,0,0,2,13),
- ('Hats\nLarge', 893, 912, '1,212', 643, 789, 159, 888, '1,298', 832, 453, '1,344','2,843')
- )
- styleSheet = getSampleStyleSheet()
- lst = []
- lst.append(Paragraph("Tables", styleSheet['Heading1']))
- lst.append(Paragraph(__doc__, styleSheet['BodyText']))
- lst.append(Paragraph("The Tables (shown in different styles below) were created using the following code:", styleSheet['BodyText']))
- lst.append(Preformatted("""
- colwidths = (50, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32)
- rowheights = (24, 16, 16, 16, 16)
- data = (
- ('', 'Jan', 'Feb', 'Mar','Apr','May', 'Jun',
- 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'),
- ('Mugs', 0, 4, 17, 3, 21, 47, 12, 33, 2, -2, 44, 89),
- ('T-Shirts', 0, 42, 9, -3, 16, 4, 72, 89, 3, 19, 32, 119),
- ('Key Ring', 0,0,0,0,0,0,1,0,0,0,2,13),
- ('Hats', 893, 912, '1,212', 643, 789, 159,
- 888, '1,298', 832, 453, '1,344','2,843')
- )
- t = Table(colwidths, rowheights, data)
- """, styleSheet['Code'], dedent=4))
- lst.append(Paragraph("""
- You can then give the Table a TableStyle object to control its format. The first TableStyle used was
- created as follows:
- """, styleSheet['BodyText']))
- lst.append(Preformatted("""
+ rowheights = (24, 16, 16, 16, 16)
+ rowheights2 = (24, 16, 16, 16, 30)
+ colwidths = (50, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32)
+ data = (
+ ('', 'Jan', 'Feb', 'Mar','Apr','May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'),
+ ('Mugs', 0, 4, 17, 3, 21, 47, 12, 33, 2, -2, 44, 89),
+ ('T-Shirts', 0, 42, 9, -3, 16, 4, 72, 89, 3, 19, 32, 119),
+ ('Key Ring', 0,0,0,0,0,0,1,0,0,0,2,13),
+ ('Hats', 893, 912, '1,212', 643, 789, 159, 888, '1,298', 832, 453, '1,344','2,843')
+ )
+ data2 = (
+ ('', 'Jan', 'Feb', 'Mar','Apr','May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'),
+ ('Mugs', 0, 4, 17, 3, 21, 47, 12, 33, 2, -2, 44, 89),
+ ('T-Shirts', 0, 42, 9, -3, 16, 4, 72, 89, 3, 19, 32, 119),
+ ('Key Ring', 0,0,0,0,0,0,1,0,0,0,2,13),
+ ('Hats\nLarge', 893, 912, '1,212', 643, 789, 159, 888, '1,298', 832, 453, '1,344','2,843')
+ )
+ styleSheet = getSampleStyleSheet()
+ lst = []
+ lst.append(Paragraph("Tables", styleSheet['Heading1']))
+ lst.append(Paragraph(__doc__, styleSheet['BodyText']))
+ lst.append(Paragraph("The Tables (shown in different styles below) were created using the following code:", styleSheet['BodyText']))
+ lst.append(Preformatted("""
+ colwidths = (50, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32)
+ rowheights = (24, 16, 16, 16, 16)
+ data = (
+ ('', 'Jan', 'Feb', 'Mar','Apr','May', 'Jun',
+ 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'),
+ ('Mugs', 0, 4, 17, 3, 21, 47, 12, 33, 2, -2, 44, 89),
+ ('T-Shirts', 0, 42, 9, -3, 16, 4, 72, 89, 3, 19, 32, 119),
+ ('Key Ring', 0,0,0,0,0,0,1,0,0,0,2,13),
+ ('Hats', 893, 912, '1,212', 643, 789, 159,
+ 888, '1,298', 832, 453, '1,344','2,843')
+ )
+ t = Table(colwidths, rowheights, data)
+ """, styleSheet['Code'], dedent=4))
+ lst.append(Paragraph("""
+ You can then give the Table a TableStyle object to control its format. The first TableStyle used was
+ created as follows:
+ """, styleSheet['BodyText']))
+ lst.append(Preformatted("""
GRID_STYLE = TableStyle(
- [('GRID', (0,0), (-1,-1), 0.25, colors.black),
- ('ALIGN', (1,1), (-1,-1), 'RIGHT')]
- )
- """, styleSheet['Code']))
- lst.append(Paragraph("""
- TableStyles are created by passing in a list of commands. There are two types of commands - line commands
- and cell formatting commands. In all cases, the first three elements of a command are the command name,
- the starting cell and the ending cell.
- """, styleSheet['BodyText']))
- lst.append(Paragraph("""
- Line commands always follow this with the weight and color of the desired lines. Colors can be names,
- or they can be specified as a (R,G,B) tuple, where R, G and B are floats and (0,0,0) is black. The line
- command names are: GRID, BOX, OUTLINE, INNERGRID, LINEBELOW, LINEABOVE, LINEBEFORE
- and LINEAFTER. BOX and OUTLINE are equivalent, and GRID is the equivalent of applying both BOX and
- INNERGRID.
- """, styleSheet['BodyText']))
- lst.append(Paragraph("""
- Cell formatting commands are:
- """, styleSheet['BodyText']))
- lst.append(Paragraph("""
- FONT - takes fontname, fontsize and (optional) leading.
- """, styleSheet['Definition']))
- lst.append(Paragraph("""
- TEXTCOLOR - takes a color name or (R,G,B) tuple.
- """, styleSheet['Definition']))
- lst.append(Paragraph("""
- ALIGNMENT (or ALIGN) - takes one of LEFT, RIGHT and CENTRE (or CENTER).
- """, styleSheet['Definition']))
- lst.append(Paragraph("""
- LEFTPADDING - defaults to 6.
- """, styleSheet['Definition']))
- lst.append(Paragraph("""
- RIGHTPADDING - defaults to 6.
- """, styleSheet['Definition']))
- lst.append(Paragraph("""
- BOTTOMPADDING - defaults to 3.
- """, styleSheet['Definition']))
- lst.append(Paragraph("""
- A tablestyle is applied to a table by calling Table.setStyle(tablestyle).
- """, styleSheet['BodyText']))
- t = Table(colwidths, rowheights, data)
- t.setStyle(GRID_STYLE)
- lst.append(PageBreak())
- lst.append(Paragraph("This is GRID_STYLE\n", styleSheet['BodyText']))
- lst.append(t)
-
- t = Table(colwidths, rowheights, data)
- t.setStyle(BOX_STYLE)
- lst.append(Paragraph("This is BOX_STYLE\n", styleSheet['BodyText']))
- lst.append(t)
- lst.append(Paragraph("""
- It was created as follows:
- """, styleSheet['BodyText']))
- lst.append(Preformatted("""
+ [('GRID', (0,0), (-1,-1), 0.25, colors.black),
+ ('ALIGN', (1,1), (-1,-1), 'RIGHT')]
+ )
+ """, styleSheet['Code']))
+ lst.append(Paragraph("""
+ TableStyles are created by passing in a list of commands. There are two types of commands - line commands
+ and cell formatting commands. In all cases, the first three elements of a command are the command name,
+ the starting cell and the ending cell.
+ """, styleSheet['BodyText']))
+ lst.append(Paragraph("""
+ Line commands always follow this with the weight and color of the desired lines. Colors can be names,
+ or they can be specified as a (R,G,B) tuple, where R, G and B are floats and (0,0,0) is black. The line
+ command names are: GRID, BOX, OUTLINE, INNERGRID, LINEBELOW, LINEABOVE, LINEBEFORE
+ and LINEAFTER. BOX and OUTLINE are equivalent, and GRID is the equivalent of applying both BOX and
+ INNERGRID.
+ """, styleSheet['BodyText']))
+ lst.append(Paragraph("""
+ Cell formatting commands are:
+ """, styleSheet['BodyText']))
+ lst.append(Paragraph("""
+ FONT - takes fontname, fontsize and (optional) leading.
+ """, styleSheet['Definition']))
+ lst.append(Paragraph("""
+ TEXTCOLOR - takes a color name or (R,G,B) tuple.
+ """, styleSheet['Definition']))
+ lst.append(Paragraph("""
+ ALIGNMENT (or ALIGN) - takes one of LEFT, RIGHT and CENTRE (or CENTER).
+ """, styleSheet['Definition']))
+ lst.append(Paragraph("""
+ LEFTPADDING - defaults to 6.
+ """, styleSheet['Definition']))
+ lst.append(Paragraph("""
+ RIGHTPADDING - defaults to 6.
+ """, styleSheet['Definition']))
+ lst.append(Paragraph("""
+ BOTTOMPADDING - defaults to 3.
+ """, styleSheet['Definition']))
+ lst.append(Paragraph("""
+ A tablestyle is applied to a table by calling Table.setStyle(tablestyle).
+ """, styleSheet['BodyText']))
+ t = Table(colwidths, rowheights, data)
+ t.setStyle(GRID_STYLE)
+ lst.append(PageBreak())
+ lst.append(Paragraph("This is GRID_STYLE\n", styleSheet['BodyText']))
+ lst.append(t)
+
+ t = Table(colwidths, rowheights, data)
+ t.setStyle(BOX_STYLE)
+ lst.append(Paragraph("This is BOX_STYLE\n", styleSheet['BodyText']))
+ lst.append(t)
+ lst.append(Paragraph("""
+ It was created as follows:
+ """, styleSheet['BodyText']))
+ lst.append(Preformatted("""
BOX_STYLE = TableStyle(
- [('BOX', (0,0), (-1,-1), 0.50, colors.black),
- ('ALIGN', (1,1), (-1,-1), 'RIGHT')]
- )
- """, styleSheet['Code']))
-
- t = Table(colwidths, rowheights, data)
- t.setStyle(LABELED_GRID_STYLE)
- lst.append(Paragraph("This is LABELED_GRID_STYLE\n", styleSheet['BodyText']))
- lst.append(t)
- t = Table(colwidths, rowheights2, data2)
- t.setStyle(LABELED_GRID_STYLE)
- lst.append(Paragraph("This is LABELED_GRID_STYLE ILLUSTRATES EXPLICIT LINE SPLITTING WITH NEWLINE (different heights and data)\n", styleSheet['BodyText']))
- lst.append(t)
- lst.append(Paragraph("""
- It was created as follows:
- """, styleSheet['BodyText']))
- lst.append(Preformatted("""
+ [('BOX', (0,0), (-1,-1), 0.50, colors.black),
+ ('ALIGN', (1,1), (-1,-1), 'RIGHT')]
+ )
+ """, styleSheet['Code']))
+
+ t = Table(colwidths, rowheights, data)
+ t.setStyle(LABELED_GRID_STYLE)
+ lst.append(Paragraph("This is LABELED_GRID_STYLE\n", styleSheet['BodyText']))
+ lst.append(t)
+ t = Table(colwidths, rowheights2, data2)
+ t.setStyle(LABELED_GRID_STYLE)
+ lst.append(Paragraph("This is LABELED_GRID_STYLE ILLUSTRATES EXPLICIT LINE SPLITTING WITH NEWLINE (different heights and data)\n", styleSheet['BodyText']))
+ lst.append(t)
+ lst.append(Paragraph("""
+ It was created as follows:
+ """, styleSheet['BodyText']))
+ lst.append(Preformatted("""
LABELED_GRID_STYLE = TableStyle(
- [('INNERGRID', (0,0), (-1,-1), 0.25, colors.black),
- ('BOX', (0,0), (-1,-1), 2, colors.black),
- ('LINEBELOW', (0,0), (-1,0), 2, colors.black),
- ('LINEAFTER', (0,0), (0,-1), 2, colors.black),
- ('ALIGN', (1,1), (-1,-1), 'RIGHT')]
- )
- """, styleSheet['Code']))
- lst.append(PageBreak())
-
- t = Table(colwidths, rowheights, data)
- t.setStyle(COLORED_GRID_STYLE)
- lst.append(Paragraph("This is COLORED_GRID_STYLE\n", styleSheet['BodyText']))
- lst.append(t)
- lst.append(Paragraph("""
- It was created as follows:
- """, styleSheet['BodyText']))
- lst.append(Preformatted("""
+ [('INNERGRID', (0,0), (-1,-1), 0.25, colors.black),
+ ('BOX', (0,0), (-1,-1), 2, colors.black),
+ ('LINEBELOW', (0,0), (-1,0), 2, colors.black),
+ ('LINEAFTER', (0,0), (0,-1), 2, colors.black),
+ ('ALIGN', (1,1), (-1,-1), 'RIGHT')]
+ )
+ """, styleSheet['Code']))
+ lst.append(PageBreak())
+
+ t = Table(colwidths, rowheights, data)
+ t.setStyle(COLORED_GRID_STYLE)
+ lst.append(Paragraph("This is COLORED_GRID_STYLE\n", styleSheet['BodyText']))
+ lst.append(t)
+ lst.append(Paragraph("""
+ It was created as follows:
+ """, styleSheet['BodyText']))
+ lst.append(Preformatted("""
COLORED_GRID_STYLE = TableStyle(
- [('INNERGRID', (0,0), (-1,-1), 0.25, colors.black),
- ('BOX', (0,0), (-1,-1), 2, colors.red),
- ('LINEBELOW', (0,0), (-1,0), 2, colors.black),
- ('LINEAFTER', (0,0), (0,-1), 2, colors.black),
- ('ALIGN', (1,1), (-1,-1), 'RIGHT')]
- )
- """, styleSheet['Code']))
-
- t = Table(colwidths, rowheights, data)
- t.setStyle(LIST_STYLE)
- lst.append(Paragraph("This is LIST_STYLE\n", styleSheet['BodyText']))
- lst.append(t)
- lst.append(Paragraph("""
- It was created as follows:
- """, styleSheet['BodyText']))
- lst.append(Preformatted("""
+ [('INNERGRID', (0,0), (-1,-1), 0.25, colors.black),
+ ('BOX', (0,0), (-1,-1), 2, colors.red),
+ ('LINEBELOW', (0,0), (-1,0), 2, colors.black),
+ ('LINEAFTER', (0,0), (0,-1), 2, colors.black),
+ ('ALIGN', (1,1), (-1,-1), 'RIGHT')]
+ )
+ """, styleSheet['Code']))
+
+ t = Table(colwidths, rowheights, data)
+ t.setStyle(LIST_STYLE)
+ lst.append(Paragraph("This is LIST_STYLE\n", styleSheet['BodyText']))
+ lst.append(t)
+ lst.append(Paragraph("""
+ It was created as follows:
+ """, styleSheet['BodyText']))
+ lst.append(Preformatted("""
LIST_STYLE = TableStyle(
- [('LINEABOVE', (0,0), (-1,0), 2, colors.green),
- ('LINEABOVE', (0,1), (-1,-1), 0.25, colors.black),
- ('LINEBELOW', (0,-1), (-1,-1), 2, colors.green),
- ('ALIGN', (1,1), (-1,-1), 'RIGHT')]
- )
- """, styleSheet['Code']))
+ [('LINEABOVE', (0,0), (-1,0), 2, colors.green),
+ ('LINEABOVE', (0,1), (-1,-1), 0.25, colors.black),
+ ('LINEBELOW', (0,-1), (-1,-1), 2, colors.green),
+ ('ALIGN', (1,1), (-1,-1), 'RIGHT')]
+ )
+ """, styleSheet['Code']))
- t = Table(colwidths, rowheights, data)
- ts = TableStyle(
- [('LINEABOVE', (0,0), (-1,0), 2, colors.green),
- ('LINEABOVE', (0,1), (-1,-1), 0.25, colors.black),
- ('LINEBELOW', (0,-1), (-1,-1), 2, colors.green),
- ('ALIGN', (1,1), (-1,-1), 'RIGHT'),
- ('TEXTCOLOR', (0,1), (0,-1), colors.red),
- ('BACKGROUND', (0,0), (-1,0), colors.Color(0,0.7,0.7))]
- )
- t.setStyle(ts)
- lst.append(Paragraph("This is a custom style\n", styleSheet['BodyText']))
- lst.append(t)
- lst.append(Paragraph("""
- It was created as follows:
- """, styleSheet['BodyText']))
- lst.append(Preformatted("""
+ t = Table(colwidths, rowheights, data)
+ ts = TableStyle(
+ [('LINEABOVE', (0,0), (-1,0), 2, colors.green),
+ ('LINEABOVE', (0,1), (-1,-1), 0.25, colors.black),
+ ('LINEBELOW', (0,-1), (-1,-1), 2, colors.green),
+ ('ALIGN', (1,1), (-1,-1), 'RIGHT'),
+ ('TEXTCOLOR', (0,1), (0,-1), colors.red),
+ ('BACKGROUND', (0,0), (-1,0), colors.Color(0,0.7,0.7))]
+ )
+ t.setStyle(ts)
+ lst.append(Paragraph("This is a custom style\n", styleSheet['BodyText']))
+ lst.append(t)
+ lst.append(Paragraph("""
+ It was created as follows:
+ """, styleSheet['BodyText']))
+ lst.append(Preformatted("""
ts = TableStyle(
- [('LINEABOVE', (0,0), (-1,0), 2, colors.green),
- ('LINEABOVE', (0,1), (-1,-1), 0.25, colors.black),
- ('LINEBELOW', (0,-1), (-1,-1), 2, colors.green),
- ('ALIGN', (1,1), (-1,-1), 'RIGHT'),
- ('TEXTCOLOR', (0,1), (0,-1), colors.red),
- ('BACKGROUND', (0,0), (-1,0), colors.Color(0,0.7,0.7))]
- )
- """, styleSheet['Code']))
- SimpleDocTemplate('testtables.pdf', showBoundary=1).build(lst)
+ [('LINEABOVE', (0,0), (-1,0), 2, colors.green),
+ ('LINEABOVE', (0,1), (-1,-1), 0.25, colors.black),
+ ('LINEBELOW', (0,-1), (-1,-1), 2, colors.green),
+ ('ALIGN', (1,1), (-1,-1), 'RIGHT'),
+ ('TEXTCOLOR', (0,1), (0,-1), colors.red),
+ ('BACKGROUND', (0,0), (-1,0), colors.Color(0,0.7,0.7))]
+ )
+ """, styleSheet['Code']))
+ data = (
+ ('', 'Jan\nCold', 'Feb\n', 'Mar\n','Apr\n','May\n', 'Jun\nHot', 'Jul\n', 'Aug\nThunder', 'Sep\n', 'Oct\n', 'Nov\n', 'Dec\n'),
+ ('Mugs', 0, 4, 17, 3, 21, 47, 12, 33, 2, -2, 44, 89),
+ ('T-Shirts', 0, 42, 9, -3, 16, 4, 72, 89, 3, 19, 32, 119),
+ ('Key Ring', 0,0,0,0,0,0,1,0,0,0,2,13),
+ ('Hats', 893, 912, '1,212', 643, 789, 159, 888, '1,298', 832, 453, '1,344','2,843')
+ )
+ c = list(colwidths)
+ c[0] = None
+ c[8] = None
+ t = Table(c, [None]+list(rowheights[1:]), data)
+ t.setStyle(LIST_STYLE)
+ lst.append(Paragraph("""
+ This is a LIST_STYLE table with the first rowheight set to None ie automatic.
+ The top row cells are split at a newline '\\n' character. The first and August
+ column widths were also set to None.
+ """, styleSheet['BodyText']))
+ lst.append(t)
+ SimpleDocTemplate('testtables.pdf', showBoundary=1).build(lst)
if __name__ == '__main__':
- test()
+ test()