title: reportlab.platypus - rendering template with a right aligned image in the template header as background
body: <p>i'm tryng to use Reportlab to output an invoice on a simple Django app. it seems quite difficult to do simple things like this. here's my code:</p>
  
  <pre><code>def print_pdf(fattura, soggetto, buffer=None):
  
  import time
  from reportlab.lib.enums import TA_LEFT, TA_CENTER, TA_RIGHT, TA_JUSTIFY
  from reportlab.lib.pagesizes import letter
  from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer, Image, ParagraphAndImage
  from reportlab.lib.styles import ParagraphStyle, getSampleStyleSheet
  from reportlab.lib.units import inch
  
  static_files_dir_path = settings.SITE_ROOT+'/'+settings.CURRENT_APP_NAME+settings.STATIC_URL+'user/images/';
  img_file = 'Logo_effetti.jpg'
  img_height = 75
  img_width = 99
  
  str_data_fatt = (fattura.data).strftime('%d/%m/%Y')
  fattura_file_name = str('fattura_'+str_data_fatt+'_'+str(fattura.soggetto)+'.pdf')
  
  img = Image(static_files_dir_path+img_file, img_width, img_height)
  
  styles = getSampleStyleSheet()
  normalStyle = styles["Normal"]
  
  nfattura_ptext = 'numero fattura: '+str(fattura.numerofattura)
  
  if buffer:
      doc = SimpleDocTemplate(buffer, pagesize=letter)
  else:
      doc = SimpleDocTemplate(fattura_file_name, pagesize=letter)
  elems = []
  
  intestazione_studio_ptext = 'Studio AAA&lt;br/&gt;Via XXX 99&lt;br/&gt; 20202 DDDDDDD'
  prestazioni = []
  
  elems.append(Paragraph(intestazione_studio_ptext, styles["Normal"]))
  elems.append(Spacer(1,12))
  elems.append(Spacer(1,12))
  elems.append(Spacer(1,12))
  
  elems.append(Paragraph(nfattura_ptext, styles["Normal"]))
  cliente_ptext = soggetto.nome+" "+soggetto.cognome+"&lt;br/&gt;"+soggetto.indirizzo+", "+soggetto.cap+" "+soggetto.citta+"&lt;br/&gt;C.F.: "+soggetto.codfisc
  if(soggetto.is_privato):
      cliente_ptext += "P.IVA: "+soggetto.piva
  
  prezzo = Prezzo.objects.get(pk=1)
  
  if fattura.riabmot &gt; 0:
      prestazioni.append({'nome':'Rieducazione motoria','qta': fattura.riabmot,'p_unit': prezzo.riabmot,
                          'p_finale': fattura.riabmot * prezzo.riabmot,'id':'riabmot'})
  if fattura.riabacq &gt; 0:
      prestazioni.append({'nome':'Riabilitazione in acqua','qta': fattura.riabacq,'p_unit': prezzo.riabacq,
                          'p_finale': fattura.riabacq * prezzo.riabacq,'id':'riabacq'})
  if fattura.riabdom &gt; 0:
      prestazioni.append({'nome':'Riabilitazione domiciliare','qta': fattura.riabdom,'p_unit': prezzo.riabdom,
                          'p_finale':fattura.riabdom * prezzo.riabdom,'id':'riabdom'})
  if fattura.osteo &gt; 0:
      prestazioni.append({'nome':'Osteopatia','qta': fattura.osteo,'p_unit': prezzo.osteo,
                          'p_finale':fattura.osteo * prezzo.osteo,'id':'osteo'})
  if fattura.masso &gt; 0:
      prestazioni.append({'nome':'Massoterapia','qta': fattura.masso,'p_unit': prezzo.masso,
                          'p_finale':fattura.masso * prezzo.masso,'id':'masso'})
  if fattura.diate &gt; 0:
      prestazioni.append({'nome':'Diatermia','qta': fattura.diate,'p_unit': prezzo.diate,
                               'p_finale':fattura.diate * prezzo.diate,'id':'diate'})
  if fattura.laser &gt; 0:
      prestazioni.append({'nome':'Laserterapia','qta': fattura.laser,'p_unit': prezzo.laser,
                              'p_finale':fattura.laser * prezzo.laser,'id':'laser'})
  if fattura.usman &gt; 0:
      prestazioni.append({'nome':'US Manuale','qta': fattura.usman,'p_unit': prezzo.usman,
                              'p_finale':fattura.usman * prezzo.usman,'id':'usman'})
  if fattura.usacq &gt; 0:
      prestazioni.append({'nome':'US in acqua','qta': fattura.usacq,'p_unit': prezzo.usacq,
                              'p_finale':fattura.usacq * prezzo.usacq,'id':'usacq'})
  if fattura.tens &gt; 0:
      prestazioni.append({'nome':'TENS','qta': fattura.tens,'p_unit': prezzo.tens,
                              'p_finale':fattura.tens * prezzo.tens,'id':'usacq'})
  if fattura.ets &gt; 0:
      prestazioni.append({'nome':'Elettroterapia stimolante','qta': fattura.ets,'p_unit': prezzo.ets,
                               'p_finale': fattura.ets * prezzo.ets,'id':'ets'})
  if fattura.magneto &gt; 0:
      prestazioni.append({'nome':'Magnetoterapia','qta': fattura.magneto,'p_unit': prezzo.magneto,
                              'p_finale':fattura.magneto * prezzo.magneto,'id':'magneto'})
  if fattura.iono &gt; 0:
      prestazioni.append({'nome':'Ionoforesi','qta': fattura.iono,'p_unit': prezzo.iono,
                              'p_finale':fattura.iono * prezzo.iono,'id':'iono'})
  
  totale = 0
  totale += fattura.diate * prezzo.diate
  totale += fattura.ets * prezzo.ets
  totale += fattura.iono * prezzo.iono
  totale += fattura.tens * prezzo.tens
  totale += fattura.laser * prezzo.laser
  totale += fattura.magneto * prezzo.magneto
  totale += fattura.masso * prezzo.masso
  totale += fattura.usacq * prezzo.usacq
  totale += fattura.usman * prezzo.usman
  totale += fattura.osteo * prezzo.osteo
  totale += fattura.riabacq * prezzo.riabacq
  totale += fattura.riabdom * prezzo.riabdom
  totale += fattura.riabmot * prezzo.riabmot
  
  prestazioni_instestazione_ptext = "Prestazione     N.Sedute     Pr. unitario (euro)     Pr. finale (euro)"
  elems.append(Paragraph(prestazioni_instestazione_ptext, styles["Normal"]))
  elems.append(Spacer(1,12))
  for p in prestazioni:
      prestazione_ptext = p['nome']+"     "+str(p['qta'])+"     "+str(p['p_unit'])+"     "+str(p['p_finale'])
      elems.append(Paragraph(prestazione_ptext, styles["Normal"]))
  
  
  elems.append(Spacer(1,12))
  elems.append(Spacer(1,12))
  totale_ptext = "Importo totale: "+str(totale)+" euro"
  elems.append(Paragraph(totale_ptext, styles["Normal"]))
  
  doc.build(elems);
  return buffer;
  </code></pre>
  
  <p>with this code, my header image is always rendered on page center. i want to insert it on the right (like <a href="http://i.imgur.com/0Ahww.png" rel="nofollow">that</a> ) or even better having image on the right and text on the left. i've tried in many ways (setting the hAlign or oAlign propetry of img, inserting image in a ParagraphAndImage flowable) but always i got errors or the same alignment.
  what is the right way? </p>
  
  <p>i've tried to look at Reportlab documentation but seems not so clear to me and poor of code snippets.</p>
  
  <p>tnx to everyone,</p>
  
  <p>LuKe</p>
  
  <hr>
  
  <p>thanks for your reply. i've modified the code by this way:</p>
  
  <pre><code>def print_fatt_pdf(fattura, soggetto, buffer=None):
  
  import time
  from reportlab.lib.enums import TA_LEFT, TA_CENTER, TA_RIGHT, TA_JUSTIFY
  from reportlab.lib.pagesizes import letter
  from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer
  from reportlab.platypus.frames import Frame
  from reportlab.lib.styles import ParagraphStyle, getSampleStyleSheet
  from reportlab.lib.units import inch, cm
  from PIL import Image
  from reportlab.pdfgen.canvas import Canvas
  
  static_files_dir_path = settings.SITE_ROOT+'/'+settings.CURRENT_APP_NAME+settings.STATIC_URL+'user/images/';
  img_file = 'Logo_effetti.jpg'
  img_height = 75
  img_width = 98
  elems = []
  
  
  str_data_fatt = (fattura.data).strftime('%d/%m/%Y')
  fattura_file_name = str('fattura_'+str_data_fatt+'_'+str(fattura.soggetto)+'.pdf')
  print 'fattura_file_name',fattura_file_name
  
  f = Frame(1.5*cm, 1.5*cm, 6*inch, 9*inch)
  p = Canvas(buffer);
  
  # adding flowables
  styles = getSampleStyleSheet()
  normalStyle = styles["Normal"]
  
  nfattura_ptext = 'numero fattura: '+str(fattura.numerofattura)
  intestazione_studio_ptext = 'Studio Fisiodel&lt;br/&gt;Via Sant\'Isaia 99&lt;br/&gt;20012 Mantegazza di Vanzago (MI)'
  print 'intestazione_studio_ptext type: ',type(intestazione_studio_ptext)
  elems.append(Paragraph(intestazione_studio_ptext, normalStyle))
  elems.append(Spacer(1,12))
  elems.append(Spacer(1,12))
  elems.append(Spacer(1,12))
  
  elems.append(Paragraph(nfattura_ptext, styles["Normal"]))
  cliente_ptext = soggetto.nome+" "+soggetto.cognome+"&lt;br/&gt;"+soggetto.indirizzo+", "+soggetto.cap+" "+soggetto.citta+"&lt;br/&gt;C.F.: "+soggetto.codfisc
  if(soggetto.is_privato):
      cliente_ptext += "P.IVA: "+soggetto.piva
  
  prezzo = Prezzo.objects.get(pk=1)
  
  prestazioni = []
  if fattura.riabmot &gt; 0:
      prestazioni.append({'nome':'Rieducazione motoria','qta': fattura.riabmot,'p_unit': prezzo.riabmot,
                          'p_finale': fattura.riabmot * prezzo.riabmot,'id':'riabmot'})
  if fattura.riabacq &gt; 0:
      prestazioni.append({'nome':'Riabilitazione in acqua','qta': fattura.riabacq,'p_unit': prezzo.riabacq,
                          'p_finale': fattura.riabacq * prezzo.riabacq,'id':'riabacq'})
  if fattura.riabdom &gt; 0:
      prestazioni.append({'nome':'Riabilitazione domiciliare','qta': fattura.riabdom,'p_unit': prezzo.riabdom,
                          'p_finale':fattura.riabdom * prezzo.riabdom,'id':'riabdom'})
  if fattura.osteo &gt; 0:
      prestazioni.append({'nome':'Osteopatia','qta': fattura.osteo,'p_unit': prezzo.osteo,
                          'p_finale':fattura.osteo * prezzo.osteo,'id':'osteo'})
  if fattura.masso &gt; 0:
      prestazioni.append({'nome':'Massoterapia','qta': fattura.masso,'p_unit': prezzo.masso,
                          'p_finale':fattura.masso * prezzo.masso,'id':'masso'})
  if fattura.diate &gt; 0:
      prestazioni.append({'nome':'Diatermia','qta': fattura.diate,'p_unit': prezzo.diate,
                               'p_finale':fattura.diate * prezzo.diate,'id':'diate'})
  if fattura.laser &gt; 0:
      prestazioni.append({'nome':'Laserterapia','qta': fattura.laser,'p_unit': prezzo.laser,
                              'p_finale':fattura.laser * prezzo.laser,'id':'laser'})
  if fattura.usman &gt; 0:
      prestazioni.append({'nome':'US Manuale','qta': fattura.usman,'p_unit': prezzo.usman,
                              'p_finale':fattura.usman * prezzo.usman,'id':'usman'})
  if fattura.usacq &gt; 0:
      prestazioni.append({'nome':'US in acqua','qta': fattura.usacq,'p_unit': prezzo.usacq,
                              'p_finale':fattura.usacq * prezzo.usacq,'id':'usacq'})
  if fattura.tens &gt; 0:
      prestazioni.append({'nome':'TENS','qta': fattura.tens,'p_unit': prezzo.tens,
                              'p_finale':fattura.tens * prezzo.tens,'id':'usacq'})
  if fattura.ets &gt; 0:
      prestazioni.append({'nome':'Elettroterapia stimolante','qta': fattura.ets,'p_unit': prezzo.ets,
                               'p_finale': fattura.ets * prezzo.ets,'id':'ets'})
  if fattura.magneto &gt; 0:
      prestazioni.append({'nome':'Magnetoterapia','qta': fattura.magneto,'p_unit': prezzo.magneto,
                              'p_finale':fattura.magneto * prezzo.magneto,'id':'magneto'})
  if fattura.iono &gt; 0:
      prestazioni.append({'nome':'Ionoforesi','qta': fattura.iono,'p_unit': prezzo.iono,
                              'p_finale':fattura.iono * prezzo.iono,'id':'iono'})
  
  totale = 0
  totale += fattura.diate * prezzo.diate
  totale += fattura.ets * prezzo.ets
  totale += fattura.iono * prezzo.iono
  totale += fattura.tens * prezzo.tens
  totale += fattura.laser * prezzo.laser
  totale += fattura.magneto * prezzo.magneto
  totale += fattura.masso * prezzo.masso
  totale += fattura.usacq * prezzo.usacq
  totale += fattura.usman * prezzo.usman
  totale += fattura.osteo * prezzo.osteo
  totale += fattura.riabacq * prezzo.riabacq
  totale += fattura.riabdom * prezzo.riabdom
  totale += fattura.riabmot * prezzo.riabmot
  
  prestazioni_instestazione_ptext = "Prestazione     N.Sedute     Pr. unitario (euro)     Pr. finale (euro)"
  elems.append(Paragraph(prestazioni_instestazione_ptext, normalStyle))
  elems.append(Spacer(1,12))
  for p in prestazioni:
      prestazione_ptext = str(p['nome']+"     "+str(p['qta'])+"     "+str(p['p_unit'])+"     "+str(p['p_finale']))
      print 'prestazione_ptext type : ',type(prestazione_ptext)
      elems.append(Paragraph(prestazione_ptext, styles["Normal"]))
  
  elems.append(Spacer(1,12))
  elems.append(Spacer(1,12))
  totale_ptext = "Importo totale: "+str(totale)+" euro"
  print 'totale_ptext: ',totale_ptext
  elems.append(Paragraph(totale_ptext, styles["Normal"]))
  
  
  f.addFromList(elems,p)
  p.drawImage(static_files_dir_path+img_file,450,730,img_width,img_height)
  p.save()
  return buffer
  </code></pre>
  
  <p>but it still doesn't work. the issue seems to be on this section:</p>
  
  <pre><code>for p in prestazioni:
      prestazione_ptext = str(p['nome']+"     "+str(p['qta'])+"     "+str(p['p_unit'])+"     "+str(p['p_finale']))
      print 'prestazione_ptext type : ',type(prestazione_ptext)
      elems.append(Paragraph(prestazione_ptext, styles["Normal"]))
  </code></pre>
  
  <p>on which i got the following error: </p>
  
  <p><em>AttributeError at /fattura/pdf/
  'dict' object has no attribute 'saveState'</em></p>
  
  <p>removing that section the code works. any help?</p>