【问题标题】:reportlab.platypus - rendering template with a right aligned image in the template header as backgroundreportlab.platypus - 在模板标题中以右对齐图像作为背景渲染模板
【发布时间】:2012-04-22 04:14:43
【问题描述】:

我正在尝试使用 Reportlab 在一个简单的 Django 应用程序上输出发票。做这样简单的事情似乎很困难。这是我的代码:

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<br/>Via XXX 99<br/> 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+"<br/>"+soggetto.indirizzo+", "+soggetto.cap+" "+soggetto.citta+"<br/>C.F.: "+soggetto.codfisc
if(soggetto.is_privato):
    cliente_ptext += "P.IVA: "+soggetto.piva

prezzo = Prezzo.objects.get(pk=1)

if fattura.riabmot > 0:
    prestazioni.append({'nome':'Rieducazione motoria','qta': fattura.riabmot,'p_unit': prezzo.riabmot,
                        'p_finale': fattura.riabmot * prezzo.riabmot,'id':'riabmot'})
if fattura.riabacq > 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 > 0:
    prestazioni.append({'nome':'Riabilitazione domiciliare','qta': fattura.riabdom,'p_unit': prezzo.riabdom,
                        'p_finale':fattura.riabdom * prezzo.riabdom,'id':'riabdom'})
if fattura.osteo > 0:
    prestazioni.append({'nome':'Osteopatia','qta': fattura.osteo,'p_unit': prezzo.osteo,
                        'p_finale':fattura.osteo * prezzo.osteo,'id':'osteo'})
if fattura.masso > 0:
    prestazioni.append({'nome':'Massoterapia','qta': fattura.masso,'p_unit': prezzo.masso,
                        'p_finale':fattura.masso * prezzo.masso,'id':'masso'})
if fattura.diate > 0:
    prestazioni.append({'nome':'Diatermia','qta': fattura.diate,'p_unit': prezzo.diate,
                             'p_finale':fattura.diate * prezzo.diate,'id':'diate'})
if fattura.laser > 0:
    prestazioni.append({'nome':'Laserterapia','qta': fattura.laser,'p_unit': prezzo.laser,
                            'p_finale':fattura.laser * prezzo.laser,'id':'laser'})
if fattura.usman > 0:
    prestazioni.append({'nome':'US Manuale','qta': fattura.usman,'p_unit': prezzo.usman,
                            'p_finale':fattura.usman * prezzo.usman,'id':'usman'})
if fattura.usacq > 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 > 0:
    prestazioni.append({'nome':'TENS','qta': fattura.tens,'p_unit': prezzo.tens,
                            'p_finale':fattura.tens * prezzo.tens,'id':'usacq'})
if fattura.ets > 0:
    prestazioni.append({'nome':'Elettroterapia stimolante','qta': fattura.ets,'p_unit': prezzo.ets,
                             'p_finale': fattura.ets * prezzo.ets,'id':'ets'})
if fattura.magneto > 0:
    prestazioni.append({'nome':'Magnetoterapia','qta': fattura.magneto,'p_unit': prezzo.magneto,
                            'p_finale':fattura.magneto * prezzo.magneto,'id':'magneto'})
if fattura.iono > 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;

使用此代码,我的标题图像始终呈现在页面中心。我想把它插在右边(比如that),或者更好的是把图片放在右边,把文字放在左边。我已经尝试了很多方法(设置 img 的 hAlign 或 oAlign 属性,在 ParagraphAndImage 可流动的图像中插入图像),但总是出现错误或相同的对齐方式。 什么是正确的方法?

我尝试查看 Reportlab 文档,但对我来说似乎不是很清楚,而且代码 sn-ps 很差。

tnx 给大家,

卢克


感谢您的回复。我已经通过这种方式修改了代码:

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<br/>Via Sant\'Isaia 99<br/>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+"<br/>"+soggetto.indirizzo+", "+soggetto.cap+" "+soggetto.citta+"<br/>C.F.: "+soggetto.codfisc
if(soggetto.is_privato):
    cliente_ptext += "P.IVA: "+soggetto.piva

prezzo = Prezzo.objects.get(pk=1)

prestazioni = []
if fattura.riabmot > 0:
    prestazioni.append({'nome':'Rieducazione motoria','qta': fattura.riabmot,'p_unit': prezzo.riabmot,
                        'p_finale': fattura.riabmot * prezzo.riabmot,'id':'riabmot'})
if fattura.riabacq > 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 > 0:
    prestazioni.append({'nome':'Riabilitazione domiciliare','qta': fattura.riabdom,'p_unit': prezzo.riabdom,
                        'p_finale':fattura.riabdom * prezzo.riabdom,'id':'riabdom'})
if fattura.osteo > 0:
    prestazioni.append({'nome':'Osteopatia','qta': fattura.osteo,'p_unit': prezzo.osteo,
                        'p_finale':fattura.osteo * prezzo.osteo,'id':'osteo'})
if fattura.masso > 0:
    prestazioni.append({'nome':'Massoterapia','qta': fattura.masso,'p_unit': prezzo.masso,
                        'p_finale':fattura.masso * prezzo.masso,'id':'masso'})
if fattura.diate > 0:
    prestazioni.append({'nome':'Diatermia','qta': fattura.diate,'p_unit': prezzo.diate,
                             'p_finale':fattura.diate * prezzo.diate,'id':'diate'})
if fattura.laser > 0:
    prestazioni.append({'nome':'Laserterapia','qta': fattura.laser,'p_unit': prezzo.laser,
                            'p_finale':fattura.laser * prezzo.laser,'id':'laser'})
if fattura.usman > 0:
    prestazioni.append({'nome':'US Manuale','qta': fattura.usman,'p_unit': prezzo.usman,
                            'p_finale':fattura.usman * prezzo.usman,'id':'usman'})
if fattura.usacq > 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 > 0:
    prestazioni.append({'nome':'TENS','qta': fattura.tens,'p_unit': prezzo.tens,
                            'p_finale':fattura.tens * prezzo.tens,'id':'usacq'})
if fattura.ets > 0:
    prestazioni.append({'nome':'Elettroterapia stimolante','qta': fattura.ets,'p_unit': prezzo.ets,
                             'p_finale': fattura.ets * prezzo.ets,'id':'ets'})
if fattura.magneto > 0:
    prestazioni.append({'nome':'Magnetoterapia','qta': fattura.magneto,'p_unit': prezzo.magneto,
                            'p_finale':fattura.magneto * prezzo.magneto,'id':'magneto'})
if fattura.iono > 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

但它仍然不起作用。问题似乎在这部分:

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"]))

我收到以下错误:

/fattura/pdf/ 处的 AttributeError “dict”对象没有属性“saveState”

删除该部分代码有效。有什么帮助吗?

【问题讨论】:

    标签: python django pdf-generation django-views reportlab


    【解决方案1】:

    如果您使用的是鸭嘴兽,则需要在页面上设置框架。然后您可以指定将特定内容放入页面的哪个框架。在您的情况下,这就像设置一个框架来包含图像,然后设置一个框架来包含内容。然后,您可以从框架中构建页面模板,并在生成它们时将这些页面模板应用于特定页面。这是在 ReportLab 中使用鸭嘴兽进行复杂布局的一般模式。

    【讨论】:

      【解决方案2】:

      我正在努力实现这一目标。查看当前的source code,我想出了以下解决方案:

      from reportlab.platypus import Image
      
      class AlignedImage(Image):
          def __init__(self, filename, hAlign='CENTER', **kwargs):
              Image.__init__(self, filename, **kwargs)
              self.hAlign = hAlign
      
      # simply use it like this ('LEFT' can also be used):
      my_image = AlignedImage('/foo/bar.png', hAlign='RIGHT')
      

      所有需要的代码都已经在这里了;我有reported the issue直接在Image类中添加这个参数。

      【讨论】:

        【解决方案3】:

        看起来现在在那里!

        from reportlab.platypus import SimpleDocTemplate, Paragraph, Image, HRFlowable
        
        ss = reportlab.lib.styles.getSampleStyleSheet() 
        p1 = Paragraph("Title", ss['Heading1'])                                                                    
        p2 = Paragraph("normal paragraph", ss['BodyText'])                                                         
        p3 = HRFlowable(width="100%")  
        p4 = Image("/home/usr/Downloads/me.jpg", width=100, height=75, hAlign="LEFT")                  
                
        flo = [p4,p3,p1,p3,p2]  
        pdf = SimpleDocTemplate("test.pdf") 
        pdf.showboundary = 1
        pdf.build(flo)
        

        【讨论】:

        • 欢迎来到 StackOverflow。虽然这段代码可以解决问题,including an explanation 解决问题的方式和原因确实有助于提高帖子的质量,并可能导致更多的赞成票。请记住,您正在为将来的读者回答问题,而不仅仅是现在提问的人。请编辑您的答案以添加解释并说明适用的限制和假设。
        猜你喜欢
        • 2017-04-26
        • 2023-03-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-03-04
        • 1970-01-01
        相关资源
        最近更新 更多