title: Python & ReportLab: wrong column width and alignment in PDF table
body: <p>I use Python 2.7 (iOS Pythonista App) and the reportlab 2.7 module to create a PDF with a table. Everything works fine. RepotLab formats the width of the columns automatically. But in two cases I can't understand why reportlab formats the output the way it does and how I can get the format I want.</p>
  
  <p><strong>Case 1: Everything almost as I want …</strong></p>
  
  <pre class="lang-none prettyprint-override"><code>+-----+----------+---------------+----------+---------------------------------------------------------------------------------------------------------------+
  | Day | Date     | Time          | Duration | Notes                                                                                                         |
  +-----+----------+---------------+----------+---------------------------------------------------------------------------------------------------------------+
  | Tue | 01.04.14 | 14:00 - 17:15 | 3.25     | Here are some notes.                                                                                          |
  +-----+----------+---------------+----------+---------------------------------------------------------------------------------------------------------------+
  | Wed | 02.04.14 | 18:00 - 20:15 | 2.25     | Sometime these notes are a little longer text so there must be a line break to let the whole note be visible! |
  +-----+----------+---------------+----------+---------------------------------------------------------------------------------------------------------------+
  | Thu | 02.04.14 | 14:00 - 17:15 | 3.25     | And sometimes these notes are only a few words.                                                               |
  +-----+----------+---------------+----------+---------------------------------------------------------------------------------------------------------------+
  </code></pre>
  
  <p><strong>Case 2: I try to line up the float points</strong></p>
  
  <p>With the help of</p>
  
  <pre><code>TableStyle([('ALIGN', (3,1), (3,-1), 'DECIMAL'),])
  </code></pre>
  
  <p>I tried to get every float point exactly in one vertical line. It works but in the Duration column everything is so (hard) aligned to the right that a part of the number in the Notes column (and there is much space to the left of the Duration values). It seems as if the right padding is set to the point or the number before the point and not to the whole value.</p>
  
  <pre class="lang-none prettyprint-override"><code>+-----+----------+---------------+-----------+-------------------------------------------------+
  | Day | Date     | Time          | Duration  | Notes                                           |
  +-----+----------+---------------+-----------+-------------------------------------------------+
  | Tue | 01.04.14 | 14:00 - 17:15 |        3.2|5Here are some notes.                            |
  +-----+----------+---------------+-----------+-------------------------------------------------+
  | Wed | 02.04.14 | 14:00 - 17:15 |        3.2|5And sometimes these notes are only a few words. |
  +-----+----------+---------------+-----------+-------------------------------------------------+
  </code></pre>
  
  <p>With the help of</p>
  
  <pre><code>TableStyle([('RIGHTPADDING', (3,1), (3,-1), 18),])
  </code></pre>
  
  <p>I got get better results, but I think there should be a better way!?</p>
  
  <p><strong>Case 3: Try to wrap the notes text.</strong></p>
  
  <p>When I use a Paragraph to insert the notes texts, I get wrapping text, but the column width is astonishing. I can't get the following example exactly as the real output is.</p>
  
  <p>The whole table width fits to the document ( DIN A4 without the margins). But it seems as if every column gets a equal width. So that the Day, Date, Time and Duration columns are much wider than they need to be and the Notes column is much narrower than it need to be. These two things I couldn't present in the following example table as I wish, but I trust in your imagination ;-) .</p>
  
  <pre class="lang-none prettyprint-override"><code>+-----+----------+---------------+----------+----------------------+
  | Day | Date     | Time          | Duration | Notes                |
  +-----+----------+---------------+----------+----------------------+
  | Tue | 01.04.14 | 14:00 - 17:15 | 3.25     | Here are some notes. |
  +-----+----------+---------------+----------+----------------------+
  | Wed | 02.04.14 | 18:00 - 20:15 | 2.25     | Sometime these       |
  |     |          |               |          | notes are a          |
  |     |          |               |          | little longer        |
  |     |          |               |          | text so there        |
  |     |          |               |          | must be a line       |
  |     |          |               |          | break to let         |
  |     |          |               |          | the whole note       |
  |     |          |               |          | be visible!          |
  +-----+----------+---------------+----------+----------------------+
  | Thu | 02.04.14 | 14:00 - 17:15 | 3.25     | And sometimes        |
  |     |          |               |          | these notes are      |
  |     |          |               |          | only a few words.    |
  +-----+----------+---------------+----------+----------------------+
  </code></pre>
  
  <p>And here is the code I use:</p>
  
  <pre><code>import pipista
  from reportlab.lib.styles import getSampleStyleSheet
  from reportlab.lib.pagesizes import A4
  from reportlab.lib import colors
  from reportlab.platypus import SimpleDocTemplate, Paragraph, Table, TableStyle
  
  styleSheet = getSampleStyleSheet()
  
  def makeReportData(n):
    monthreport = []
    monthreport += ('Day', '', 'Time', 'Duration', 'Notes'),
    monthreport += ('Tue', '01.04.14', '14:00 - 17:15', '3.25', n[0]),
    monthreport += ('Wed', '02.04.14', '14:00 - 17:15', '3.25', n[1]),
    monthreport += ('Thu', '03.04.14', '14:00 - 17:15', '3.25', n[2]),
    return monthreport
  
  notes = ['Here are some notes.',
           'Sometime these notes are a little longer text so there must be a line break to let the whole note be visible!',
           'And sometimes these notes are only a few words.']
  
  paranote = []
  for note in notes:
    paranote += (Paragraph(note, styleSheet["BodyText"]),)
  
  tstyle = [('INNERGRID', (0,0), (-1,-1), 0.25, colors.black),
            ('BOX', (0,0), (-1,-1), 0.25, colors.black),]
  
  case1 = []
  t = Table(makeReportData(notes))
  t.setStyle(TableStyle(tstyle))
  case1.append(t)
  doc = SimpleDocTemplate('Table normal.pdf', pagesize = A4)
  doc.build(case1)
  
  case2 = []
  tstyledez = tstyle + [('ALIGN', (3,1), (3,-1), 'DECIMAL'),]
  t.setStyle(TableStyle(tstyledez))
  case2.append(t)
  doc = SimpleDocTemplate('Table align decimal.pdf', pagesize = A4)
  doc.build(case2)
  
  case3 = []
  t = Table(makeReportData(paranote))
  tstylepara = tstyle + [('VALIGN',(0,1),(3,-1),'TOP'),]
  t.setStyle(TableStyle(tstylepara))
  case3.append(t)
  doc = SimpleDocTemplate('Table Paragraph.pdf', pagesize = A4)
  doc.build(case3)
  </code></pre>
  
  <p>I hope someone can push me in the right direction.</p>