AW: [reportlab-users] table problem

Mike Dewhirst miked at dewhirst.com.au
Wed Mar 8 03:20:55 EST 2006


Joerg Maeckle wrote:
> mike,
> 
> you may check if you have enough space to maintain the table's content. 
> if the content is too large in its dinmesions, the table will not be
> rendered and no error message is raised..


Joerg

Thanks. I'm using small tables. the biggest is 7 rows with 3 columns all 
containing simple strings. None of the rows wrap when I print the html 
page so I don't think there is a space issue. I found a few mistakes I 
had made and moved forward to discover different errors. The one below 
is the one I cannot get past.

The problem is undoubtedly inexperience. This is my first attempt to 
produce output with Reportlab.

In case anyone has time to look at it I have copied my code and the 
error which has stopped me below that inside tags so you can see where 
stuff starts and stops.

If anyone does take a look - please accept my heartfelt in advance :)

Thanks

Mike

<pdfopinion.py>
#history 
http://www.reportlab.co.uk/cgi-bin/viewcvs.cgi/public/reportlab/trunk/reportlab/demos/gadflypaper/gfe.py
#saved as pdfopinion.py by mike dewhirst and tweaked to buggery

import sys

import mdafs
from mdafs import FORMDIR   # local path/

from reportlab.platypus import *    # includes tables.py
from reportlab.lib.colors import black
from reportlab.lib.styles import getSampleStyleSheet
from reportlab.rl_config import defaultPageSize
PAGE_HEIGHT=defaultPageSize[1]

styles = getSampleStyleSheet()

tstyle = TableStyle(
                    [('LINEABOVE', (0, 0), (-1, 0), 0.25, black)]
                    )

from reportlab.lib.units import inch

elements = list()

HeaderStyle = styles["Heading1"] # XXXX

ParaStyle = styles["Normal"]

PreStyle = styles["Code"]

ht_h = '<h'
ht_p = '<p'


class Transit(mdafs.FSys):

     def __init__(self, client='Test Client', author='Test Author'):
         self._client = client
         self._author = author
         self._pageinfo = 'CGT opinion for ' + \
                          client + ' by ' + author

     def myFirstPage(self, canvas, doc):
         canvas.saveState()
         #canvas.setStrokeColorRGB(1,0,0)
         #canvas.setLineWidth(5)
         #canvas.line(66,72,66,PAGE_HEIGHT-72)
         canvas.setFont('Times-Bold',16)
         #canvas.drawString(108, PAGE_HEIGHT-108, Title)
         canvas.setFont('Times-Roman',9)
         canvas.drawString(inch, 0.75 * inch, "%s" % self._pageinfo)
         canvas.restoreState()

     def myLaterPages(self, canvas, doc):
         #canvas.drawImage("snkanim.gif", 36, 36)
         canvas.saveState()
         #canvas.setStrokeColorRGB(1,0,0)
         #canvas.setLineWidth(5)
         #canvas.line(66,72,66,PAGE_HEIGHT-72)
         canvas.setFont('Times-Roman',9)
         canvas.drawString(inch, 0.75 * inch, "%s" % self._pageinfo)
         canvas.drawString(7 * inch, 0.75 * inch, "Page %d" % doc.page)
         canvas.restoreState()

     def pre(self, txt):
         s = Spacer(0.1*inch, 0.1*inch)
         elements.append(s)
         p = Preformatted(txt, PreStyle)
         elements.append(p)

     def header(self, txt, style=HeaderStyle, klass=Paragraph, sep=0.3):
         s = Spacer(0.2*inch, sep*inch)
         elements.append(s)
         para = klass(txt, style)
         elements.append(para)

     def tt(self, data, style=tstyle, klass=Table, sep=0.3):
         s = Spacer(0.2*inch, sep*inch)
         elements.append(s)
         para = klass(data, style)
         elements.append(para)

     def p(self, txt):
         return Transit.header(self, txt, style=ParaStyle, sep=0.1)

     def output(self, fname):
         elements.insert(0,Spacer(0,inch))
         doc = SimpleDocTemplate(fname)
         doc.build(elements,onFirstPage=self.myFirstPage,
                            onLaterPages=self.myLaterPages)


     def get_tag(self, line, tag='table'):
         """For the first tag encountered return prefix, tag_params,
         tag_content and suffix with unused remainder of line. All
         returned values are strip()ed
         Requires both opening and closing tags
         """
         line = line.strip()
         assert len(line) > 0
         assert len(tag) > 0
         if tag[0] == '<':
             tag = tag[1:]
         o_tag = '<' + tag                           # <tr
         endtag = '</' + tag + '>'                   # </tr>
         prefix = ''
         tag_params = ''
         tag_content = ''
         suffix = ''
         # split on opening tag once
         if line.find(o_tag) > -1:
             parts = line.split(o_tag, 1)                #
             assert len(parts) == 2
             prefix = parts[0].strip()
             line = parts[1]
             # now collect tag_params and shorten line
             for char in line:
                 if char == '>':
                     # have to add 1 to account for '>'
                     line = line[len(tag_params)+1:]
                     break
                 tag_params += char
             # extract content
             ends = line.split(endtag, 1)
             if len(ends) == 1:
                 # line must have been empty
                 ends.insert(0, '')
             assert len(ends) == 2
             # ends[0] has all the between tag contents
             tag_content = ends[0].strip()
             suffix = ends[1].strip()
         return prefix, tag_params.strip(), tag_content, suffix

     def exchange_th_td(self, row):
         """ swap <th out and replace it with <td....><b> """
         row = row.strip()
         row = row.replace('</th>', '</b></td>')
         base = ''
         i = 0
         while i > -1:
             i = row.find('<th')
             if i > -1:
                 base = row[:i] + '<td'
                 row = row[i+3:]
                 found = False
                 for char in row:
                     if not found:
                         if char == '>':
                             found = True
                             base += char + '<b>'
                             char = ''
                     base += char
                 row = base
         return row.strip()

     def count_tags(self, row, tag='<td'):
         assert isinstance(row, str)
         c = 0
         while True:
             i = row.find(tag)
             if i > -1:
                 row = row.replace(tag, '   ', 1)
                 c += 1
             else: break
         return c

     def convert_table_to_rows(self, line):
         """Expects a string containing <table tags and will extract
         data from between the first set as a list of rows and return
         the remainder.
         """

         line = line.strip()
         prefix, params, line, suffix = Transit.get_tag(self, line, 'table')
         # we want rows so split the line
         rowlist = list()
         maxcells = 0
         lst = line.split('</tr>')
         for row in lst:
             # reassemble tags so we can use get_tag() again
             row = row + '</tr>'
             # exchange <th for <td so we can count adequately
             row = Transit.exchange_th_td(self, row)
             c = Transit.count_tags(self, row.lower(), '<td')
             if c > maxcells:
                 maxcells = c
             # now we just want the row internals - discard x, y, z
             x, y, row_text, z = Transit.get_tag(self, row, 'tr')
             # row_text will be a string with all <td> cells in the row
             rowlist.append(row_text)
         # send back suffix in case there is another table in it
         return prefix, rowlist, suffix, maxcells

     def get_cell_data(self, row_text, maxcells):
         """ expects html row without tr tags and with td tags
         returns the contents of table cells in a list of maxcells length
         """
         assert isinstance(row_text, str)
         assert len(row_text) > 0
         cells = list()
         if row_text.find('<table') > -1:
             Transit.wprint(self, 'Cannot handle embedded tables')
         else:
             # we definitely only have <td cause we exchanged <th
             lst = row_text.split('<td')
             for cell in lst:
                 if len(cell) > 0:
                     cell = '<td' + cell
                     x, param, cell, y = Transit.get_tag(self, cell, 'td')
                     # havent figured how to use param yet
                     cells.append(cell)
         # if < max add one at each end in turn starting on the left
         rlen = len(cells)
         i = maxcells - rlen
         for k in range(i):
             # if i = 2 then k ranges from 0 to 1 but we need 1 to 2
             x = k + 1
             if divmod(x, 2)[1] == 1:    # divmod(1, 2) = (0, 1)
                 # "1" and "0" to ensure no empty cells in testing
                 cells.insert(0, ' "1" ')
             else:                       # divmod(2, 2) = (1, 0)
                 cells.append(' "0" ')
         assert len(cells) == maxcells
         return cells

# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # 
# # # # # #

     def pdf_print(self, story, fname, client, author):
         """ story is a list of html lines with heading and para markup """
         self.__init__(client, author)
         for line in story:
             # this removes everything outside the body tags
             # XXX and all &nbsp; we might try this with &nbsp; later
             line = Transit.remove_html(self, line, '&', ';')
             line = line.strip()
             # see if it contains <h...
             if line.startswith(ht_h):
                 Transit.header(self, Transit.remove_html(self, line))

             elif line.find('<table') > -1:
                 # seed line_end for inside the loop
                 line_end = line
                 while len(line_end) > 0:
                     prefix, rowlist, line_end, maxcells = \
                         Transit.convert_table_to_rows(self, line_end)
                     assert maxcells > 0
                     if len(prefix) > 0:
                         h = False
                         if line.startswith(ht_h):
                             h = True
                         prefix = Transit.remove_html(self, prefix)
                         if len(prefix) > 0:
                             # pdfprint it
                             if h :
                                 Transit.header(self, prefix)
                             else:
                                 Transit.p(self, prefix)
                             # done - so finish it forever
                             prefix = ''
                     # now for the first/next table
                     if len(rowlist) > 0:
                         data = list()
                         for row_text in rowlist:
                             if len(row_text) > 0:
                                 cells = Transit.get_cell_data(self, 
row_text, maxcells)
                                 data.append(cells)
                         # pdfpprint the table
                         for row in data:
                             assert isinstance(row, list)
                             assert len(row) == maxcells
                         ######### THIS STARTS THE ERROR SEQUENCE ####
                         Transit.tt(self, data)
                         #############################################
                         # done - so empty the list
                         data = list()
                     if len(line_end) > 0:
                         if line_end.find('<table') == -1:
                             # no more tables so output remainder
                             line_end = Transit.remove_html(self, line_end)
                             if len(line_end) > 0:
                                 # pdfprint line_end
                                 Transit.p(self, line_end)
                                 # done - so finish it off
                                 line_end = ''
                                 # should break here
             # otherwise it is <p
             elif len(line) > 0:
                 line = Transit.remove_html(self, line)
                 Transit.p(self, line)
                 line = ''

         Transit.output(self, fname)


# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # 
# # # # # #

if __name__ == "main":
     pdfdoc = Transit()
     pdfdoc.pdf_print(['Hello World'],'test.pdf')

</pdfopinion.py>

<test_pdfopinion.py>
#!/usr/bin/python
"""
Unit tests for pdfopinion.py.py

"""

import pdfopinion
import unittest

from pdfopinion import FORMDIR



#htlist = util.read_file_into_list(FORMDIR + 'test_table.html')
#tstform = ' '.join(htlist)
tstform = '<html> <head> <title>Untitled Document</title> <meta 
http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> 
</head>  <body bgcolor="#FFFFFF" text="#000000"> <p>Furthermore, it can 
be established that the market values of active assets owned by Magoogle 
Pty Ltd exceed 80% of the total assets owned. The following table 
depicts Active Assets calculations.</p><table width="80%" border="0" 
cellspacing="3" cellpadding="3" align="center"><tr>   <th 
colspan="3">Active Assets Calculation - Magoogle Pty Ltd</th>  </tr> 
<tr> <th width="42%"> <div align="left">Assets</div> </th> <th 
width="29%"> <p align="right">Active Assets</p> </th> <th width="29%"> 
<p align="right">Non-Active Assets</p> </th> </tr> <tr> <td 
width="42%">Cash at Bank</td> <td width="29%"> <div align="right"> 
</div> </td> <td width="29%"> <div align="right">100,000</div> </td> 
</tr> <tr> <td width="42%">Trade Debtors</td> <td width="29%"> <div 
align="right">1,000,000</div> </td> <td width="29%"> <div align="right"> 
</div> </td> </tr> <tr> <td colspan="2"> <div align="right"> 
------------ </div> </td> <td> <div align="right"> ------------ </div> 
</td> </tr> <tr> <th width="42%"> <div align="left">Totals</div> </th> 
<td width="29%"> <div align="right">1,000,000</div> </td> <td 
width="29%"> <div align="right">100,000</div> </td> </tr> <tr> <th 
width="42%"> <div align="left">Percentage Active</div> </th> <th 
width="29%"> <div align="right">90.9%</div> </th> <th width="29%"> <div 
align="left"> </div> </th> </tr></table><p>&nbsp;</p></body> </html>'
table_prefix = '<html> <head> <title>Untitled Document</title> <meta 
http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> 
</head>  <body bgcolor="#FFFFFF" text="#000000"> <p>Furthermore, it can 
be established that the market values of active assets owned by Magoogle 
Pty Ltd exceed 80% of the total assets owned. The following table 
depicts Active Assets calculations.</p>'
table_params = 'width="80%" border="0" cellspacing="3" cellpadding="3" 
align="center"'
table_content = '<tr>   <th colspan="3">Active Assets Calculation - 
Magoogle Pty Ltd</th>  </tr> <tr> <th width="42%"> <div 
align="left">Assets</div> </th> <th width="29%"> <p align="right">Active 
Assets</p> </th> <th width="29%"> <p align="right">Non-Active Assets</p> 
</th> </tr> <tr> <td width="42%">Cash at Bank</td> <td width="29%"> <div 
align="right"> </div> </td> <td width="29%"> <div 
align="right">100,000</div> </td> </tr> <tr> <td width="42%">Trade 
Debtors</td> <td width="29%"> <div align="right">1,000,000</div> </td> 
<td width="29%"> <div align="right"> </div> </td> </tr> <tr> <td 
colspan="2"> <div align="right"> ------------ </div> </td> <td> <div 
align="right"> ------------ </div> </td> </tr> <tr> <th width="42%"> 
<div align="left">Totals</div> </th> <td width="29%"> <div 
align="right">1,000,000</div> </td> <td width="29%"> <div 
align="right">100,000</div> </td> </tr> <tr> <th width="42%"> <div 
align="left">Percentage Active</div> </th> <th width="29%"> <div 
align="right">90.9%</div> </th> <th width="29%"> <div align="left"> 
</div> </th> </tr>'
table_suffix = '<p>&nbsp;</p></body> </html>'
row1_content = '<th colspan="3">Active Assets Calculation - Magoogle Pty 
Ltd</th>'
row1_cont_td = '<td colspan="3"><b>Active Assets Calculation - Magoogle 
Pty Ltd</b></td>'
r1_c2 = '<b>Active Assets Calculation - Magoogle Pty Ltd</b>'
row1_suffix = ' <tr> <th width="42%"> <div align="left">Assets</div> 
</th> <th width="29%"> <p align="right">Active Assets</p> </th> <th 
width="29%"> <p align="right">Non-Active Assets</p> </th> </tr> <tr> <td 
width="42%">Cash at Bank</td> <td width="29%"> <div align="right"> 
</div> </td> <td width="29%"> <div align="right">100,000</div> </td> 
</tr> <tr> <td width="42%">Trade Debtors</td> <td width="29%"> <div 
align="right">1,000,000</div> </td> <td width="29%"> <div align="right"> 
</div> </td> </tr> <tr> <td colspan="2"> <div align="right"> 
------------ </div> </td> <td> <div align="right"> ------------ </div> 
</td> </tr> <tr> <th width="42%"> <div align="left">Totals</div> </th> 
<td width="29%"> <div align="right">1,000,000</div> </td> <td 
width="29%"> <div align="right">100,000</div> </td> </tr> <tr> <th 
width="42%"> <div align="left">Percentage Active</div> </th> <th 
width="29%"> <div align="right">90.9%</div> </th> <th width="29%"> <div 
align="left"> </div> </th> </tr></table><p>&nbsp;</p></body> </html>'
row2_content = '<th width="42%"> <div align="left">Assets</div> </th> 
<th width="29%"> <p align="right">Active Assets</p> </th> <th 
width="29%"> <p align="right">Non-Active Assets</p> </th>'
row2_suffix = ' <tr> <td width="42%">Cash at Bank</td> <td width="29%"> 
<div align="right"> </div> </td> <td width="29%"> <div 
align="right">100,000</div> </td> </tr> <tr> <td width="42%">Trade 
Debtors</td> <td width="29%"> <div align="right">1,000,000</div> </td> 
<td width="29%"> <div align="right"> </div> </td> </tr> <tr> <td 
colspan="2"> <div align="right"> ------------ </div> </td> <td> <div 
align="right"> ------------ </div> </td> </tr> <tr> <th width="42%"> 
<div align="left">Totals</div> </th> <td width="29%"> <div 
align="right">1,000,000</div> </td> <td width="29%"> <div 
align="right">100,000</div> </td> </tr> <tr> <th width="42%"> <div 
align="left">Percentage Active</div> </th> <th width="29%"> <div 
align="right">90.9%</div> </th> <th width="29%"> <div align="left"> 
</div> </th> </tr></table><p>&nbsp;</p></body> </html>'
row3_content = '<td width="42%">Cash at Bank</td> <td width="29%"> <div 
align="right"> </div> </td> <td width="29%"> <div 
align="right">100,000</div> </td>'
r3_c1 = 'Cash at Bank'
r3_c2 = '<div align="right"> </div>'
r3_c3 = '<div align="right">100,000</div>'
row3_suffix = ' <tr> <td width="42%">Trade Debtors</td> <td width="29%"> 
<div align="right">1,000,000</div> </td> <td width="29%"> <div 
align="right"> </div> </td> </tr> <tr> <td colspan="2"> <div 
align="right"> ------------ </div> </td> <td> <div align="right"> 
------------ </div> </td> </tr> <tr> <th width="42%"> <div 
align="left">Totals</div> </th> <td width="29%"> <div 
align="right">1,000,000</div> </td> <td width="29%"> <div 
align="right">100,000</div> </td> </tr> <tr> <th width="42%"> <div 
align="left">Percentage Active</div> </th> <th width="29%"> <div 
align="right">90.9%</div> </th> <th width="29%"> <div align="left"> 
</div> </th> </tr></table><p>&nbsp;</p></body> </html>'
row4_content = '<td width="42%">Trade Debtors</td> <td width="29%"> <div 
align="right">1,000,000</div> </td> <td width="29%"> <div align="right"> 
</div> </td>'
row4_suffix = ' <tr> <td colspan="2"> <div align="right"> ------------ 
</div> </td> <td> <div align="right"> ------------ </div> </td> </tr> 
<tr> <th width="42%"> <div align="left">Totals</div> </th> <td 
width="29%"> <div align="right">1,000,000</div> </td> <td width="29%"> 
<div align="right">100,000</div> </td> </tr> <tr> <th width="42%"> <div 
align="left">Percentage Active</div> </th> <th width="29%"> <div 
align="right">90.9%</div> </th> <th width="29%"> <div align="left"> 
</div> </th> </tr></table><p>&nbsp;</p></body> </html>'
row5_content = '<td colspan="2"> <div align="right"> ------------ </div> 
</td> <td> <div align="right"> ------------ </div> </td>'
r5_c3 = r5_c2 = '<div align="right"> ------------ </div>'
row5_suffix = ' <tr> <th width="42%"> <div align="left">Totals</div> 
</th> <td width="29%"> <div align="right">1,000,000</div> </td> <td 
width="29%"> <div align="right">100,000</div> </td> </tr> <tr> <th 
width="42%"> <div align="left">Percentage Active</div> </th> <th 
width="29%"> <div align="right">90.9%</div> </th> <th width="29%"> <div 
align="left"> </div> </th> </tr></table><p>&nbsp;</p></body> </html>'
row6_content = '<th width="42%"> <div align="left">Totals</div> </th> 
<td width="29%"> <div align="right">1,000,000</div> </td> <td 
width="29%"> <div align="right">100,000</div> </td>'
row6_suffix = ' <tr> <th width="42%"> <div align="left">Percentage 
Active</div> </th> <th width="29%"> <div align="right">90.9%</div> </th> 
<th width="29%"> <div align="left"> </div> </th> 
</tr></table><p>&nbsp;</p></body> </html>'
row7_content = '<th width="42%"> <div align="left">Percentage 
Active</div> </th> <th width="29%"> <div align="right">90.9%</div> </th> 
<th width="29%"> <div align="left"> </div> </th>'
row7_suffix = '</table><p>&nbsp;</p></body> </html>'

def count_tags(row, tag):
     i = 0
     while True:
         if row.find(tag) > -1:
             i += 1
             row = row.replace(tag, '~~~', 1)
         else: break
     return i

class test_pdfopinion(unittest.TestCase):
     """     """

     def test_get_cell_data_1(self):
         """ , row_text, maxcells - expects html row without tr tags and
         returns the contents of table cells in a list of maxcells length"""
         tsto = pdfopinion.Transit()
         cells = tsto.get_cell_data(row1_cont_td, 3) # has 1 td
         self.assertEqual(len(cells), 3)
         #tsto.wprint(cells)
         self.assertEqual(cells[0], ' "1" ')
         self.assertEqual(cells[1], r1_c2)
         self.assertEqual(cells[2], ' "0" ')

     def test_get_cell_data_2(self):
         """ , row_text, maxcells - expects html row without tr tags and
         returns the contents of table cells in a list of maxcells length"""
         tsto = pdfopinion.Transit()
         cells = tsto.get_cell_data(row5_content, 3) # has 1 td
         self.assertEqual(len(cells), 3)
         #tsto.wprint(cells)
         self.assertEqual(cells[0], ' "1" ')
         self.assertEqual(cells[1], r5_c2)
         self.assertEqual(cells[2], r5_c3)

     def test_get_cell_data_3(self):
         """ , row_text, maxcells - expects html row without tr tags and
         returns the contents of table cells in a list of maxcells length"""
         tsto = pdfopinion.Transit()
         cells = tsto.get_cell_data(row3_content, 3) # has 1 td
         self.assertEqual(len(cells), 3)
         #tsto.wprint(cells)
         self.assertEqual(cells[0], r3_c1)
         self.assertEqual(cells[1], r3_c2)
         self.assertEqual(cells[2], r3_c3)


     def test_get_tag(self):
         """ for the first tag encountered return
         prefix, tag_params, tag_content and suffix
         """
         tsto = pdfopinion.Transit()
         prefix, params, content, suffix = tsto.get_tag(tstform, 
'table')
         self.assertEqual(prefix, table_prefix)
         self.assertEqual(params, table_params)
         self.assertEqual(content, table_content)
         self.assertEqual(suffix, table_suffix)


     def test_exchange_th_td(self):
         tst1 = table_content
         tsto = pdfopinion.Transit()
         stst = tsto.exchange_th_td(tst1)
         self.assertNotEqual(stst, tst1)
         ah = count_tags(tst1, '<th')
         bh = count_tags(stst, '<th')
         ab = count_tags(tst1, '<b>')
         bb = count_tags(stst, '<b>')
         ad = count_tags(tst1, '<td')
         bd = count_tags(stst, '<td')
         a_b = count_tags(tst1, '</b></td>')
         b_b = count_tags(stst, '</b></td>')
         self.assertEqual(bd, ad + ah)
         self.assertEqual(bb, ah)
         self.assertEqual(bh, 0)
         self.assertEqual(ab, 0)
         self.assertEqual(a_b, 0)
         self.assertEqual(b_b, ah)


     def test_convert_table_to_rows(self):
         tsto = pdfopinion.Transit()
         tst1 = tstform
         line0, rowlist, line_end, i = tsto.convert_table_to_rows(tst1)
         self.assertEqual(line0, table_prefix)
         self.assertEqual(len(rowlist), 8)
         self.assertEqual(line_end, table_suffix)
         self.assertEqual(rowlist[0], row1_cont_td)


if __name__ == "__main__":
     unittest.main()

</test_pdfopinion.py>

<error>
  -->  --> -->


TypeError	Python 2.4.2: /usr/bin/python
Wed Mar 8 19:03:57 2006

A problem occurred in a Python script. Here is the sequence of function 
calls leading up to the error, in the order they occurred.
  /srv/www/cgi-bin/ppp/active_assets.py
   291     page = Transit()
   292     form = cgi.FieldStorage()
   293     mainfile = NEXTSRC
   294     page.transit_from_caller(form, mainfile)
   295 # end
page = <__main__.Transit instance>, page.transit_from_caller = <bound 
method Transit.transit_from_caller of <__main__.Transit instance>>, form 
= FieldStorage(None, None, [MiniFieldStorage('txtR...'500,000'), 
MiniFieldStorage('btnNext', 'Next')]), mainfile = '../../data/forms/ppp/'
  /srv/www/cgi-bin/ppp/active_assets.py in 
transit_from_caller(self=<__main__.Transit instance>, 
form=FieldStorage(None, None, [MiniFieldStorage('txtR...'500,000'), 
MiniFieldStorage('btnNext', 'Next')]), htfile='../../data/forms/ppp/')
   280                 Transit.save_opinion(self, oprowids, notids, rowid)
   281                 #
   282                 htlist = Transit.build_opinion(self, refid, 
rowid, userid)
   283                 Transit.serve_page_from_list(self, htlist)
   284                 err = ''
htlist undefined, global Transit = <class __main__.Transit>, 
Transit.build_opinion = <unbound method Transit.build_opinion>, self = 
<__main__.Transit instance>, refid = 'MD:34567~1023', rowid = '1023', 
userid = 'miked'
  /srv/www/cgi-bin/ppp/opinion.py in 
build_opinion(self=<__main__.Transit instance>, refid='MD:34567~1023', 
rowid='1023', userid='miked')
   361                 # XXX should construct a dict for all the info
   362                 pdf.pdf_print(pdflines, HTMLOUT + pdf_refid + '.pdf',
   363                               client, author)
   364                 pdf_link = APPDIR + pdf_refid + '.pdf'
   365         # show all to admins
client = 'Fred Magoo', author = "Michael's Bicycles"
  /srv/www/cgi-bin/ppp/pdfopinion.py in 
pdf_print(self=<pdfopinion.Transit instance>, story=['<h><h5>Capital 
Gains Tax Opinion <Br>Fred Magoo - Sale of Shares</h5>\n', '<p>\n', 
'<h><h5>Introduction</h5>\n', "<p>This opinion has been formulated by 
Michael's... file reference in this matter is MD:34567~1023.\n", 
'<h><h5>Background</h5>\n', '<p>Fred Magoo hereafter, Fred, was born on 
26/8/... <a href="#[00001]">Australian Resident [1]</a>.\n', '<h><h5>Tax 
Position</h5>\n', '<p>Fred has stipulated that his intention when 
o...eated as a <a href="#[00002]">CGT Event [2]</a>.\n', '<h><h5>Div 115 
Concession</h5>\n', '<p><p>The <a href="#[00003]">Div 115 Discount 
[3...align="right">212,609</div> </td> </tr> </table>\n', '<h><h5>Small 
Business Concessions</h5>\n', '<p><p> In qualifying for any of the small 
busine...e basic conditions stipulated above are met.</p>\n', 
'<h><h5>Net Assets Test</h5>\n', '<p><p>Based on the information held by 
our offic...ign="right">4,100,000</div> </th> </tr> </table>\n', 
'<h><h5>Active Assets Test</h5>\n', '<p><p>Furthermore, it can be 
established that th...> <div align="left"> </div> </th> </tr> 
</table>\n', '<h><h5>Controlling Individual Test - Voting Power Not 
Satisfied</h5>\n', '<p>The Controlling Individual test has not been 
...at least 50% of the voting power in the company.\n', '<h><h5>Small 
Business Active Asset Concession Not Satisfied</h5>\n', '<p><p>Fred has 
not satisfied the three tests to ...<li>Minimum 80% Active Assets 
(90.9%)</li> </ul>\n', ...], fname='../../htdocs/ppp/MD_34567~1023.pdf', 
client='Fred Magoo', author="Michael's Bicycles")
   289                 line = ''
   290
   291         Transit.output(self, fname)
   292
   293
global Transit = <class pdfopinion.Transit>, Transit.output = <unbound 
method Transit.output>, self = <pdfopinion.Transit instance>, fname = 
'../../htdocs/ppp/MD_34567~1023.pdf'
  /srv/www/cgi-bin/ppp/pdfopinion.py in output(self=<pdfopinion.Transit 
instance>, fname='../../htdocs/ppp/MD_34567~1023.pdf')
    88         doc = SimpleDocTemplate(fname)
    89         doc.build(elements,onFirstPage=self.myFirstPage,
    90                            onLaterPages=self.myLaterPages)
    91
    92
onLaterPages undefined, self = <pdfopinion.Transit instance>, 
self.myLaterPages = <bound method Transit.myLaterPages of 
<pdfopinion.Transit instance>>
 
/usr/local/lib/python2.4/site-packages/reportlab/platypus/doctemplate.py 
in build(self=<reportlab.platypus.doctemplate.SimpleDocTemplate 
instance>, flowables=[Spacer(14.4, 21.6), Paragraph( 'style' 
<ParagraphStyle 'Headin... 'bold' 1 ) #ParaFrag] ) #Paragraph, 
Spacer(14.4, 7.2), Paragraph( 'style' <ParagraphStyle 'Normal... 'bold' 
0 ) #ParaFrag] ) #Paragraph, Spacer(14.4, 21.6), Paragraph( 'style' 
<ParagraphStyle 'Headin... 'bold' 1 ) #ParaFrag] ) #Paragraph, 
Spacer(14.4, 7.2), Paragraph( 'style' <ParagraphStyle 'Normal... 'bold' 
0 ) #ParaFrag] ) #Paragraph, Spacer(14.4, 21.6), Table( 
rowHeights=[None, None, None, None, None...ign="right">4,100,000</div> 
</b>']] ) # end table, Spacer(14.4, 21.6), Paragraph( 'style' 
<ParagraphStyle 'Headin... 'bold' 1 ) #ParaFrag] ) #Paragraph, 
Spacer(14.4, 7.2), Paragraph( 'style' <ParagraphStyle 'Normal... 'bold' 
0 ) #ParaFrag] ) #Paragraph, Spacer(14.4, 21.6), Table( 
rowHeights=[None, None, None, None, None...> <div align="left"> </div> 
</b>']] ) # end table, Spacer(14.4, 21.6), Paragraph( 'style' 
<ParagraphStyle 'Headin... 'bold' 1 ) #ParaFrag] ) #Paragraph, 
Spacer(14.4, 7.2), Paragraph( 'style' <ParagraphStyle 'Normal... 'bold' 
0 ) #ParaFrag] ) #Paragraph, ...], onFirstPage=<bound method 
Transit.myFirstPage of <pdfopinion.Transit instance>>, 
onLaterPages=<bound method Transit.myLaterPages of <pdfopinion.Transit 
instance>>)
   812         if onLaterPages is _doNothing and 
hasattr(self,'onLaterPages'):
   813             self.pageTemplates[1].beforeDrawPage = self.onLaterPages
   814         BaseDocTemplate.build(self,flowables)
   815
   816
global BaseDocTemplate = <class 
reportlab.platypus.doctemplate.BaseDocTemplate>, BaseDocTemplate.build = 
<unbound method BaseDocTemplate.build>, self = 
<reportlab.platypus.doctemplate.SimpleDocTemplate instance>, flowables = 
[Spacer(14.4, 21.6), Paragraph( 'style' <ParagraphStyle 'Headin... 
'bold' 1 ) #ParaFrag] ) #Paragraph, Spacer(14.4, 7.2), Paragraph( 
'style' <ParagraphStyle 'Normal... 'bold' 0 ) #ParaFrag] ) #Paragraph, 
Spacer(14.4, 21.6), Paragraph( 'style' <ParagraphStyle 'Headin... 'bold' 
1 ) #ParaFrag] ) #Paragraph, Spacer(14.4, 7.2), Paragraph( 'style' 
<ParagraphStyle 'Normal... 'bold' 0 ) #ParaFrag] ) #Paragraph, 
Spacer(14.4, 21.6), Table( rowHeights=[None, None, None, None, 
None...ign="right">4,100,000</div> </b>']] ) # end table, Spacer(14.4, 
21.6), Paragraph( 'style' <ParagraphStyle 'Headin... 'bold' 1 ) 
#ParaFrag] ) #Paragraph, Spacer(14.4, 7.2), Paragraph( 'style' 
<ParagraphStyle 'Normal... 'bold' 0 ) #ParaFrag] ) #Paragraph, 
Spacer(14.4, 21.6), Table( rowHeights=[None, None, None, None, None...> 
<div align="left"> </div> </b>']] ) # end table, Spacer(14.4, 21.6), 
Paragraph( 'style' <ParagraphStyle 'Headin... 'bold' 1 ) #ParaFrag] ) 
#Paragraph, Spacer(14.4, 7.2), Paragraph( 'style' <ParagraphStyle 
'Normal... 'bold' 0 ) #ParaFrag] ) #Paragraph, ...]
 
/usr/local/lib/python2.4/site-packages/reportlab/platypus/doctemplate.py 
in build(self=<reportlab.platypus.doctemplate.SimpleDocTemplate 
instance>, flowables=[Spacer(14.4, 21.6), Paragraph( 'style' 
<ParagraphStyle 'Headin... 'bold' 1 ) #ParaFrag] ) #Paragraph, 
Spacer(14.4, 7.2), Paragraph( 'style' <ParagraphStyle 'Normal... 'bold' 
0 ) #ParaFrag] ) #Paragraph, Spacer(14.4, 21.6), Paragraph( 'style' 
<ParagraphStyle 'Headin... 'bold' 1 ) #ParaFrag] ) #Paragraph, 
Spacer(14.4, 7.2), Paragraph( 'style' <ParagraphStyle 'Normal... 'bold' 
0 ) #ParaFrag] ) #Paragraph, Spacer(14.4, 21.6), Table( 
rowHeights=[None, None, None, None, None...ign="right">4,100,000</div> 
</b>']] ) # end table, Spacer(14.4, 21.6), Paragraph( 'style' 
<ParagraphStyle 'Headin... 'bold' 1 ) #ParaFrag] ) #Paragraph, 
Spacer(14.4, 7.2), Paragraph( 'style' <ParagraphStyle 'Normal... 'bold' 
0 ) #ParaFrag] ) #Paragraph, Spacer(14.4, 21.6), Table( 
rowHeights=[None, None, None, None, None...> <div align="left"> </div> 
</b>']] ) # end table, Spacer(14.4, 21.6), Paragraph( 'style' 
<ParagraphStyle 'Headin... 'bold' 1 ) #ParaFrag] ) #Paragraph, 
Spacer(14.4, 7.2), Paragraph( 'style' <ParagraphStyle 'Normal... 'bold' 
0 ) #ParaFrag] ) #Paragraph, ...], filename=None, canvasmaker=<class 
reportlab.pdfgen.canvas.Canvas>)
   642             try:
   643                 first = flowables[0]
   644                 self.handle_flowable(flowables)
   645             except:
   646                 #if it has trace info, add it to the traceback 
message.
self = <reportlab.platypus.doctemplate.SimpleDocTemplate instance>, 
self.handle_flowable = <bound method SimpleDocTemplate.handle_flowable 
...platypus.doctemplate.SimpleDocTemplate instance>>, flowables = 
[Spacer(14.4, 21.6), Paragraph( 'style' <ParagraphStyle 'Headin... 
'bold' 1 ) #ParaFrag] ) #Paragraph, Spacer(14.4, 7.2), Paragraph( 
'style' <ParagraphStyle 'Normal... 'bold' 0 ) #ParaFrag] ) #Paragraph, 
Spacer(14.4, 21.6), Paragraph( 'style' <ParagraphStyle 'Headin... 'bold' 
1 ) #ParaFrag] ) #Paragraph, Spacer(14.4, 7.2), Paragraph( 'style' 
<ParagraphStyle 'Normal... 'bold' 0 ) #ParaFrag] ) #Paragraph, 
Spacer(14.4, 21.6), Table( rowHeights=[None, None, None, None, 
None...ign="right">4,100,000</div> </b>']] ) # end table, Spacer(14.4, 
21.6), Paragraph( 'style' <ParagraphStyle 'Headin... 'bold' 1 ) 
#ParaFrag] ) #Paragraph, Spacer(14.4, 7.2), Paragraph( 'style' 
<ParagraphStyle 'Normal... 'bold' 0 ) #ParaFrag] ) #Paragraph, 
Spacer(14.4, 21.6), Table( rowHeights=[None, None, None, None, None...> 
<div align="left"> </div> </b>']] ) # end table, Spacer(14.4, 21.6), 
Paragraph( 'style' <ParagraphStyle 'Headin... 'bold' 1 ) #ParaFrag] ) 
#Paragraph, Spacer(14.4, 7.2), Paragraph( 'style' <ParagraphStyle 
'Normal... 'bold' 0 ) #ParaFrag] ) #Paragraph, ...]
 
/usr/local/lib/python2.4/site-packages/reportlab/platypus/doctemplate.py 
in 
handle_flowable(self=<reportlab.platypus.doctemplate.SimpleDocTemplate 
instance>, flowables=[Spacer(14.4, 21.6), Paragraph( 'style' 
<ParagraphStyle 'Headin... 'bold' 1 ) #ParaFrag] ) #Paragraph, 
Spacer(14.4, 7.2), Paragraph( 'style' <ParagraphStyle 'Normal... 'bold' 
0 ) #ParaFrag] ) #Paragraph, Spacer(14.4, 21.6), Paragraph( 'style' 
<ParagraphStyle 'Headin... 'bold' 1 ) #ParaFrag] ) #Paragraph, 
Spacer(14.4, 7.2), Paragraph( 'style' <ParagraphStyle 'Normal... 'bold' 
0 ) #ParaFrag] ) #Paragraph, Spacer(14.4, 21.6), Table( 
rowHeights=[None, None, None, None, None...ign="right">4,100,000</div> 
</b>']] ) # end table, Spacer(14.4, 21.6), Paragraph( 'style' 
<ParagraphStyle 'Headin... 'bold' 1 ) #ParaFrag] ) #Paragraph, 
Spacer(14.4, 7.2), Paragraph( 'style' <ParagraphStyle 'Normal... 'bold' 
0 ) #ParaFrag] ) #Paragraph, Spacer(14.4, 21.6), Table( 
rowHeights=[None, None, None, None, None...> <div align="left"> </div> 
</b>']] ) # end table, Spacer(14.4, 21.6), Paragraph( 'style' 
<ParagraphStyle 'Headin... 'bold' 1 ) #ParaFrag] ) #Paragraph, 
Spacer(14.4, 7.2), Paragraph( 'style' <ParagraphStyle 'Normal... 'bold' 
0 ) #ParaFrag] ) #Paragraph, ...])
   560         else:
   561             #try to fit it then draw it
   562             if self.frame.add(f, self.canv, 
trySplit=self.allowSplitting):
   563                 self._curPageFlowableCount = 
self._curPageFlowableCount + 1
   564                 self.afterFlowable(f)
self = <reportlab.platypus.doctemplate.SimpleDocTemplate instance>, 
self.frame = <reportlab.platypus.frames.Frame instance>, self.frame.add 
= <bound method Frame._add of <reportlab.platypus.frames.Frame 
instance>>, f = Table( rowHeights=[None, None, None, None, None...<div 
align="right">212,609</div>']] ) # end table, self.canv = 
<reportlab.pdfgen.canvas.Canvas instance>, trySplit undefined, 
self.allowSplitting = 1
  /usr/local/lib/python2.4/site-packages/reportlab/platypus/frames.py in 
_add(self=<reportlab.platypus.frames.Frame instance>, flowable=Table( 
rowHeights=[None, None, None, None, None...<div 
align="right">212,609</div>']] ) # end table, 
canv=<reportlab.pdfgen.canvas.Canvas instance>, trySplit=1)
   122         if h>0:
   123             flowable.canv = canv #so they can use stringWidth etc
   124             w, h = flowable.wrap(aW, h)
   125             del flowable.canv
   126         else:
w undefined, h = 116.28976377952731, flowable = Table( rowHeights=[None, 
None, None, None, None...<div align="right">212,609</div>']] ) # end 
table, flowable.wrap = <bound method Table.wrap of Table( 
rowHeights=[...div align="right">212,609</div>']] ) # end table>, aW = 
439.27559055118104
  /usr/local/lib/python2.4/site-packages/reportlab/platypus/tables.py in 
wrap(self=Table( rowHeights=[None, None, None, None, None...<div 
align="right">212,609</div>']] ) # end table, 
availWidth=439.27559055118104, availHeight=116.28976377952731)
   789
   790     def wrap(self, availWidth, availHeight):
   791         self._calc(availWidth, availHeight)
   792         #nice and easy, since they are predetermined size
   793         self.availWidth = availWidth
self = Table( rowHeights=[None, None, None, None, None...<div 
align="right">212,609</div>']] ) # end table, self._calc = <bound method 
Table._calc of Table( rowHeights=...div align="right">212,609</div>']] ) 
# end table>, availWidth = 439.27559055118104, availHeight = 
116.28976377952731
  /usr/local/lib/python2.4/site-packages/reportlab/platypus/tables.py in 
_calc(self=Table( rowHeights=[None, None, None, None, None...<div 
align="right">212,609</div>']] ) # end table, 
availWidth=439.27559055118104, availHeight=116.28976377952731)
   450
   451         # calculate the full table height
   452         self._calc_height(availHeight,availWidth,W=W)
   453
   454         # calculate the full table width
self = Table( rowHeights=[None, None, None, None, None...<div 
align="right">212,609</div>']] ) # end table, self._calc_height = <bound 
method Table._calc_height of Table( rowH...div 
align="right">212,609</div>']] ) # end table>, availHeight = 
116.28976377952731, availWidth = 439.27559055118104, W = None
  /usr/local/lib/python2.4/site-packages/reportlab/platypus/tables.py in 
_calc_height(self=Table( rowHeights=[None, None, None, None, None...<div 
align="right">212,609</div>']] ) # end table, 
availHeight=116.28976377952731, availWidth=439.27559055118104, H=[None, 
None, None, None, None, None, None, None, None], W=None)
   361
   362         H = self._argH
   363         if not W: W = _calc_pc(self._argW,availWidth)   #widths array
   364
   365         hmax = lim = len(H)
W = None, global _calc_pc = <function _calc_pc>, self = Table( 
rowHeights=[None, None, None, None, None...<div 
align="right">212,609</div>']] ) # end table, self._argW = [TableStyle( 
('LINEABOVE', (0, 0), (-1, 0), 0.25, Color(0,0,0)) ) # end TableStyle, 
TableStyle( ('LINEABOVE', (0, 0), (-1, 0), 0.25, Color(0,0,0)) ) # end 
TableStyle], availWidth = 439.27559055118104
  /usr/local/lib/python2.4/site-packages/reportlab/platypus/tables.py in 
_calc_pc(V=[TableStyle( ('LINEABOVE', (0, 0), (-1, 0), 0.25, 
Color(0,0,0)) ) # end TableStyle, TableStyle( ('LINEABOVE', (0, 0), (-1, 
0), 0.25, Color(0,0,0)) ) # end TableStyle], avail=439.27559055118104)
   135             n += 1
   136         else:
   137             s -= v
   138         r(v)
   139     s = max(0.,s)
s = 439.27559055118104, v = TableStyle( ('LINEABOVE', (0, 0), (-1, 0), 
0.25, Color(0,0,0)) ) # end TableStyle

TypeError: unsupported operand type(s) for -=: 'float' and 'instance'
       args = ("unsupported operand type(s) for -=: 'float' and 
'instance'",)
</error>




> 
> joerg
> 
> 
> 
>>I'm new to Python and Reportlab.
>>
>>I have written some python to output html to pdf and it sort 
>>of works a little bit. I can produce paragraph headers and 
>>paragraph text ok but have struck a black hole with tables.
>>
>>My reading of the docs and samples indicates that all I need 
>>to do is call platypus.tables.Table() with a list of 
>>equi-length lists containing strings and it should work.
>>
>>For me it just doesn't. Quietly. No errors. The paragraphs 
>>before and after the tables come out OK. I can guarantee via 
>>unit tests that the data (ie., Table(data) ) is a list of lists.
>>
>>When I checked the source it seems to be looking for a 
>>Flowable rather than a list of lists. This is what I saw in 
>>platypus.tables.py ...
>>
>>class Table(Flowable):
>>     def __init__(self, data, colWidths=None, 
>>rowHeights=None, style=None, repeatRows=0, repeatCols=0, splitByRow=1,
>>emptyTableAction=None):
>>
>>Where am I going astray? Can anyone help?
>>
>>Thanks
>>
>>Mike
>>
>>
>>_______________________________________________
>>reportlab-users mailing list
>>reportlab-users at reportlab.com
>>http://two.pairlist.net/mailman/listinfo/reportlab-users
>>
>>
> 
> 
> _______________________________________________
> reportlab-users mailing list
> reportlab-users at reportlab.com
> http://two.pairlist.net/mailman/listinfo/reportlab-users
> 
> 



More information about the reportlab-users mailing list