示例#1
0
    def _header_footer(self, canvas, doc):
        """ Renders a header and footer which will be inserted regardless of pdf method"""
        
        # Save the state of our canvas so we can draw on it
        canvas.saveState()
        stylesheet = getSampleStyleSheet()
 
        # Header
        logo = Image("http://www.fabco.la/fabco-seal-1.png", width=1.5*inch, height=1.5*inch)
        logo.hAlign = 'CENTER'
        
        stylesheet['BodyText'].fontSize = 10    
        stylesheet['BodyText'].leading = 14
        stylesheet['BodyText'].leftIndent = 5
        stylesheet['BodyText'].textColor = 'gray'
        
        FabcoAddress = "Fabco Art Services\n166 West Avenue 34\nLos Angeles CA 90031"
                                       
                                       
        project = get_object_or_404(Project, pk=self.pk)
        rightHeader = "Job #%s\nCompletion Date %s" % (project.project_id, project.due_date)
        
        # Build and format Left Header Table:
        leftHeaderData = [[FabcoAddress],
                            [project.client.first_name + ' ' + project.client.last_name+'\n'+project.client.address.street+'\n'+project.client.address.city + ' ' + project.client.address.zip_code], 
                            ]
        leftHeaderTable = Table(leftHeaderData)
        leftHeaderTable.setStyle(TableStyle([
                                            ('LEFTPADDING',(0,0),(0, 1),0),
                                            ('TOPPADDING',(0,1),(0, 1), 30),
                                            ('BOTTOMPADDING',(0,1),(0, 1), 0),                                            
                                            ]))

        # Build and format Header Table:
        headerData = [([leftHeaderTable, logo, rightHeader])]
        headerTable = Table(headerData, colWidths=doc.width/3)
        headerTable.setStyle(TableStyle([
            ('VALIGN', (0, 0), (-3, 0), 'MIDDLE'),
            ('VALIGN', (0, 0), (0, 0), 'TOP'),
            ('ALIGN',(1,0),(1,0),'CENTER'),
            ('ALIGN',(2,0),(2,0),'RIGHT'),
            ('LEFTPADDING',(0,0),(0,0),-1),
            ('RIGHTPADDING',(2,0),(2,0),-1),        
            ]))
        
        
        # find required space | I don't really understand this..    
        w, h = headerTable.wrap(doc.width, doc.height)
        # render to canvas | I also don't really understand this..
        headerTable.drawOn(canvas, doc.leftMargin, doc.height + doc.topMargin - doc.bottomMargin) 
 
        # Footer
        footer = Paragraph('Client Signature: _________________________', stylesheet['Normal'])
        w, h = footer.wrap(doc.width, doc.bottomMargin)
        footer.drawOn(canvas, doc.leftMargin, doc.bottomMargin)
 
        # Release the canvas
        canvas.restoreState()
示例#2
0
文件: pdf.py 项目: pmzhou/phase
 def draw_contract_nb_table(self, canvas):
     data = [
         ('Contract NB', self.transmittal.contract_number),
         ('Phase', ''),
     ]
     table = Table(data, hAlign='LEFT', colWidths=[25 * mm, 25 * mm])
     table.setStyle(self.get_table_style())
     table.wrapOn(canvas, 50 * mm, 50 * mm)
     table.drawOn(canvas, *self.coord(145, 55))
示例#3
0
文件: pdf.py 项目: Talengi/phase
 def draw_contract_nb_table(self, canvas):
     data = [
         ('Contract NB', self.transmittal.contract_number),
         ('Phase', ''),
     ]
     table = Table(data, hAlign='LEFT', colWidths=[25 * mm, 25 * mm])
     table.setStyle(self.get_table_style())
     table.wrapOn(canvas, 50 * mm, 50 * mm)
     table.drawOn(canvas, *self.coord(145, 55))
示例#4
0
文件: views.py 项目: RaynerHM/proRes
	def cabecera(self, request, fecha, pdf):
		usuario = request.user.get_full_name()

		#Utilizamos el archivo logo_django.png que está guardado en la carpeta media/imagenes
		archivo_imagen = settings.MEDIA_ROOT + 'Logo.png'

		#Definimos el tamaño de la imagen a cargar y las coordenadas correspondientes
		pdf.drawImage(archivo_imagen, 30, 700, 120, 90,
			preserveAspectRatio=True
		)
		pdf.setFont("Helvetica", 9)
		# pdf.drawString(550, 770, u"%s" %time.strftime("%x"))
		pdf.drawString(500, 760, u"Fecha:  %s/%s/%s"
			%(fecha.day, fecha.month, fecha.year)
		)
		pdf.drawString(500, 750, u"Hora:           %s:%s"
			%(fecha.hour, fecha.minute)
		)

		#Creamos una tupla de encabezados para neustra tabla
		encabezados = ['Estado de Cuenta'.upper()]

		#Creamos una lista de tuplas que van a contener a las personas
		detalles = [
			('%s, Edificio %s, Apartamento %s'
			%(usuario, p.edificio,
			p.no_apartamento)) for p in
			Residente.objects.filter(id=request.user.id)
		]

		#Establecemos el tamaño de cada una de las columnas de la tabla
		detalle_orden = Table([encabezados] + [detalles],
			rowHeights=50, colWidths=[575]
		)

		#Aplicamos estilos a las celdas de la tabla
		detalle_orden.setStyle(
			TableStyle(
				[
					#La primera fila(encabezados) va a estar centrada
					('VALIGN', (0, 0), (-1, -1), 'MIDDLE'),
					('ALIGN', (0, 0), (0, -1), 'CENTER'),
					('FONTSIZE', (0, 0), (-1, -1), 12),
					('VALIGN', (0, 0), (-1, -1), 'MIDDLE'),
					('ALIGN', (0, 0), (0, 0), 'CENTER'),
					('FONTSIZE', (0, 0), (-1, 0), 16),
					('TEXTCOLOR', (0, 1), (-1, -1), colors.black),
				]
			)
		)

		#Establecemos el tamaño de la hoja que ocupará la tabla
		detalle_orden.wrapOn(pdf, 1000, 800)
		#Definimos la coordenada donde se dibujará la tabla
		detalle_orden.drawOn(pdf, 15, 660)
示例#5
0
 def tabla(self, datos, c):
     encabezados = [["Nombre", "Primer Apellido", "Sergundo Apellido", "Correo", "Nombre Mascota", "Tipo", "Peso"]]
     width,  height = A4
     tabla = Table(encabezados+datos, colWidths=30*mm)
     tabla.setStyle([("VALIGN", (0,0), (-1,-1), "MIDDLE"),
             ("ALIGN", (0,0), (-1,-1), "CENTER"),
             ('INNERGRID', (0,0), (-1,-1), 0.25, colors.black), 
             ('FONT', (0,0), (-1,0), 'Times-Bold'), 
             ('FONTSIZE', (0,0),(-1,-1), 10)])
     tabla.wrapOn(c, width, height)
     tabla.drawOn(c, 0, 520)
示例#6
0
    def set_common_per_page(self, canvas, doc):
        PAGE_WIDTH, PAGE_HEIGHT = pagesizes.A4
        PDF_HEADER_FONT_SIZE = 8

        canvas.saveState()

        # header
        string = self.set_header_string()
        canvas.setFont(self.FONT_MEIRYO, PDF_HEADER_FONT_SIZE)
        canvas.drawCentredString((PAGE_WIDTH / 2.0), (PAGE_HEIGHT - 20), string)

        # footer
        string = self.set_footer_string()
        canvas.setFont(self.FONT_MEIRYO, PDF_HEADER_FONT_SIZE)
        canvas.drawCentredString((PAGE_WIDTH / 2.0), 20, string)

        # 左上: アイコン
        image_path = django_settings.PDF_IMAGE_DIR + 'apple-icon-180x180.png'
        canvas.drawImage(image_path, 10*mm, 285*mm, width=10*mm, height=10*mm, preserveAspectRatio=True, mask=[0, 0, 0, 0, 0, 0])

        # 右上: TLP表記
        string = 'TLP: %s' % (self.feed.tlp.upper())
        # Tableにて実装
        data = [[string], ]
        table = Table(data)
        if self.feed.tlp.upper() == 'RED':
            color = '#FF0033'
        elif self.feed.tlp.upper() == 'AMBER':
            color = '#FFC000'
        elif self.feed.tlp.upper() == 'GREEN':
            color = '#33FF00'
        else:
            color = '#FFFFFF'

        table.setStyle(TableStyle([
            # 背景色は黒
            ('BACKGROUND', (0, 0), (-1, -1), colors.black),
            # テキスト色はTLPによって異なる
            ('TEXTCOLOR', (0, 0), (-1, -1), color),
            # 表で使うフォントとそのサイズを設定
            ('FONT', (0, 0), (-1, -1), self.FONT_MEIRYO, 9),
            # ('FONT', (0, 0), (-1, -1), 'CJK', 9),
            # 四角に罫線を引いて、0.5の太さで、色は黒
            ('BOX', (0, 0), (-1, -1), 1, colors.black),
            # 四角の内側に格子状の罫線を引いて、0.25の太さで、色は赤
            ('INNERGRID', (0, 0), (-1, -1), 0.25, colors.black),
            # セルの縦文字位置を、TOPにする
            ('VALIGN', (0, 0), (-1, -1), 'TOP'),
        ]))
        # 配置位置
        table.wrapOn(canvas, 180*mm, 287*mm)
        table.drawOn(canvas, 180*mm, 287*mm)

        canvas.restoreState()
示例#7
0
文件: pdf.py 项目: jswope00/griffinx
    def draw_totals(self, y_pos):
        """
        Draws the boxes containing the totals and the tax id.
        """
        totals_data = [[(_('Total')), self.total_cost],
                       [(_('Payment Received')), self.payment_received],
                       [(_('Balance')), self.balance]]

        if self.is_invoice:
            # only print TaxID if we are generating an Invoice
            totals_data.append([
                '', '{tax_label}:  {tax_id}'.format(tax_label=self.tax_label,
                                                    tax_id=self.tax_id)
            ])

        heights = 8 * mm
        totals_table = Table(totals_data, 40 * mm, heights)

        styles = [
            # Styling for the totals table.
            ('ALIGN', (0, 0), (-1, -1), 'RIGHT'),
            ('VALIGN', (0, 0), (-1, -1), 'MIDDLE'),
            ('TEXTCOLOR', (0, 0), (-1, -1), colors.black),

            # Styling for the Amounts cells
            # NOTE: since we are not printing the TaxID for Credit Card
            # based receipts, we need to change the cell range for
            # these formatting rules
            ('RIGHTPADDING', (-1, 0), (-1, -2 if self.is_invoice else -1),
             7 * mm),
            ('GRID', (-1, 0), (-1, -2 if self.is_invoice else -1), 3.0,
             colors.white),
            ('BACKGROUND', (-1, 0), (-1, -2 if self.is_invoice else -1),
             '#EEEEEE'),
        ]

        totals_table.setStyle(TableStyle(styles))

        __, rendered_height = totals_table.wrap(0, 0)

        left_padding = 97 * mm
        if y_pos - (self.margin + self.min_clearance) <= rendered_height:
            # if space left on page is smaller than the rendered height, render the table on the next page.
            self.prepare_new_page()
            totals_table.drawOn(self.pdf, self.margin + left_padding,
                                self.second_page_start_y_pos - rendered_height)
            return self.second_page_start_y_pos - rendered_height - self.min_clearance
        else:
            totals_table.drawOn(self.pdf, self.margin + left_padding,
                                y_pos - rendered_height)
            return y_pos - rendered_height - self.min_clearance
示例#8
0
    def razas(self, pdf):
        #Se crea una lista de tuplas que van a contener los datos de todos los animales
        encabezados = ('Codigo', 'Nombre')
        parametros = [(p.id, p.nombre) for p in Raza.objects.all()]

        t = Table([encabezados] + parametros)
        t.setStyle(
            TableStyle([('GRID', (0, 0), (3, -1), 1, colors.dodgerblue),
                        ('LINEBELOW', (0, 0), (-1, 0), 2, colors.darkblue),
                        ('BACKGROUND', (0, 0), (-1, 0), colors.green)]))

        #Establecemos el tamaño de la hoja que ocupará la tabla
        t.wrapOn(pdf, 640, 480)
        #Definimos la coordenada donde se dibujará la tabla
        t.drawOn(pdf, 200, 200)
示例#9
0
    def tabla(self, pdf):
        #Se crea una lista de tuplas que van a contener los datos de todos los animales
        encabezados = ('Nombre', 'Fecha nacimiento', 'Raza', 'Tipo de Rodeo')
        parametros = [(p.nombre, p.fechanacimiento, p.raza, p.tipo)
                      for p in Animal.objects.all()]

        t = Table([encabezados] + parametros)
        t.setStyle(
            TableStyle([('GRID', (0, 0), (3, -1), 1, colors.dodgerblue),
                        ('LINEBELOW', (0, 0), (-1, 0), 2, colors.darkblue),
                        ('BACKGROUND', (0, 0), (-1, 0), colors.green)]))
        #Establecemos el tamaño de la hoja que ocupará la tabla
        t.wrapOn(pdf, 50, 80)
        #Definimos la coordenada donde se dibujará la tabla
        t.drawOn(pdf, 140, 280)
示例#10
0
    def tabla(self, pdf, y):
        encabezados = ('Nombre', 'Placa', 'Dia', 'Valor')
        model = Alquiler

        detalles = [(persona.idcliente, persona.idcar, persona.Fecha_Salida,
                     persona.valor) for persona in model.objects.filter()]
        detalle_orden = Table([encabezados] + detalles,
                              colWidths=[2 * cm, 5 * cm, 5 * cm, 5 * cm])
        detalle_orden.setStyle(
            TableStyle([
                ('ALIGN', (0, 0), (3, 0), 'CENTER'),
                ('GRID', (0, 0), (-1, -1), 1, colors.black),
                ('FONTSIZE', (0, 0), (-1, -1), 10),
            ]))
        detalle_orden.wrapOn(pdf, 800, 600)
        detalle_orden.drawOn(pdf, 60, y)
示例#11
0
    def pdf_drawTable(self,
                      table_data,
                      table_style=[],
                      x=45,
                      y=800,
                      table_width=2460,
                      table_height=300,
                      font_size=50,
                      colWidths=[]):
        '''
            @example:

                    table_data = []
                    table_data.append(['Rank','Total Entries','Occupancy','Exit_number','Percenty'])
                    table_data.append(["1",'11','555','1251','22'])
                    self.pdf_drawTable(table_data)
        '''

        if len(colWidths) == 0:
            colWidths = self.get_table_column_width_list(
                table_data, table_width)
        try:
            rowHeights = int(table_height / (len(table_data)))
        except ZeroDivisionError as e:
            raise e
            return
        table_object = Table(table_data, colWidths, rowHeights)
        # (column,row)
        table_basic_stylesheet = [
            ('INNERGRID', (0, 0), (-1, -1), 0.25, colors.white),
            ('TEXTCOLOR', (0, 0), (-1, 0), colors.white),
            ('ALIGN', (0, 0), (-1, -1), 'CENTRE'),
            ('VALIGN', (0, 0), (-1, -1), 'MIDDLE'),
            ('BOTTOMPADDING', (0, 0), (-1, -1), 55),
            ('FONT', (0, 0), (-1, 0), FONTBLOD),
            ('FONT', (0, 1), (-1, -1), FONT),
            ('FONTSIZE', (0, 0), (-1, -1), font_size),
            ('BACKGROUND', (0, 0), (-1, 0), HexColor(0X4472c4)),
            ('BACKGROUND', (0, 1), (-1, -1), HexColor(0xE9ECF6)),
        ]
        for i in table_style:
            table_basic_stylesheet.append(i)
        table_stylesheet = TableStyle(table_basic_stylesheet)
        table_object.setStyle(table_stylesheet)
        table_object.wrapOn(self.pdf_page_object, 0, 0)
        y = self.pdf_config_object.pdf_height - y
        table_object.drawOn(self.pdf_page_object, x, y)
示例#12
0
    def draw_totals(self, y_pos):
        """
        Draws the boxes containing the totals and the tax id.
        """
        totals_data = [
            [(_('Total')), self.total_cost],
            [(_('Payment Received')), self.payment_received],
            [(_('Balance')), self.balance]
        ]

        if self.is_invoice:
            # only print TaxID if we are generating an Invoice
            totals_data.append(
                ['', u'{tax_label}:  {tax_id}'.format(tax_label=self.tax_label, tax_id=self.tax_id)]
            )

        heights = 8 * mm
        totals_table = Table(totals_data, 40 * mm, heights)

        styles = [
            # Styling for the totals table.
            ('ALIGN', (0, 0), (-1, -1), 'RIGHT'),
            ('VALIGN', (0, 0), (-1, -1), 'MIDDLE'),
            ('TEXTCOLOR', (0, 0), (-1, -1), colors.black),

            # Styling for the Amounts cells
            # NOTE: since we are not printing the TaxID for Credit Card
            # based receipts, we need to change the cell range for
            # these formatting rules
            ('RIGHTPADDING', (-1, 0), (-1, 2), 7 * mm),
            ('GRID', (-1, 0), (-1, 2), 3.0, colors.white),
            ('BACKGROUND', (-1, 0), (-1, 2), '#EEEEEE'),
        ]

        totals_table.setStyle(TableStyle(styles))

        __, rendered_height = totals_table.wrap(0, 0)

        left_padding = 97 * mm
        if y_pos - (self.margin + self.min_clearance) <= rendered_height:
            # if space left on page is smaller than the rendered height, render the table on the next page.
            self.prepare_new_page()
            totals_table.drawOn(self.pdf, self.margin + left_padding, self.second_page_start_y_pos - rendered_height)
            return self.second_page_start_y_pos - rendered_height - self.min_clearance
        else:
            totals_table.drawOn(self.pdf, self.margin + left_padding, y_pos - rendered_height)
            return y_pos - rendered_height - self.min_clearance
示例#13
0
 def CreatePdfNum(self,s,num):
     x = 0
     salt = ''.join(random.sample(string.ascii_letters + string.digits, 16))
     #pdfmetrics.registerFont(TTFont('hei', 'hei.TTF'))
     #import testSubFun
     #testSubFun.testSubFunc('first')
     #设置页面大小
     c = canvas.Canvas('Result\\dlp%s.pdf' % num,pagesize=A4)
     xlength,ylength = A4
     #print('width:%d high:%d'%(xlength,ylength))
     #c.line(1,1,ylength/2,ylength)
     #设置文字类型及字号
     #c.setFont('hei',20)
     #生成一个table表格
     atable = [[1,2,3,4,5,6,7,8],[11,12,13,14,15,16,17,18]]
     t = Table(atable,50,20)
     t.setStyle(TableStyle([('ALIGN',(0,0),(3,1),'CENTER'),
                            ('INNERGRID',(0,0),(-1,-1),0.25,colors.black),
                            ('BOX',(0,0),(-1,-1),0.25,colors.black)]))
     textOb = c.beginText(1,ylength-10)
     indexVlaue = 0
     while(indexVlaue < ylength):
         textStr = u'''wo shi tupian---wo shi tupian--wo shi tupian--wo shi tupian%d'''%indexVlaue + salt
         #print('nextline,nextline%d'%indexVlaue)
         textOb.textLine(textStr)
         indexVlaue = indexVlaue + 1
         break
     c.drawText(textOb)
     
     #简单的图片载入
     imageValue = 'file\\dlp.png'
     c.drawImage(imageValue,97,97,650,650)
     #c.drawImage('file\\dlp.png',50,50,50,50)
     t.split(0,0)
     t.drawOn(c,100,1)
     c.showPage()
     #换页的方式不同的showPage
     while x < s:
         imageValue = 'file\\dlp.png'
         c.drawImage(imageValue,97,97,650,650)
         c.drawString(0,0,'tupian%s' % x)
         c.showPage()
         x = x + 1
     c.save()
示例#14
0
文件: views.py 项目: RaynerHM/proRes
	def tabla(self, request, pago, pdf, y):
		#Creamos una tupla de encabezados para neustra tabla
		encabezados = ('FECHA', 'PAGO', 'CONCEPTO', 'PENDIENTE',
					   'RECARGO', 'CONCEPTO RECARGO')
		#Creamos una lista de tuplas que van a contener a las personas
		detalles = [(p.fecha, 'RD$%s%s' %(p.pagos, '.00'),
			p.concepto, 'RD$%s%s' %(p.deuda_pendiente, '.00'), 'RD$%s%s'
			%(p.recargo, '.00'), p.concepto_deuda) for p in pago
		]

		#Establecemos el tamaño de cada una de las columnas de la tabla
		detalle_orden = Table(
			[encabezados] + detalles, rowHeights=15, colWidths=
			[
				12 * 5,
				15 * 5,
				30 * 5,
				15 * 5,
				15 * 5,
				30 * 5
			]
		)
		#Aplicamos estilos a las celdas de la tabla
		detalle_orden.setStyle(TableStyle(
			[
				#La primera fila(encabezados) va a estar centrada
				('ALIGN', (0, 0), (0, 0), 'CENTER'),
				#Los bordes de todas las celdas serán de color negro y con un grosor de 1
				('INNERGRID', (0, 0), (-1, -1), 0.25, colors.black),
				('BOX', (0, 0), (-1, -1), 0.75, colors.black),
				#El tamaño de las letras de cada una de las celdas será de 10
				('BACKGROUND', (0, 0), (8, 0), colors.lightblue),
				('ALIGN', (0, 0), (-5, -1), 'CENTER'),
				('ALIGN', (4, 0), (-2, -1), 'CENTER'),
				('FONTSIZE', (0, 0), (-1, -1), 7),
				('ALIGN', (0, 0), (-1, 0), 'CENTER'),
				('VALIGN', (0, 0), (-1, -1), 'MIDDLE'),
				('FONTSIZE', (0, 0), (-1, 0), 9),
			]
		))
		#Establecemos el tamaño de la hoja que ocupará la tabla
		detalle_orden.wrapOn(pdf, 1000, 800)
		#Definimos la coordenada donde se dibujará la tabla
		detalle_orden.drawOn(pdf, 15, y)
示例#15
0
文件: views.py 项目: RaynerHM/proRes
	def totales(self, request, pago, pdf, y):
		#Creamos una tupla de encabezados para neustra tabla
		encabezados = ['TOTALES']
		#Creamos una lista de tuplas que van a contener a las personas
		deuda = 0
		deuda_pendiente = 0
		total_pagado = 0

		for p in pago:
			deuda += p.recargo
			deuda_pendiente = (p.deuda_pendiente + p.recargo)
			total_pagado += p.pagos

		detalles = [
			['Total Deuda                                   RD$%s.00' %deuda],
			['Total Deuda Por Recargo             RD$%s.00' %deuda_pendiente],
			['Total Pagado                                 RD$%s.00'
			%total_pagado]
		]
		#Establecemos el tamaño de cada una de las columnas de la tabla
		detalle_orden = Table([encabezados] + detalles,
							  rowHeights=15, colWidths=[43 * 5])
		#Aplicamos estilos a las celdas de la tabla
		detalle_orden.setStyle(
			TableStyle(
				[
					('VALIGN', (0, 0), (-1, -1), 'MIDDLE'),
					('BACKGROUND', (0, 0), (8, 0), colors.lightblue),
					('INNERGRID', (0, 0), (0, 0), 0.25, colors.black),
					('ALIGN', (0, 0), (-1, -1), 'LEFT'),
					('VALIGN', (0, 0), (-1, -1), 'MIDDLE'),
					('ALIGN', (0, 0), (0, 0), 'CENTER'),
					('TEXTCOLOR', (0, 1), (-1, -1), colors.black),
				]
			)
		)
		#Establecemos el tamaño de la hoja que ocupará la tabla
		detalle_orden.wrapOn(pdf, 1000, 800)
		#Definimos la coordenada donde se dibujará la tabla
		detalle_orden.drawOn(pdf, 380, 50)
示例#16
0
def genera_copertina(citazione):
    sfondo = settings.IMG_DIR + 'coperchio_bomboniera2.jpg'

    img_for_print = utils.ImageReader(sfondo)
    print(citazione['canzone'])
    path_file = '%s/copertine/cop_%s%s.pdf' % (settings.DOCDIR, citazione['id_frase'], citazione['canzone'])

    dimensione = (19*units.cm, 27*units.cm)
    c = canvas.Canvas(path_file, pagesize=dimensione)
    c.setFontSize(10)
    c.drawImage(img_for_print, 0, 10, dimensione[0], dimensione[1])


    tabella_testo = [
        [
            par_nero('...{citazione}...'.format(**citazione), font=citazione['font'], lead=citazione['lead'], fontName='mvboli', align=TA_CENTER)
        ],
        [
            par_nero("<i></i>".format(**citazione), font=15, align=TA_RIGHT, lead= 15)
        ],
        [
            par_nero("<i>{canzone}</i>".format(**citazione), font=15, align=TA_RIGHT, lead= 15)
        ],
        [
            par_nero("{autore}".format(**citazione), font=15, align=TA_RIGHT, lead= 15)
        ],

    ]

    style_row = TableStyle([])
    #style_row.add('LINEABOVE', (0, 0), (-1, 0), 0.25, colors.grey)
    #style_row.add('LINEBELOW', (0, 0), (-1, 0), 0.25, colors.grey)
    #style_row.add('LINEAFTER', (-1, 0), (-1, 0), 0.25, colors.grey)
    #style_row.add('LINEBEFORE', (0, 0), (0, 0), 0.25, colors.grey)

    table = Table(tabella_testo, colWidths=11.5*units.cm, style=style_row)
    table.wrapOn(c, citazione['margin_left']*units.cm, citazione['margin_bottom']*units.cm)
    table.drawOn(c, citazione['margin_left']*units.cm, citazione['margin_bottom']*units.cm)

    c.save()
示例#17
0
    def draw_totals(self, y_pos):
        """
        Draws the boxes containing the totals and the tax id.
        """
        totals_data = [
            [(_('Total')), self.total_cost],
            [(_('Payment Received')), self.payment_received],
            [(_('Balance')), self.balance],
            ['', '{tax_label}:  {tax_id}'.format(tax_label=self.tax_label, tax_id=self.tax_id)]
        ]

        heights = 8 * mm
        totals_table = Table(totals_data, 40 * mm, heights)

        totals_table.setStyle(TableStyle([
            # Styling for the totals table.
            ('ALIGN', (0, 0), (-1, -1), 'RIGHT'),
            ('VALIGN', (0, 0), (-1, -1), 'MIDDLE'),
            ('TEXTCOLOR', (0, 0), (-1, -1), colors.black),

            # Styling for the Amounts cells
            ('RIGHTPADDING', (-1, 0), (-1, -2), 7 * mm),
            ('GRID', (-1, 0), (-1, -2), 3.0, colors.white),
            ('BACKGROUND', (-1, 0), (-1, -2), '#EEEEEE'),
        ]))

        __, rendered_height = totals_table.wrap(0, 0)

        left_padding = 97 * mm
        if y_pos - (self.margin + self.min_clearance) <= rendered_height:
            # if space left on page is smaller than the rendered height, render the table on the next page.
            self.prepare_new_page()
            totals_table.drawOn(self.pdf, self.margin + left_padding, self.second_page_start_y_pos - rendered_height)
            return self.second_page_start_y_pos - rendered_height - self.min_clearance
        else:
            totals_table.drawOn(self.pdf, self.margin + left_padding, y_pos - rendered_height)
            return y_pos - rendered_height - self.min_clearance
	def body_1(start, end,event_time):
		#Body
		data= [['No.', 'Name', 'Cat II', 'Cat III']]
		
		for i in range(start,end):
			#Generate Transaction Id
			transaction_id = str(event_id)+event_date+event_time+str(i)
			transaction_id = filter(str.isalnum, str(transaction_id))

			luhn = generate(transaction_id)
			transaction_id = str(transaction_id)+luhn
			
			data.append([str(i)+','+luhn,'','','']) #####
			   

		tstyle = [('INNERGRID', (0,0), (-1,-1), 0.25, colors.black),
				  ('BOX', (0,0), (-1,-1), 0.25, colors.black),]
			   
		t = Table(data, colWidths=(3*cm, 4*cm, 6*cm, 6*cm))
		t.setStyle(TableStyle(tstyle))
		t.wrapOn(c, 1*cm, 0*cm)
		t.drawOn(c, 1*cm, 1*cm)

		c.showPage()
示例#19
0
class DelayedTable(Table):
    """A flowable that inserts a table for which it has the data.

    Needed so column widths can be determined after we know on what frame
    the table will be inserted, thus making the overal table width correct.

    """
    def __init__(self,
                 data,
                 colWidths,
                 style=None,
                 repeatrows=False,
                 splitByRow=True):
        self.data = data
        self._colWidths = colWidths
        if style is None:
            style = TableStyle([
                ('LEFTPADDING', (0, 0), (-1, -1), 0),
                ('RIGHTPADDING', (0, 0), (-1, -1), 0),
                ('TOPPADDING', (0, 0), (-1, -1), 0),
                ('BOTTOMPADDING', (0, 0), (-1, -1), 0),
            ])
        self.style = style
        self.t = None
        self.repeatrows = repeatrows
        self.hAlign = TA_CENTER
        self.splitByRow = splitByRow

    def wrap(self, w, h):
        # Create the table, with the widths from colWidths reinterpreted
        # if needed as percentages of frame/cell/whatever width w is.

        # _tw = w/sum(self.colWidths)
        def adjust(*args, **kwargs):
            kwargs['total'] = w
            return styles.adjustUnits(*args, **kwargs)

        # adjust=functools.partial(styles.adjustUnits, total=w)
        self.colWidths = [adjust(x) for x in self._colWidths]
        # colWidths = [_w * _tw for _w in self.colWidths]
        self.t = Table(
            self.data,
            colWidths=self.colWidths,
            style=self.style,
            repeatRows=self.repeatrows,
            splitByRow=True,
        )
        # splitByRow=self.splitByRow)
        self.t.hAlign = self.hAlign
        return self.t.wrap(w, h)

    def split(self, w, h):
        if self.splitByRow:
            if not self.t:
                self.wrap(w, h)
            return self.t.split(w, h)
        else:
            return []

    def drawOn(self, canvas, x, y, _sW=0):
        self.t.drawOn(canvas, x, y, _sW)

    def identity(self, maxLen=None):
        return "<%s at %s%s%s> containing: %s" % (
            self.__class__.__name__,
            hex(id(self)),
            self._frameName(),
            getattr(self, 'name', '') and
            (' name="%s"' % getattr(self, 'name', '')) or '',
            repr(self.data[0]),
        )[:180]
示例#20
0
def account_to_pdf_export(request, account_id):
    label = 'Информация о счете:'
    item = get_account_data(account_id)
    import datetime
    buffer = io.BytesIO()
    p = canvas.Canvas(buffer)
    datetime_now = datetime.datetime.now()
    datetime_str = datetime.datetime.strftime(datetime_now,
                                              '%d.%m.%Y %H:%M:%S')

    pdfmetrics.registerFont(TTFont('Arial', 'Arial.ttf'))
    p.setFont('Arial', 16)
    p.drawString(
        100, 770,
        'Выписка по счету: "{}" на {}'.format(str(item['info'].name),
                                              datetime_str))
    p.setFont('Arial', 12)
    p.drawString(100, 700, 'Валюта: {}'.format(str(item['info'].currency)))
    p.drawString(
        100, 680, 'Дата создания счета: {}'.format(
            datetime.datetime.strftime(item['info'].datetime,
                                       '%H:%M:%S %d.%m.%Y')))
    p.drawString(100, 660,
                 'Начальный баланс: {}'.format(str(item['info'].amount)))
    p.drawString(100, 640, 'Текущий баланс: {}'.format(str(item['total'])))
    p.drawString(100, 620, 'Таблица операций со счетом:')
    p.setFont('Arial', 8)
    data = []
    data.append(('Категория:', 'Тип операции', 'Дата добавления:', 'Сумма:'))
    data.append(('создание счета', 'начальный баланс', '{}'.format(
        datetime.datetime.strftime(item['info'].datetime,
                                   '%d.%m.%Y %H:%M:%S')),
                 str(item['info'].amount)))

    for data_item in item['data']:
        data.append((
            data_item.category,
            'зачисление' if data_item.prefix == 'income' else 'cписание',
            datetime.datetime.strftime(data_item.datetime,
                                       '%d.%m.%Y %H:%M:%S'),
            data_item.amount,
        ))
    data.append(('', '', 'Итого:', str(item['total'])))
    data_length = len(data)
    width = 300
    height = 100
    x = 100
    y = 500 - data_length * 5
    f = Table(data)

    f.setStyle(
        TableStyle([('FONTNAME', (0, 0), (-1, -1), 'Arial'),
                    ('BOX', (0, 0), (-1, -1), .5, colors.black),
                    ('GRID', (0, 0), (-1, 0), .5, colors.black),
                    ('LINEBEFORE', (0, 0), (-1, -1), .5, colors.black),
                    ('LINEAFTER', (-1, 0), (-1, -1), .5, colors.black),
                    ('LINEBELOW', (0, 'splitlast'), (-1, 'splitlast'), .5,
                     colors.black)]))

    f.wrapOn(p, width, height)
    f.drawOn(p, x, y)
    # <td>
    # {% if data_item.type_of %}
    #     {% if data_item.type_of == '+' %}
    #         <span style="color: green">
    #     {% else %}
    #         <span style="color: red">
    #     {% endif %}
    #     {{ data_item.type_of}}{{ data_item.amount}}</span>
    # {% else %}
    #     {{ data_item.type_of}}{{ data_item.amount}}
    # {% endif %}

    p.showPage()
    p.save()
    buffer.seek(0)
    feliename = 'Отчет_на_{}.pdf'.format(
        datetime.datetime.strftime(datetime_now, '%d%m%Y_%H%M%S'))
    return FileResponse(buffer, as_attachment=True, filename=feliename)
示例#21
0
class TableOfContents(IndexingFlowable):
    """This creates a formatted table of contents.

    It presumes a correct block of data is passed in.
    The data block contains a list of (level, text, pageNumber)
    triplets.  You can supply a paragraph style for each level
    (starting at zero).
    """
    def __init__(self):
        self.entries = []
        self.rightColumnWidth = 72
        self.levelStyles = [
            levelZeroParaStyle, levelOneParaStyle, levelTwoParaStyle,
            levelThreeParaStyle, levelFourParaStyle
        ]
        self.tableStyle = defaultTableStyle
        self._table = None
        self._entries = []
        self._lastEntries = []

    def beforeBuild(self):
        # keep track of the last run
        self._lastEntries = self._entries[:]
        self.clearEntries()

    def isIndexing(self):
        return 1

    def isSatisfied(self):
        return (self._entries == self._lastEntries)

    def notify(self, kind, stuff):
        """The notification hook called to register all kinds of events.

        Here we are interested in 'TOCEntry' events only.
        """
        if kind == 'TOCEntry':
            (level, text, pageNum) = stuff
            self.addEntry(level, text, pageNum)

    def clearEntries(self):
        self._entries = []

    def addEntry(self, level, text, pageNum):
        """Adds one entry to the table of contents.

        This allows incremental buildup by a doctemplate.
        Requires that enough styles are defined."""

        assert type(level) == type(1), "Level must be an integer"
        assert level < len(self.levelStyles), \
               "Table of contents must have a style defined " \
               "for paragraph level %d before you add an entry" % level

        self._entries.append((level, text, pageNum))

    def addEntries(self, listOfEntries):
        """Bulk creation of entries in the table of contents.

        If you knew the titles but not the page numbers, you could
        supply them to get sensible output on the first run."""

        for (level, text, pageNum) in listOfEntries:
            self.addEntry(level, text, pageNum)

    def wrap(self, availWidth, availHeight):
        "All table properties should be known by now."

        widths = (availWidth - self.rightColumnWidth, self.rightColumnWidth)

        # makes an internal table which does all the work.
        # we draw the LAST RUN's entries!  If there are
        # none, we make some dummy data to keep the table
        # from complaining
        if len(self._lastEntries) == 0:
            _tempEntries = [(0, 'Placeholder for table of contents', 0)]
        else:
            _tempEntries = self._lastEntries

        tableData = []
        for (level, text, pageNum) in _tempEntries:
            leftColStyle = self.levelStyles[level]
            #right col style is right aligned
            rightColStyle = ParagraphStyle(name='leftColLevel%d' % level,
                                           parent=leftColStyle,
                                           leftIndent=0,
                                           alignment=enums.TA_RIGHT)
            leftPara = Paragraph(text, leftColStyle)
            rightPara = Paragraph(str(pageNum), rightColStyle)
            tableData.append([leftPara, rightPara])

        self._table = Table(tableData, colWidths=widths, style=self.tableStyle)

        self.width, self.height = self._table.wrapOn(self.canv, availWidth,
                                                     availHeight)
        return (self.width, self.height)

    def split(self, availWidth, availHeight):
        """At this stage we do not care about splitting the entries,
        we will just return a list of platypus tables.  Presumably the
        calling app has a pointer to the original TableOfContents object;
        Platypus just sees tables.
        """
        return self._table.splitOn(self.canv, availWidth, availHeight)

    def drawOn(self, canvas, x, y, _sW=0):
        """Don't do this at home!  The standard calls for implementing
        draw(); we are hooking this in order to delegate ALL the drawing
        work to the embedded table object.
        """
        self._table.drawOn(canvas, x, y, _sW)
示例#22
0
    def draw_course_info(self, y_pos):
        """
        Draws the main table containing the data items.
        """
        course_items_data = [
            ['', (_('Description')), (_('Quantity')), (_('List Price\nper item')), (_('Discount\nper item')),
             (_('Amount')), '']
        ]
        for row_item in self.items_data:
            course_items_data.append([
                '',
                Paragraph(row_item['item_description'], getSampleStyleSheet()['Normal']),
                row_item['quantity'],
                '{currency}{list_price:.2f}'.format(list_price=row_item['list_price'], currency=self.currency),
                '{currency}{discount:.2f}'.format(discount=row_item['discount'], currency=self.currency),
                '{currency}{item_total:.2f}'.format(item_total=row_item['item_total'], currency=self.currency),
                ''
            ])

        padding_width = 7 * mm
        desc_col_width = 60 * mm
        qty_col_width = 26 * mm
        list_price_col_width = 21 * mm
        discount_col_width = 21 * mm
        amount_col_width = 40 * mm
        course_items_table = Table(
            course_items_data,
            [
                padding_width,
                desc_col_width,
                qty_col_width,
                list_price_col_width,
                discount_col_width,
                amount_col_width,
                padding_width
            ],
            splitByRow=1,
            repeatRows=1
        )

        course_items_table.setStyle(TableStyle([
            #List Price, Discount, Amount data items
            ('ALIGN', (3, 1), (5, -1), 'RIGHT'),

            # Amount header
            ('ALIGN', (5, 0), (5, 0), 'RIGHT'),

            # Amount column (header + data items)
            ('RIGHTPADDING', (5, 0), (5, -1), 7 * mm),

            # Quantity, List Price, Discount header
            ('ALIGN', (2, 0), (4, 0), 'CENTER'),

            # Description header
            ('ALIGN', (1, 0), (1, -1), 'LEFT'),

            # Quantity data items
            ('ALIGN', (2, 1), (2, -1), 'CENTER'),

            # Lines below the header and at the end of the table.
            ('LINEBELOW', (0, 0), (-1, 0), 1.00, '#cccccc'),
            ('LINEBELOW', (0, -1), (-1, -1), 1.00, '#cccccc'),

            # Innergrid around the data rows.
            ('INNERGRID', (1, 1), (-2, -1), 0.50, '#cccccc'),

            # Entire table
            ('VALIGN', (0, 0), (-1, -1), 'MIDDLE'),
            ('TOPPADDING', (0, 0), (-1, -1), 2 * mm),
            ('BOTTOMPADDING', (0, 0), (-1, -1), 2 * mm),
            ('TEXTCOLOR', (0, 0), (-1, -1), colors.black),
        ]))
        rendered_width, rendered_height = course_items_table.wrap(0, 0)
        table_left_padding = (self.page_width - rendered_width) / 2

        split_tables = course_items_table.split(0, self.first_page_available_height)
        if len(split_tables) > 1:
            # The entire Table won't fit in the available space and requires splitting.
            # Draw the part that can fit, start a new page
            # and repeat the process with the rest of the table.
            split_table = split_tables[0]
            __, rendered_height = split_table.wrap(0, 0)
            split_table.drawOn(self.pdf, table_left_padding, y_pos - rendered_height)

            self.prepare_new_page()
            split_tables = split_tables[1].split(0, self.second_page_available_height)
            while len(split_tables) > 1:
                split_table = split_tables[0]
                __, rendered_height = split_table.wrap(0, 0)
                split_table.drawOn(self.pdf, table_left_padding, self.second_page_start_y_pos - rendered_height)

                self.prepare_new_page()
                split_tables = split_tables[1].split(0, self.second_page_available_height)
            split_table = split_tables[0]
            __, rendered_height = split_table.wrap(0, 0)
            split_table.drawOn(self.pdf, table_left_padding, self.second_page_start_y_pos - rendered_height)
        else:
            # Table will fit without the need for splitting.
            course_items_table.drawOn(self.pdf, table_left_padding, y_pos - rendered_height)

        if not self.is_on_first_page():
            y_pos = self.second_page_start_y_pos

        return y_pos - rendered_height - self.min_clearance
示例#23
0
class SimpleIndex(IndexingFlowable):
    """Creates multi level indexes.
    The styling can be cutomized and alphabetic headers turned on and off.
    """

    def __init__(self, **kwargs):
        """
        Constructor of SimpleIndex.
        Accepts the same arguments as the setup method.
        """
        #keep stuff in a dictionary while building
        self._entries = {}
        self._lastEntries = {}
        self._flowable = None
        self.setup(**kwargs)

    def getFormatFunc(self,format):
        try:
            D = {}
            exec('from reportlab.lib.sequencer import _format_%s as formatFunc' % format, D)
            return D['formatFunc']
        except ImportError:
            raise ValueError('Unknown format %r' % format)

    def setup(self, style=None, dot=None, tableStyle=None, headers=True, name=None, format='123', offset=0):
        """
        This method makes it possible to change styling and other parameters on an existing object.
        
        style is the paragraph style to use for index entries.
        dot can either be None or a string. If it's None, entries are immediatly followed by their
            corresponding page numbers. If it's a string, page numbers are aligned on the right side
            of the document and the gap filled with a repeating sequence of the string.
        tableStyle is the style used by the table which the index uses to draw itself. Use this to
            change properties like spacing between elements.
        headers is a boolean. If it is True, alphabetic headers are displayed in the Index when the first
        letter changes. If False, we just output some extra space before the next item 
        name makes it possible to use several indexes in one document. If you want this use this
            parameter to give each index a unique name. You can then index a term by refering to the
            name of the index which it should appear in:
            
                <index item="term" name="myindex" />

        format can be 'I', 'i', '123',  'ABC', 'abc'
        """
        
        if style is None:
            style = ParagraphStyle(name='index',
                                        fontName=_baseFontName,
                                        fontSize=11)
        self.textStyle = style
        self.tableStyle = tableStyle or defaultTableStyle
        self.dot = dot
        self.headers = headers
        if name is None:
            from reportlab.platypus.paraparser import DEFAULT_INDEX_NAME as name
        self.name = name
        self.formatFunc = self.getFormatFunc(format)
        self.offset = offset

    def __call__(self,canv,kind,label):
        try:
            terms, format, offset = decode_label(label)
        except:
            terms = label
            format = offset = None
        if format is None:
            formatFunc = self.formatFunc
        else:
            formatFunc = self.getFormatFunc(format)
        if offset is None:
            offset = self.offset

        terms = commasplit(terms)
        pns = formatFunc(canv.getPageNumber()-offset)
        key = 'ix_%s_%s_p_%s' % (self.name, label, pns)

        info = canv._curr_tx_info
        canv.bookmarkHorizontal(key, info['cur_x'], info['cur_y'] + info['leading'])
        self.addEntry(terms, pns, key)

    def getCanvasMaker(self, canvasmaker=canvas.Canvas):

        def newcanvasmaker(*args, **kwargs):
            from reportlab.pdfgen import canvas
            c = canvasmaker(*args, **kwargs)
            setattr(c,self.name,self)
            return c

        return newcanvasmaker

    def isIndexing(self):
        return 1

    def isSatisfied(self):
        return (self._entries == self._lastEntries)

    def beforeBuild(self):
        # keep track of the last run
        self._lastEntries = self._entries.copy()
        self.clearEntries()

    def clearEntries(self):
        self._entries = {}

    def notify(self, kind, stuff):
        """The notification hook called to register all kinds of events.

        Here we are interested in 'IndexEntry' events only.
        """
        if kind == 'IndexEntry':
            (text, pageNum) = stuff
            self.addEntry(text, pageNum)

    def addEntry(self, text, pageNum, key=None):
        """Allows incremental buildup"""
        self._entries.setdefault(makeTuple(text),set([])).add((pageNum, key))

    def split(self, availWidth, availHeight):
        """At this stage we do not care about splitting the entries,
        we will just return a list of platypus tables.  Presumably the
        calling app has a pointer to the original TableOfContents object;
        Platypus just sees tables.
        """
        return self._flowable.splitOn(self.canv,availWidth, availHeight)

    def _getlastEntries(self, dummy=[(['Placeholder for index'],enumerate((None,)*3))]):
        '''Return the last run's entries!  If there are none, returns dummy.'''
        if not self._lastEntries:
            if self._entries:
                return list(self._entries.items())
            return dummy
        return list(self._lastEntries.items())

    def _build(self,availWidth,availHeight):
        _tempEntries = self._getlastEntries()
        def getkey(seq):
            return [x.upper() for x in seq[0]]
        _tempEntries.sort(key=getkey)
        leveloffset = self.headers and 1 or 0

        def drawIndexEntryEnd(canvas, kind, label):
            '''Callback to draw dots and page numbers after each entry.'''
            style = self.getLevelStyle(leveloffset)
            pages = decode_label(label)
            drawPageNumbers(canvas, style, pages, availWidth, availHeight, self.dot)
        self.canv.drawIndexEntryEnd = drawIndexEntryEnd

        alpha = ''
        tableData = []
        lastTexts = []
        alphaStyle = self.getLevelStyle(0)
        for texts, pageNumbers in _tempEntries:
            texts = list(texts)
            #track when the first character changes; either output some extra
            #space, or the first letter on a row of its own.  We cannot do
            #widow/orphan control, sadly.
            nalpha = texts[0][0].upper()
            if alpha != nalpha:
                alpha = nalpha
                if self.headers:
                    header = alpha
                else:
                    header = ' '
                tableData.append([Spacer(1, alphaStyle.spaceBefore),])
                tableData.append([Paragraph(header, alphaStyle),])
                tableData.append([Spacer(1, alphaStyle.spaceAfter),])

                    
            i, diff = listdiff(lastTexts, texts)
            if diff:
                lastTexts = texts
                texts = texts[i:]
            label = encode_label(list(pageNumbers))
            texts[-1] = '%s<onDraw name="drawIndexEntryEnd" label="%s"/>' % (texts[-1], label)
            for text in texts:
                #Platypus and RML differ on how parsed XML attributes are escaped.  
                #e.g. <index item="M&S"/>.  The only place this seems to bite us is in
                #the index entries so work around it here.
                text = escapeOnce(text)    
                
                style = self.getLevelStyle(i+leveloffset)
                para = Paragraph(text, style)
                if style.spaceBefore:
                    tableData.append([Spacer(1, style.spaceBefore),])
                tableData.append([para,])
                i += 1

        self._flowable = Table(tableData, colWidths=[availWidth], style=self.tableStyle)

    def wrap(self, availWidth, availHeight):
        "All table properties should be known by now."
        self._build(availWidth,availHeight)
        self.width, self.height = self._flowable.wrapOn(self.canv,availWidth, availHeight)
        return self.width, self.height

    def drawOn(self, canvas, x, y, _sW=0):
        """Don't do this at home!  The standard calls for implementing
        draw(); we are hooking this in order to delegate ALL the drawing
        work to the embedded table object.
        """
        self._flowable.drawOn(canvas, x, y, _sW)

    def draw(self):
        t = self._flowable
        ocanv = getattr(t,'canv',None)
        if not ocanv:
            t.canv = self.canv
        try:
            t.draw()
        finally:
            if not ocanv:
                del t.canv

    def getLevelStyle(self, n):
        '''Returns the style for level n, generating and caching styles on demand if not present.'''
        if not hasattr(self.textStyle, '__iter__'):
            self.textStyle = [self.textStyle]
        try:
            return self.textStyle[n]
        except IndexError:
            self.textStyle = list(self.textStyle)
            prevstyle = self.getLevelStyle(n-1)
            self.textStyle.append(ParagraphStyle(
                    name='%s-%d-indented' % (prevstyle.name, n),
                    parent=prevstyle,
                    firstLineIndent = prevstyle.firstLineIndent+.2*cm,
                    leftIndent = prevstyle.leftIndent+.2*cm))
            return self.textStyle[n]
示例#24
0
def transferencia_pdf(request):
    # Create the HttpResponse object with the appropriate PDF headers.
    response = HttpResponse(content_type='application/pdf')
    # Para descargar directo
    #response['Content-Disposition'] = 'attachment; filename=reporte.pdf'
 
    # Create the PDF object, using the response object as its "file."
    buffer = BytesIO()
    p = canvas.Canvas(buffer, A4)

    # Instanciar Cuenta
    tipoCuenta = request.GET['tipocuenta']
    cuentaNumero = request.GET['cuentanumero']
    apellidos = request.GET['apellidosA']
    nombres = request.GET['nombresA']
    direccion = request.GET['direccion']
    telefono = request.GET['telefono']

    fechaTransaccion = request.GET['fecha']
    montoAux = request.GET['monto']
    numCuentaDestinatario = request.GET['numb']
    nombresDestinatario = request.GET['nomb']
    apellidosDestinatario = request.GET['apellb']
    
    # HEADER
    p.setLineWidth(.3)
    p.setFont('Helvetica', 10)
    p.drawString(180, 800, "COOPERATIVA DE AHORRO Y CREDITO")

    p.setFont('Helvetica-Bold', 17)
    p.drawString(160, 780, "COOPERATIVA JONNATHAN")

    p.setFont('Helvetica', 15)
    p.drawString(180, 762, "CUENTA TIPO: " + tipoCuenta)

    p.setFont('Helvetica-Bold', 12)
    p.drawString(30, 730, "Oficina:")

    p.setFont('Helvetica', 12)
    p.drawString(95, 730, "Loja")

    p.setFont('Helvetica-Bold', 12)
    p.drawString(325, 730, "N. de Cuenta: ")
    p.setFont('Helvetica', 12)
    p.drawString(425, 730, cuentaNumero)
    p.line(420, 727, 560, 727)#start X, height end y , height
    
    p.setFont('Helvetica-Bold', 12)
    p.drawString(30, 710, "Nombres:")

    p.setFont('Helvetica', 12)
    p.drawString(95, 710, apellidos + ' ' + nombres)

    p.setFont('Helvetica-Bold', 12)
    p.drawString(30, 690, "Domicilio:")

    p.setFont('Helvetica', 12)
    p.drawString(95, 690, direccion)

    p.setFont('Helvetica-Bold', 12)
    p.drawString(348, 690, "Telefono:")
    p.setFont('Helvetica', 12)
    p.drawString(425, 690, telefono)

    
    # Table header
    styles = getSampleStyleSheet()
    styleBH = styles["Normal"]
    styleBH.alignment = TA_CENTER
    styleBH.fontSize = 10

    fecha = Paragraph('''Fecha Emision''', styleBH)
    cuentaDestino = Paragraph('''Numero de Cuenta''', styleBH)
    destinatario = Paragraph('''Destinatario''', styleBH)
    tipo = Paragraph('''Tipo Operacion''', styleBH)
    monto = Paragraph('''Monto''', styleBH)

    data = []
    data.append([fecha, cuentaDestino, destinatario, tipo, monto])
    data.append([fechaTransaccion, numCuentaDestinatario, nombresDestinatario + apellidosDestinatario, "transferencia",montoAux])
    # Table body
    styleN = styles["BodyText"]
    styleN.alignment = TA_CENTER
    styleN.fontSize = 7

    high = 640
    
    # Table size
    table = Table(data, colWidths=[4.6 * cm, 2.5 * cm, 7 * cm, 3 * cm, 2.3 * cm])
    table.setStyle(TableStyle([# estilos de la tabla
        ('INNERGRID', (0,0), (-1,-1), 0.25, colors.black),
        ('BOX', (0,0), (-1,-1), 0.25, colors.black),
    ]))
    # pdf size
    width, height = A4
    table.wrapOn(p, width, height)
    table.drawOn(p, 30, high)
    # Close the PDF object cleanly, and we're done.
    p.showPage()# save page
    p.save() # save pdf
    # get the value of BytesIO buffer and write response
    pdf = buffer.getvalue()
    buffer.close()
    response.write(pdf)
    return response
示例#25
0
def HeaderFooterPersona(canvas, doc):
    canvas.saveState()
    title = "Reporte de Personas"
    canvas.setTitle(title)

    Story = []
    styles = getSampleStyleSheet()

    archivo_imagen = finders.find('assets/img/logo.jpg')
    canvas.drawImage(archivo_imagen,
                     30,
                     720,
                     width=540,
                     height=100,
                     preserveAspectRatio=True)

    fecha = datetime.now().strftime('%d/%m/%Y ')
    # Estilos de Párrafos
    ta_c = ParagraphStyle(
        'parrafos',
        alignment=TA_CENTER,
        fontSize=10,
        fontName="Helvetica",
    )
    ta_l = ParagraphStyle(
        'parrafos',
        alignment=TA_LEFT,
        fontSize=13,
        fontName="Helvetica-Bold",
    )
    ta_l7 = ParagraphStyle(
        'parrafos',
        alignment=TA_LEFT,
        fontSize=7,
        fontName="Helvetica-Bold",
    )
    ta_r = ParagraphStyle(
        'parrafos',
        alignment=TA_RIGHT,
        fontSize=13,
        fontName="Helvetica-Bold",
    )

    # Header
    header = Paragraph(
        "REPORTE DE PERSONAS ",
        ta_l,
    )
    w, h = header.wrap(doc.width + 250, doc.topMargin)
    header.drawOn(canvas, 215, doc.height - 10 + doc.topMargin - 80)

    #header1 = Paragraph("<u>DIRECCIÓN DE AGRICULTURA Y TIERRA</u> ",ta_r,)
    #w,h = header1.wrap(doc.width-115, doc.topMargin)
    #header1.drawOn(canvas, 140, doc.height -10 + doc.topMargin - 2)

    P1 = Paragraph('''N°''', ta_c)
    P2 = Paragraph('''CEDULA''', ta_c)
    P3 = Paragraph('''NOMBRE''', ta_c)
    P4 = Paragraph('''APELLIDO''', ta_c)
    P5 = Paragraph('''CORREO''', ta_c)
    P6 = Paragraph('''ROL''', ta_c)
    data = [[P1, P2, P3, P4, P5, P6]]
    header2 = Table(data, colWidths=[35, 85, 80, 80, 150, 80])
    header2.setStyle(
        TableStyle([
            ('GRID', (0, -1), (-1, -1), 1, colors.black),
            ('BACKGROUND', (0, 0), (-1, 0), '#50b7e6'),
            ('ALIGN', (0, 0), (-1, -3), "CENTER"),
        ]))
    w, h = header2.wrap(doc.width - 115, doc.topMargin)
    header2.drawOn(canvas, 42.5, doc.height - 40 + doc.topMargin - 93)

    # FOOTER

    footer4 = Paragraph("Fecha: " + str(fecha), ta_l7)
    w, h = footer4.wrap(doc.width - 200, doc.bottomMargin)
    footer4.drawOn(canvas, doc.height - 105, doc.topMargin + 620, h)

    canvas.restoreState()
示例#26
0
    def draw_footer(self, y_pos):
        """
        Draws the footer.
        """

        para_style = getSampleStyleSheet()['Normal']
        para_style.fontSize = 8

        footer_para = Paragraph(self.footer_text.replace("\n", "<br/>"),
                                para_style)
        disclaimer_para = Paragraph(
            self.disclaimer_text.replace("\n", "<br/>"), para_style)
        billing_address_para = Paragraph(
            self.billing_address_text.replace("\n", "<br/>"), para_style)

        footer_data = [['', footer_para], [(_('Billing Address')), ''],
                       ['', billing_address_para], [(_('Disclaimer')), ''],
                       ['', disclaimer_para]]

        footer_style = [
            # Styling for the entire footer table.
            ('ALIGN', (0, 0), (-1, -1), 'LEFT'),
            ('VALIGN', (0, 0), (-1, -1), 'MIDDLE'),
            ('TEXTCOLOR', (0, 0), (-1, -1), colors.black),
            ('FONTSIZE', (0, 0), (-1, -1), 9),
            ('TEXTCOLOR', (0, 0), (-1, -1), '#AAAAAA'),

            # Billing Address Header styling
            ('LEFTPADDING', (0, 1), (0, 1), 5 * mm),

            # Disclaimer Header styling
            ('LEFTPADDING', (0, 3), (0, 3), 5 * mm),
            ('TOPPADDING', (0, 3), (0, 3), 2 * mm),

            # Footer Body styling
            # ('BACKGROUND', (1, 0), (1, 0), '#EEEEEE'),

            # Billing Address Body styling
            ('BACKGROUND', (1, 2), (1, 2), '#EEEEEE'),

            # Disclaimer Body styling
            ('BACKGROUND', (1, 4), (1, 4), '#EEEEEE'),
        ]

        if self.is_invoice:
            terms_conditions_para = Paragraph(
                self.terms_conditions_text.replace("\n", "<br/>"), para_style)
            footer_data.append([(_('TERMS AND CONDITIONS')), ''])
            footer_data.append(['', terms_conditions_para])

            # TERMS AND CONDITIONS header styling
            footer_style.append(('LEFTPADDING', (0, 5), (0, 5), 5 * mm))
            footer_style.append(('TOPPADDING', (0, 5), (0, 5), 2 * mm))

            # TERMS AND CONDITIONS body styling
            footer_style.append(('BACKGROUND', (1, 6), (1, 6), '#EEEEEE'))

        footer_table = Table(footer_data, [5 * mm, 176 * mm])

        footer_table.setStyle(TableStyle(footer_style))
        __, rendered_height = footer_table.wrap(0, 0)

        if y_pos - (self.margin + self.min_clearance) <= rendered_height:
            self.prepare_new_page()

        footer_table.drawOn(self.pdf, self.margin, self.margin + 5 * mm)
示例#27
0
def pdf(request, guid):
    import settings
    import reportlab.pdfgen.canvas
    from reportlab.lib import pagesizes, units, colors, utils
    from reportlab.platypus import Paragraph, Image
    from reportlab.platypus.tables import Table, TableStyle
    from reportlab.lib.styles import ParagraphStyle, getSampleStyleSheet
    from django.contrib.humanize.templatetags.humanize import intcomma

    company = fact.models.Slot.company()
    invoice = get_object_or_404(fact.models.Invoice, pk=guid)
    if not invoice.date_posted or not invoice.date_due:
        return redirect(reverse('fact.views.detailed', kwargs={'guid':guid}))

    response = HttpResponse(mimetype='application/pdf')
    response['Content-Disposition'] = 'attachment; filename=' + _('invoice') + '-' + invoice.id + '.pdf'
    p = reportlab.pdfgen.canvas.Canvas(response, pagesize=pagesizes.A4)
    width, height = pagesizes.A4
    font = 'Helvetica'

    # Load options and payment text
    options = fact.models.Option.opt_list(request.LANGUAGE_CODE)
    for key, value in options.iteritems():
        options['payment_text'] = options['payment_text'].replace('%' + key + '%', value)
    options['payment_text'] = options['payment_text'].replace('\n', '<br/>')

    # Right-hand stuff
    x = units.cm * 14;
    p.setFont(font + '-Bold', 18)
    p.drawString(x, height-(units.cm*4.5), _('Invoice %s') % invoice.id)
    p.setFont(font, 10)
    p.drawString(x, height-(units.cm*5.5), _('Invoice date: %s') % invoice.date_invoice.strftime('%d.%m.%Y'))
    p.drawString(x, height-(units.cm*6), _('Due date: %s') % invoice.date_due.strftime('%d.%m.%Y'))

    # Logo
    img = utils.ImageReader(settings.FACT_LOGO)
    iw, ih = img.getSize()
    aspect = ih / float(iw)
    img = Image(settings.FACT_LOGO, width=units.cm*4, height=units.cm*4*aspect)
    img.drawOn(p, x+(units.cm*1), height-(units.cm*2.25))

    # Left-hand header stuff
    x = units.cm * 2;
    p.setFont(font + '-Oblique', 8)
    p.drawString(x, height-(units.cm*1.25), company['name'])
    address = company['address'].split("\n")
    base = 1.65
    for a in address:
        p.drawString(x, height-(units.cm*base), a)
        base += 0.4


    # Recipient name and address
    y = units.cm*4.5
    base = 0.5
    customer = invoice.customer
    p.setFont(font, 10)
    p.drawString(x, height-y, customer.addr_name); y += units.cm*base
    p.drawString(x, height-y, customer.addr_addr1); y += units.cm*base
    p.drawString(x, height-y, customer.addr_addr2); y += units.cm*base
    p.drawString(x, height-y, customer.addr_addr3); y += units.cm*base
    p.drawString(x, height-y, customer.addr_addr4); y += units.cm*base
    y += units.cm*2

    # Main
    p.setFont(font + '-Bold', 14)
    p.drawString(x, height-y, _('Specification'))
    y += units.cm*1
    p.setFont(font, 10)
    fmt = '{0:.2f}'

    # Get our invoice entries, headers, etc
    style = TableStyle()
    invoice_entries = []
    headers = [_('Description'), _('Amount'), _('Type'), _('Unit price'), _('VAT'), _('Net')]
    style.add('FONT', (0,0), (-1,0), font + '-Bold')
    style.add('LINEBELOW', (0,0), (-1,0), 1, colors.black)
    for entry in invoice.entries:
        invoice_entries.append([
            entry.description,
            intcomma(fmt.format(entry.quantity)),
            _(entry.action),
            intcomma(fmt.format(entry.unitprice)),
            intcomma(fmt.format(entry.tax_percent)) + '%',
            intcomma(fmt.format(entry.net))
        ])
    style.add('LINEBELOW', (0, len(invoice_entries)), (-1, len(invoice_entries)), 1, colors.black)
    sums = []
    sums.append([_('Net'), '', '', '', '', intcomma(fmt.format(invoice.net))])
    sums.append([_('VAT'), '', '', '', '', intcomma(fmt.format(invoice.tax))])
    if invoice.payments.count() > 0:
        sums.append([_('Subtotal'), '', '', '', '', intcomma(fmt.format(invoice.gross))])
        style.add('LINEBELOW', (0, len(invoice_entries)+3), (-1, len(invoice_entries)+3), 1, colors.black)
        for payment in invoice.payments.all():
            sums.append([_('Paid %s') + payment.post_date.strftime('%d.%m.%Y'), '', '', '', '', intcomma(fmt.format(payment.amount))])
        ln = len(invoice_entries) + len(sums)
        style.add('LINEBELOW', (0, ln), (-1, ln), 1, colors.black)
    else:
        style.add('LINEBELOW', (0, len(invoice_entries)+2), (-1, len(invoice_entries)+2), 1, colors.black)
    sums.append([_('Amount due'), '', '', '', '', intcomma(fmt.format(invoice.due))])
    ln = len(invoice_entries) + len(sums)
    style.add('BACKGROUND', (0, ln), (-1, ln), colors.wheat)
    style.add('FONT', (0, ln), (-1, ln), font + '-Bold')
    style.add('LINEBELOW', (0, ln), (-1, ln), 2, colors.black)

    # Draw the table
    t = Table([headers] + invoice_entries + sums,
            ([units.cm*6.5, units.cm*1.75, units.cm*2, units.cm*2.5, units.cm*2, units.cm*2.25])
            )
    t.setStyle(style)
    w, h = t.wrapOn(p, units.cm*19, units.cm*8)
    y += h
    t.drawOn(p, x, height-y)

    # Bank account number
    stylesheet = getSampleStyleSheet()
    if invoice.notes:
        txt = invoice.notes + '<br/><br/>'
    else:
        txt = ''
    txt += options['payment_text']
    pr = Paragraph(txt, stylesheet['BodyText'])
    w, h = pr.wrapOn(p, units.cm*17, units.cm*6)
    y += pr.height + (units.cm*1)
    pr.drawOn(p, x, height-y)

    # Footer stuff
    p.setFont(font + '-BoldOblique', 8)
    p.drawString(x, units.cm*2.8, company['name'])
    p.setFont(font + '-Oblique', 8)
    p.drawString(x, units.cm*2.4, address[0])
    p.drawString(x, units.cm*2, address[1])

    p.drawString(units.cm*8, units.cm*2.4, 'Web: ' + company['url'])
    p.drawString(units.cm*8, units.cm*2, 'E-post: ' + company['email'])

    p.drawString(units.cm*14, units.cm*2.4, 'Telefon: ' + company['phone'])
    p.drawString(units.cm*14, units.cm*2, 'Org.nr: ' + company['id'])

    # Close the PDF object cleanly, and we're done.
    p.showPage()
    p.save()

    return response
示例#28
0
class MasterInfo(Flowable):
    KEYS = {
        'master':
        ['patient', 'date', 'room_number', 'case_number', 'physician'],
        'patient': ['fullname', 'age', 'gender'],
    }

    def process_kwarg(self, data, kwargs):
        for objname in self.KEYS.keys():
            if objname in kwargs.keys():
                o = kwargs[objname]
                for k in self.KEYS[objname]:
                    display = 'get_%s_display' % k
                    if hasattr(o, display):
                        data[k] = getattr(o, display)()
                    else:
                        data[k] = getattr(o, k)
                del kwargs[objname]

        p = data.get('patient', None)
        for k in chain(*self.KEYS.values()):
            if k in kwargs.keys():
                data[k] = kwargs[k]
                del kwargs[k]
            elif p and hasattr(p, k):
                display = 'get_%s_display' % k
                if hasattr(p, display):
                    data[k] = getattr(p, display)()
                else:
                    data[k] = getattr(p, k)

    def __init__(self, **kwargs):
        data = {}
        self.process_kwarg(data, kwargs)

        self.config = {}
        for k in [
                'font', 'fontsize', 'offset', 'width', 'leftmargin',
                'rightmargin'
        ]:
            if k in kwargs:
                # setattr(self, k, kwargs[k])
                self.config[k] = kwargs[k]
                del kwargs[k]

        if len(kwargs):
            raise TypeError("__init__ got an unxepected keyworkd '%s'" %
                            kwargs.keys()[0])
        self.init_table(data)

    def init_table(self, data):

        styles = getSampleStyleSheet()
        sN = styles['Normal']
        if 'font' in self.config:
            sN.fontName = self.config['font']
        if 'fontsize' in self.config:
            sN.fontSize = self.config['fontsize']
            sN.leading = sN.fontSize * 1.1

        cell_data = [["" for x in range(12)] for y in range(3)]
        # Row 1
        cell_data[0][0] = Paragraph(
            "<b>Name:</b><u> %s</u>" % data.get('fullname', 'NO_VALUE'), sN)
        date_type = type(data['date'])
        if date_type in [datetime.datetime, datetime.date]:
            date = datetime.datetime.strftime(data['date'], "%m/%d/%Y")
        else:
            date = data['date']
        cell_data[0][6] = Paragraph("<b>Date:</b><u> %s</u>" % date, sN)
        cell_data[0][9] = Paragraph(
            "<b>Case #:</b><u> %s</u>" % data.get('case_number', 'NO_VALUE'),
            sN)
        # Row 2
        cell_data[1][0] = Paragraph(
            "<b>Room #:</b><u> %s</u>" % data.get('room_number', 'NO_VALUE'),
            sN)
        cell_data[1][4] = Paragraph("<b>Age:</b><u> %s</u>" % data['age'], sN)
        cell_data[1][8] = Paragraph(
            "<b>Sex:</b><u> %s</u>" % data.get('gender', 'NO_VALUE'), sN)
        # Row 3
        cell_data[2][0] = Paragraph(
            "<b>Requesting Physician:</b><u> %s</u>" %
            data.get('physician', 'NO_VALUE'), sN)
        if 'width' in self.config:
            width = self.config['width']
        else:
            width, height = landscape(A5)
            self.config['width'] = width

        lm = self.config.get('leftmargin', 10)
        rm = self.config.get('rightmargin', 10)
        width -= lm + rm

        self.table = Table(cell_data, colWidths=[width / 12] * 12)
        self.table.setStyle(
            TableStyle([
                # ('GRID', (0, 0), (-1, -1), 1, black),
                ('TOPPADDING', (0, 0), (-1, -1), 0),
                ('BOTTOMPADDING', (0, 0), (-1, -1), 0),
                ('BOTTOMPADDING', (0, -1), (0, -1), 3),
                ('LINEBELOW', (0, -1), (-1, -1), 1, black),
                # Row 1
                ('SPAN', (0, 0), (5, 0)),
                ('SPAN', (6, 0), (8, 0)),
                ('SPAN', (9, 0), (11, 0)),
                # Row 2
                ('SPAN', (0, 1), (3, 1)),
                ('SPAN', (4, 1), (7, 1)),
                ('SPAN', (8, 1), (11, 1)),
                # Row 3
                ('SPAN', (0, 2), (11, 2)),
            ]))

    def split(self, availWidth, availHeight):
        return []

    def wrap(self, availWidth, availHeight):
        width, height = self.table.wrap(availWidth, availHeight)
        return (width, height)

    def drawOn(self, canvas, x, y, _sW=0):
        return self.table.drawOn(canvas, x, y, _sW)
示例#29
0
class TableOfContents(IndexingFlowable):
    """This creates a formatted table of contents.

    It presumes a correct block of data is passed in.
    The data block contains a list of (level, text, pageNumber)
    triplets.  You can supply a paragraph style for each level
    (starting at zero).
    Set dotsMinLevel to determine from which level on a line of
    dots should be drawn between the text and the page number.
    If dotsMinLevel is set to a negative value, no dotted lines are drawn.
    """

    def __init__(self):
        self.rightColumnWidth = 72
        self.levelStyles = [levelZeroParaStyle,
                            levelOneParaStyle,
                            levelTwoParaStyle,
                            levelThreeParaStyle,
                            levelFourParaStyle]
        self.tableStyle = defaultTableStyle
        self.dotsMinLevel = 1
        self._table = None
        self._entries = []
        self._lastEntries = []


    def beforeBuild(self):
        # keep track of the last run
        self._lastEntries = self._entries[:]
        self.clearEntries()


    def isIndexing(self):
        return 1


    def isSatisfied(self):
        return (self._entries == self._lastEntries)

    def notify(self, kind, stuff):
        """The notification hook called to register all kinds of events.

        Here we are interested in 'TOCEntry' events only.
        """
        if kind == 'TOCEntry':
            self.addEntry(*stuff)


    def clearEntries(self):
        self._entries = []


    def addEntry(self, level, text, pageNum, key=None):
        """Adds one entry to the table of contents.

        This allows incremental buildup by a doctemplate.
        Requires that enough styles are defined."""

        assert type(level) == type(1), "Level must be an integer"
        assert level < len(self.levelStyles), \
               "Table of contents must have a style defined " \
               "for paragraph level %d before you add an entry" % level

        self._entries.append((level, text, pageNum, key))


    def addEntries(self, listOfEntries):
        """Bulk creation of entries in the table of contents.

        If you knew the titles but not the page numbers, you could
        supply them to get sensible output on the first run."""

        for entryargs in listOfEntries:
            self.addEntry(*entryargs)


    def wrap(self, availWidth, availHeight):
        "All table properties should be known by now."

        # makes an internal table which does all the work.
        # we draw the LAST RUN's entries!  If there are
        # none, we make some dummy data to keep the table
        # from complaining
        if len(self._lastEntries) == 0:
            _tempEntries = [(0,'Placeholder for table of contents',0,None)]
        else:
            _tempEntries = self._lastEntries

        def drawTOCEntryEnd(canvas, kind, label):
            '''Callback to draw dots and page numbers after each entry.'''
            page, level = [ int(x) for x in label.split(',') ]
            x, y = canvas._curr_tx_info['cur_x'], canvas._curr_tx_info['cur_y']
            style = self.levelStyles[level]
            pagew = stringWidth('  %d' % page, style.fontName, style.fontSize)
            if self.dotsMinLevel >= 0 and level >= self.dotsMinLevel:
                dotw = stringWidth(' . ', style.fontName, style.fontSize)
                dotsn = int((availWidth-x-pagew)/dotw)
            else:
                dotsn = dotw = 0

            tx = canvas.beginText(availWidth-pagew-dotsn*dotw, y)
            tx.setFont(style.fontName, style.fontSize)
            tx.textLine('%s  %d' % (dotsn * ' . ', page))
            canvas.drawText(tx)
        self.canv.drawTOCEntryEnd = drawTOCEntryEnd

        tableData = []
        for (level, text, pageNum, key) in _tempEntries:
            style = self.levelStyles[level]
            if key:
                text = '<a href="#%s">%s</a>' % (key, text)
            para = Paragraph('%s<onDraw name="drawTOCEntryEnd" label="%d,%d"/>' % (text, pageNum, level), style)
            if style.spaceBefore:
                tableData.append([Spacer(1, style.spaceBefore),])
            tableData.append([para,])

        self._table = Table(tableData, colWidths=(availWidth,),
                            style=self.tableStyle)

        self.width, self.height = self._table.wrapOn(self.canv,availWidth, availHeight)
        return (self.width, self.height)


    def split(self, availWidth, availHeight):
        """At this stage we do not care about splitting the entries,
        we will just return a list of platypus tables.  Presumably the
        calling app has a pointer to the original TableOfContents object;
        Platypus just sees tables.
        """
        return self._table.splitOn(self.canv,availWidth, availHeight)


    def drawOn(self, canvas, x, y, _sW=0):
        """Don't do this at home!  The standard calls for implementing
        draw(); we are hooking this in order to delegate ALL the drawing
        work to the embedded table object.
        """
        self._table.drawOn(canvas, x, y, _sW)
示例#30
0
	def save(self):
		# We can fit 15 rows on one page. We might want to do something
		# cute to avoid a single row on it's own page in the future, but
		# for now, just split it evenly.
		for pagenum in range(0, (len(self.rows)-1)/15+1):
			self._pageheader()
			islastpage = (pagenum == (len(self.rows)-1)/15)

			if len(self.rows) > 15:
				suffix = " (page %s/%s)" % (pagenum+1, len(self.rows)/15+1)
			else:
				suffix = ''

			# Center between 2 and 19 is 10.5
			if self.invoicenum:
				if self.receipt:
					self.canvas.drawCentredString(10.5*cm,19*cm, "RECEIPT FOR INVOICE NUMBER %s%s" % (self.invoicenum, suffix))
				else:
					self.canvas.drawCentredString(10.5*cm,19*cm, "INVOICE NUMBER %s - %s%s" % (self.invoicenum, self.invoicedate.strftime("%B %d, %Y"),suffix))
			else:
				self.canvas.drawCentredString(10.5*cm,19*cm, "RECEIPT - %s%s" % (self.invoicedate.strftime("%B %d, %Y"), suffix))

			if pagenum == 0:
				tbldata = [["Item", "Price", "Count", "Amount"], ]
			else:
				tbldata = [["Item - continued from page %s" % pagenum, "Price", "count", "amount"], ]

			tbldata.extend([(self.trimstring(title, 10.5*cm, "Times-Roman", 10),
							 "%.2f %s" % (cost, self.currency),
							 count,
							 "%.2f %s" % ((cost * count), self.currency))
							for title,cost, count in self.rows[pagenum*15:(pagenum+1)*15]])
			style = [
					('BACKGROUND',(0,0),(3,0),colors.lightgrey),
					('ALIGN',(1,0),(3,-1),'RIGHT'),
					('LINEBELOW',(0,0),(-1,0), 2, colors.black),
					('OUTLINE', (0,0), (-1, -1), 1, colors.black),
				]
			if islastpage:
				tbldata.append(['','','Total',"%.2f %s" % (sum([cost*count for title,cost,count in self.rows]),self.currency)])
				style.append(('LINEABOVE', (-2,-1), (-1, -1), 2, colors.black))
			else:
				tbldata.append(['          Continued on page %s' % (pagenum + 2), '', '', ''])
				style.append(('ALIGN', (0, -1), (-1, -1), 'CENTER'))
				style.append(('FONT', (0, -1), (-1, -1), 'Times-Italic'))

			t = Table(tbldata, [10.5*cm, 2.5*cm, 1.5*cm, 2.5*cm])
			t.setStyle(TableStyle(style))
			w,h = t.wrapOn(self.canvas,10*cm,10*cm)
			t.drawOn(self.canvas, 2*cm, 18*cm-h)

			if self.receipt:
				self.canvas.drawCentredString(10.5*cm,17.3*cm-h, "This invoice was paid %s" % self.duedate.strftime("%B %d, %Y"))
			else:
				self.canvas.drawCentredString(10.5*cm,17.3*cm-h, "This invoice is due: %s" % self.duedate.strftime("%B %d, %Y"))


			t = self.canvas.beginText()
			t.setTextOrigin(2*cm, 5*cm)
			t.setFont("Times-Italic", 10)
			t.textLine("PostgreSQL Europe is a French non-profit under the French 1901 Law. The association is not VAT registered.")
			t.textLine("")

			if islastpage and self.bankinfo:
				t.setFont("Times-Bold", 10)
				t.textLine("Bank references / Références bancaires / Bankverbindungen / Referencias bancarias")

				t.setFont("Times-Roman", 8)
				t.textLines("""CCM PARIS 1-2 LOUVRE MONTORGUEIL
28 RUE ETIENNE MARCEL
75002 PARIS
FRANCE
IBAN: FR76 1027 8060 3100 0205 2290 114
BIC: CMCIFR2A
""")

			self.canvas.drawText(t)

			# Finish this page off, and optionally loop to another one
			self.canvas.showPage()

		# Last page is finished, flush the PDF output
		self.canvas.save()

		return self.pdfdata
示例#31
0
class TableOfContents(IndexingFlowable):
    """This creates a formatted table of contents.

    It presumes a correct block of data is passed in.
    The data block contains a list of (level, text, pageNumber)
    triplets.  You can supply a paragraph style for each level
    (starting at zero).
    Set dotsMinLevel to determine from which level on a line of
    dots should be drawn between the text and the page number.
    If dotsMinLevel is set to a negative value, no dotted lines are drawn.
    """
    def __init__(self, **kwds):
        self.rightColumnWidth = kwds.pop('rightColumnWidth', 72)
        self.levelStyles = kwds.pop('levelStyles', defaultLevelStyles)
        self.tableStyle = kwds.pop('tableStyle', defaultTableStyle)
        self.dotsMinLevel = kwds.pop('dotsMinLevel', 1)
        self.formatter = kwds.pop('formatter', None)
        if kwds:
            raise ValueError('unexpected keyword arguments %s' %
                             ', '.join(kwds.keys()))
        self._table = None
        self._entries = []
        self._lastEntries = []

    def beforeBuild(self):
        # keep track of the last run
        self._lastEntries = self._entries[:]
        self.clearEntries()

    def isIndexing(self):
        return 1

    def isSatisfied(self):
        return (self._entries == self._lastEntries)

    def notify(self, kind, stuff):
        """The notification hook called to register all kinds of events.

        Here we are interested in 'TOCEntry' events only.
        """
        if kind == 'TOCEntry':
            self.addEntry(*stuff)

    def clearEntries(self):
        self._entries = []

    def getLevelStyle(self, n):
        '''Returns the style for level n, generating and caching styles on demand if not present.'''
        try:
            return self.levelStyles[n]
        except IndexError:
            prevstyle = self.getLevelStyle(n - 1)
            self.levelStyles.append(
                ParagraphStyle(name='%s-%d-indented' % (prevstyle.name, n),
                               parent=prevstyle,
                               firstLineIndent=prevstyle.firstLineIndent +
                               delta,
                               leftIndent=prevstyle.leftIndent + delta))
            return self.levelStyles[n]

    def addEntry(self, level, text, pageNum, key=None):
        """Adds one entry to the table of contents.

        This allows incremental buildup by a doctemplate.
        Requires that enough styles are defined."""

        assert type(level) == type(1), "Level must be an integer"
        self._entries.append((level, text, pageNum, key))

    def addEntries(self, listOfEntries):
        """Bulk creation of entries in the table of contents.

        If you knew the titles but not the page numbers, you could
        supply them to get sensible output on the first run."""

        for entryargs in listOfEntries:
            self.addEntry(*entryargs)

    def wrap(self, availWidth, availHeight):
        "All table properties should be known by now."

        # makes an internal table which does all the work.
        # we draw the LAST RUN's entries!  If there are
        # none, we make some dummy data to keep the table
        # from complaining
        if len(self._lastEntries) == 0:
            _tempEntries = [(0, 'Placeholder for table of contents', 0, None)]
        else:
            _tempEntries = self._lastEntries

        def drawTOCEntryEnd(canvas, kind, label):
            '''Callback to draw dots and page numbers after each entry.'''
            label = label.split(',')
            page, level, key = int(label[0]), int(label[1]), eval(label[2], {})
            style = self.getLevelStyle(level)
            if self.dotsMinLevel >= 0 and level >= self.dotsMinLevel:
                dot = ' . '
            else:
                dot = ''
            if self.formatter: page = self.formatter(page)
            drawPageNumbers(canvas, style, [(page, key)], availWidth,
                            availHeight, dot)

        self.canv.drawTOCEntryEnd = drawTOCEntryEnd

        tableData = []
        for (level, text, pageNum, key) in _tempEntries:
            style = self.getLevelStyle(level)
            if key:
                text = '<a href="#%s">%s</a>' % (key, text)
                keyVal = repr(key).replace(',', '\\x2c').replace('"', '\\x2c')
            else:
                keyVal = None
            para = Paragraph(
                '%s<onDraw name="drawTOCEntryEnd" label="%d,%d,%s"/>' %
                (text, pageNum, level, keyVal), style)
            if style.spaceBefore:
                tableData.append([
                    Spacer(1, style.spaceBefore),
                ])
            tableData.append([
                para,
            ])

        self._table = Table(tableData,
                            colWidths=(availWidth, ),
                            style=self.tableStyle)

        self.width, self.height = self._table.wrapOn(self.canv, availWidth,
                                                     availHeight)
        return (self.width, self.height)

    def split(self, availWidth, availHeight):
        """At this stage we do not care about splitting the entries,
        we will just return a list of platypus tables.  Presumably the
        calling app has a pointer to the original TableOfContents object;
        Platypus just sees tables.
        """
        return self._table.splitOn(self.canv, availWidth, availHeight)

    def drawOn(self, canvas, x, y, _sW=0):
        """Don't do this at home!  The standard calls for implementing
        draw(); we are hooking this in order to delegate ALL the drawing
        work to the embedded table object.
        """
        self._table.drawOn(canvas, x, y, _sW)
示例#32
0
文件: elements.py 项目: fiqus/pirra
 def drawOn(self, *args, **kwargs):
     if self.cust_data_function:
         self._cellvalues = self.cust_data_function()
     Table.drawOn(self, *args, **kwargs)
示例#33
0
class SimpleIndex(IndexingFlowable):
    """Creates multi level indexes.
    The styling can be cutomized and alphabetic headers turned on and off.
    """
    def __init__(self, **kwargs):
        """
        Constructor of SimpleIndex.
        Accepts the same arguments as the setup method.
        """
        #keep stuff in a dictionary while building
        self._entries = {}
        self._lastEntries = {}
        self._flowable = None
        self.setup(**kwargs)

    def getFormatFunc(self, format):
        try:
            D = {}
            exec(
                'from reportlab.lib.sequencer import _format_%s as formatFunc'
                % format, D)
            return D['formatFunc']
        except ImportError:
            raise ValueError('Unknown format %r' % format)

    def setup(self,
              style=None,
              dot=None,
              tableStyle=None,
              headers=True,
              name=None,
              format='123',
              offset=0):
        """
        This method makes it possible to change styling and other parameters on an existing object.

        style is the paragraph style to use for index entries.
        dot can either be None or a string. If it's None, entries are immediatly followed by their
            corresponding page numbers. If it's a string, page numbers are aligned on the right side
            of the document and the gap filled with a repeating sequence of the string.
        tableStyle is the style used by the table which the index uses to draw itself. Use this to
            change properties like spacing between elements.
        headers is a boolean. If it is True, alphabetic headers are displayed in the Index when the first
        letter changes. If False, we just output some extra space before the next item
        name makes it possible to use several indexes in one document. If you want this use this
            parameter to give each index a unique name. You can then index a term by refering to the
            name of the index which it should appear in:

                <index item="term" name="myindex" />

        format can be 'I', 'i', '123',  'ABC', 'abc'
        """

        if style is None:
            style = ParagraphStyle(name='index',
                                   fontName=_baseFontName,
                                   fontSize=11)
        self.textStyle = style
        self.tableStyle = tableStyle or defaultTableStyle
        self.dot = dot
        self.headers = headers
        if name is None:
            from reportlab.platypus.paraparser import DEFAULT_INDEX_NAME as name
        self.name = name
        self.formatFunc = self.getFormatFunc(format)
        self.offset = offset

    def __call__(self, canv, kind, label):
        label = asNative(label, 'latin1')
        try:
            terms, format, offset = decode_label(label)
        except:
            terms = label
            format = offset = None
        if format is None:
            formatFunc = self.formatFunc
        else:
            formatFunc = self.getFormatFunc(format)
        if offset is None:
            offset = self.offset

        terms = commasplit(terms)
        cPN = canv.getPageNumber()
        pns = formatFunc(cPN - offset)
        key = 'ix_%s_%s_p_%s' % (self.name, label, pns)

        info = canv._curr_tx_info
        canv.bookmarkHorizontal(key, info['cur_x'],
                                info['cur_y'] + info['leading'])
        self.addEntry(terms, (cPN, pns), key)

    def getCanvasMaker(self, canvasmaker=canvas.Canvas):
        def newcanvasmaker(*args, **kwargs):
            from reportlab.pdfgen import canvas
            c = canvasmaker(*args, **kwargs)
            setattr(c, self.name, self)
            return c

        return newcanvasmaker

    def isIndexing(self):
        return 1

    def isSatisfied(self):
        return (self._entries == self._lastEntries)

    def beforeBuild(self):
        # keep track of the last run
        self._lastEntries = self._entries.copy()
        self.clearEntries()

    def clearEntries(self):
        self._entries = {}

    def notify(self, kind, stuff):
        """The notification hook called to register all kinds of events.

        Here we are interested in 'IndexEntry' events only.
        """
        if kind == 'IndexEntry':
            text, pageNum = stuff
            self.addEntry(text, (self._canv.getPageNumber(), pageNum))

    def addEntry(self, text, pageNum, key=None):
        """Allows incremental buildup"""
        self._entries.setdefault(makeTuple(text), set([])).add((pageNum, key))

    def split(self, availWidth, availHeight):
        """At this stage we do not care about splitting the entries,
        we will just return a list of platypus tables.  Presumably the
        calling app has a pointer to the original TableOfContents object;
        Platypus just sees tables.
        """
        return self._flowable.splitOn(self.canv, availWidth, availHeight)

    def _getlastEntries(self,
                        dummy=[(['Placeholder for index'],
                                enumerate((None, ) * 3))]):
        '''Return the last run's entries!  If there are none, returns dummy.'''
        lE = self._lastEntries or self._entries
        if not lE:
            return dummy
        return list(sorted(lE.items()))

    def _build(self, availWidth, availHeight):
        _tempEntries = [(tuple(asUnicode(t) for t in texts), pageNumbers)
                        for texts, pageNumbers in self._getlastEntries()]

        def getkey(seq):
            return [
                ''.join((c for c in unicodedata.normalize('NFD', x.upper())
                         if unicodedata.category(c) != 'Mn')) for x in seq[0]
            ]

        _tempEntries.sort(key=getkey)
        leveloffset = self.headers and 1 or 0

        def drawIndexEntryEnd(canvas, kind, label):
            '''Callback to draw dots and page numbers after each entry.'''
            style = self.getLevelStyle(leveloffset)
            pages = [(p[1], k) for p, k in sorted(decode_label(label))]
            drawPageNumbers(canvas, style, pages, availWidth, availHeight,
                            self.dot)

        self.canv.drawIndexEntryEnd = drawIndexEntryEnd

        alpha = ''
        tableData = []
        lastTexts = []
        alphaStyle = self.getLevelStyle(0)
        for texts, pageNumbers in _tempEntries:
            texts = list(texts)
            #track when the first character changes; either output some extra
            #space, or the first letter on a row of its own.  We cannot do
            #widow/orphan control, sadly.
            nalpha = ''.join(
                (c for c in unicodedata.normalize('NFD', texts[0][0].upper())
                 if unicodedata.category(c) != 'Mn'))
            if alpha != nalpha:
                alpha = nalpha
                if self.headers:
                    header = alpha
                else:
                    header = ' '
                tableData.append([
                    Spacer(1, alphaStyle.spaceBefore),
                ])
                tableData.append([
                    Paragraph(header, alphaStyle),
                ])
                tableData.append([
                    Spacer(1, alphaStyle.spaceAfter),
                ])

            i, diff = listdiff(lastTexts, texts)
            if diff:
                lastTexts = texts
                texts = texts[i:]
            label = encode_label(list(pageNumbers))
            texts[-1] = '%s<onDraw name="drawIndexEntryEnd" label="%s"/>' % (
                texts[-1], label)
            for text in texts:
                #Platypus and RML differ on how parsed XML attributes are escaped.
                #e.g. <index item="M&S"/>.  The only place this seems to bite us is in
                #the index entries so work around it here.
                text = escapeOnce(text)

                style = self.getLevelStyle(i + leveloffset)
                para = Paragraph(text, style)
                if style.spaceBefore:
                    tableData.append([
                        Spacer(1, style.spaceBefore),
                    ])
                tableData.append([
                    para,
                ])
                i += 1

        self._flowable = Table(tableData,
                               colWidths=[availWidth],
                               style=self.tableStyle)

    def wrap(self, availWidth, availHeight):
        "All table properties should be known by now."
        self._build(availWidth, availHeight)
        self.width, self.height = self._flowable.wrapOn(
            self.canv, availWidth, availHeight)
        return self.width, self.height

    def drawOn(self, canvas, x, y, _sW=0):
        """Don't do this at home!  The standard calls for implementing
        draw(); we are hooking this in order to delegate ALL the drawing
        work to the embedded table object.
        """
        self._flowable.drawOn(canvas, x, y, _sW)

    def draw(self):
        t = self._flowable
        ocanv = getattr(t, 'canv', None)
        if not ocanv:
            t.canv = self.canv
        try:
            t.draw()
        finally:
            if not ocanv:
                del t.canv

    def getLevelStyle(self, n):
        '''Returns the style for level n, generating and caching styles on demand if not present.'''
        if not hasattr(self.textStyle, '__iter__'):
            self.textStyle = [self.textStyle]
        try:
            return self.textStyle[n]
        except IndexError:
            self.textStyle = list(self.textStyle)
            prevstyle = self.getLevelStyle(n - 1)
            self.textStyle.append(
                ParagraphStyle(name='%s-%d-indented' % (prevstyle.name, n),
                               parent=prevstyle,
                               firstLineIndent=prevstyle.firstLineIndent +
                               .2 * cm,
                               leftIndent=prevstyle.leftIndent + .2 * cm))
            return self.textStyle[n]
示例#34
0
文件: pdf.py 项目: itkinside/ufs
def pdf(group, list, show_header=True, show_footer=True):
    """PDF version of list"""

    content = StringIO()

    columns = list.column_set.all()
    accounts = list.accounts()

    margin = 0.5*cm

    font_name = 'Times-Roman'
    font_name_bold = 'Times-Bold'
    font_size = 12
    font_size_small = 10
    font_size_min = 8

    head_height = 30  # pt
    foot_height = 15  # pt
    logo_height = 25  # pt

    font_size_name = font_size_small
    font_size_short_name = font_size_small
    font_size_balance = font_size_small

    if list.orientation == list.LANDSCAPE:
        height, width = A4
    else:
        width, height = A4

    # Create canvas for page and set fonts
    p = canvas.Canvas(content, (width, height))

    show_logo = bool(group.logo and group.logo.storage.exists(group.logo.path))

    if show_logo:
        # Find scaling ratio
        ratio = group.logo.width / group.logo.height

        # Load logo with correct scaling
        logo = Image(
            group.logo.path, width=logo_height*ratio, height=logo_height)

    def draw_header():
        if not show_header:
            return

        if show_logo:
            logo.drawOn(
                p,
                width - margin - logo_height*ratio,
                height - margin - logo_height)

        # Setup rest of header
        p.setFont(font_name, font_size)
        p.drawString(
            margin, height - margin - font_size,
            u'%s: %s' % (group, list.name))
        p.setFont(font_name, font_size_small)
        p.drawString(
            margin, height - margin - font_size - font_size + 2,
            u'%s: %s' % (_('Printed'), str(date.today())))

    footer = []
    if group.email:
        footer.append(group.email)
    if group.account_number:
        footer.append(group.get_account_number_display())
    if list.comment.strip():
        footer.append(list.comment.replace('\n', ' ').replace('\r', ' '))

    def draw_footer():
        if not show_footer:
            return

        p.drawString(margin, margin, u' - '.join(footer))

        blacklisted_note = _(u'Blacklisted accounts are marked with: ')

        p.drawRightString(width - margin - 10, margin, blacklisted_note)
        p.setFillColor(BLACKLISTED_COLOR)
        p.rect(width - margin - 10, margin, 8, 8, fill=1, stroke=0)

        p.setFont(font_name, font_size)

    if not accounts:
        no_accounts_message = _(u"Sorry, this list is empty.")
        draw_header()
        p.drawString(
            margin, height - font_size - margin - head_height,
            no_accounts_message)
        draw_footer()
        p.save()

        return content

    elif not columns:
        no_columns_message = _(
            u"Sorry, this list isn't set up correctly, "
            u"please add some columns.")
        draw_header()
        p.drawString(
            margin, height - font_size - margin - head_height,
            no_columns_message)
        draw_footer()
        p.save()

        return content

    # Store col widths
    col_width = []
    header = [_(u'Name')]

    if list.account_width:
        col_width.append(list.account_width)

    if list.short_name_width:
        col_width.append(list.short_name_width)

    if list.account_width and list.short_name_width:
        header.append('')

    if list.balance_width:
        header.append(_(u'Balance'))
        col_width.append(list.balance_width)

    if list.short_name_width > 0 and list.account_width > 0:
        GRID_STYLE.add('SPAN', (0, 0), (1, 0))

    base_x = len(header)

    for c in columns:
        header.append(c.name)
        col_width.append(c.width)

    # Calculate relative col widths over to absolute points
    for i, w in enumerate(col_width):
        col_width[i] = float(w) / float(
            (list.listcolumn_width or 0) + list.balance_width +
            (list.account_width or 0) + (list.short_name_width or 0)
        ) * (width - 2 * margin)

    # Intialise table with header
    data = [header]

    for i, a in enumerate(accounts):
        color = ALTERNATE_COLORS[(i+1) % len(ALTERNATE_COLORS)]

        if list.double:
            i *= 2
            extra_row_height = 1
        else:
            extra_row_height = 0

        i += 1

        GRID_STYLE.add('BACKGROUND', (0, i), (-1, i+extra_row_height), color)

        row = []

        if list.account_width:
            row.append(a.name)

            # Check if we need to reduce col font size
            while (
                    col_width[len(row)-1] <
                    p.stringWidth(row[-1], font_name, font_size_name) + 12
                    and font_size_name > font_size_min):
                font_size_name -= 1

        if list.short_name_width:
            short_name = a.short_name

            if not short_name and a.owner:
                short_name = a.owner.username

            row.append(short_name or a.name)

            # Check if we need to reduce col font size
            while (
                    col_width[len(row)-1] <
                    p.stringWidth(row[-1], font_name, font_size_name) + 12
                    and font_size_short_name > font_size_min):
                font_size_short_name -= 1

        if list.balance_width:
            row.append('%d' % a.normal_balance())

            # XXX: currently warnings are only shown if balance is shown, this
            # if needs to be moved if you want to change that
            if a.needs_warning():
                GRID_STYLE.add(
                    'FONTNAME', (0, i), (base_x - 1, i), font_name_bold)
                GRID_STYLE.add(
                    'TEXTCOLOR', (base_x - 1, i), (base_x - 1, i),
                    WARN_TEXT_COLOR)

            # Check if we need to reduce col font size
            while (
                    col_width[len(row)-1] <
                    p.stringWidth(str(row[-1]), font_name, font_size_balance) +
                    12
                    and font_size_balance > font_size_min):
                font_size_balance -= 1

        if a.is_blocked():
            if list.balance_width:
                GRID_STYLE.add(
                    'TEXTCOLOR', (base_x - 1, i), (base_x - 1, i),
                    BLACKLISTED_TEXT_COLOR)
                GRID_STYLE.add(
                    'FONTNAME', (0, i), (base_x - 1, i), font_name_bold)
            GRID_STYLE.add(
                'BACKGROUND', (base_x, i), (-1, i + extra_row_height),
                BLACKLISTED_COLOR)

            row.extend([''] * len(header[base_x:]))

        else:
            row.extend(header[base_x:])

        data.append(row)

        if list.double:
            data.append([''] * len(row))

            GRID_STYLE.add('SPAN', (0, i), (0, i + extra_row_height))

            if list.balance_width:
                GRID_STYLE.add('SPAN', (1, i), (1, i + extra_row_height))

    GRID_STYLE.add('FONTSIZE', (0, 0), (-1, -1), font_size_small)

    # Set font size for names
    GRID_STYLE.add('FONTSIZE', (0, 1), (0, -1), font_size_name)
    GRID_STYLE.add('ALIGN', (0, 0), (-1, -1), 'LEFT')
    GRID_STYLE.add('ALIGN', (base_x, 0), (-1, -1), 'RIGHT')

    GRID_STYLE.add('FONTNAME', (0, 0), (-1, 0), font_name_bold)

    # Set font size for balance
    if list.balance_width:
        GRID_STYLE.add(
            'FONTSIZE', (base_x - 1, 1), (base_x - 1, -1), font_size_balance)
        GRID_STYLE.add('ALIGN', (base_x - 1, 1), (base_x - 1, -1), 'RIGHT')

    GRID_STYLE.add('TEXTCOLOR', (base_x, 1), (-1, -1), FAINT_COLOR)

    if list.double:
        GRID_STYLE.add('TOPPADDING', (base_x, 1), (-1, -1), 2)
        GRID_STYLE.add('BOTTOMPADDING', (base_x, 1), (-1, -1), 2)

    GRID_STYLE.add('VALIGN', (0, 1), (-1, -1), 'TOP')
    GRID_STYLE.add('GRID', (0, 0), (-1, -1), 0.25, BORDER_COLOR)

    # Create table
    t = Table(data, colWidths=col_width, style=GRID_STYLE, repeatRows=1)

    rest = None
    avail_w = width-2*margin
    avail_h = height - 2*margin - head_height - foot_height

    while t:
        # Figure out how big table will be
        t_width, t_height = t.wrapOn(p, avail_w, avail_h)

        if not rest and t_height > height - 2*margin - head_height:
            t, rest = t.split(avail_w, avail_h)
            continue

        # Draw on canvas
        draw_header()
        t.drawOn(p, margin, height - t_height - margin - head_height)
        draw_footer()

        if rest:
            # set t to the second table and reset rest
            t, rest = (rest, None)

            # Show new page
            p.showPage()
        else:
            # Leave loop
            break

    p.save()

    return content
示例#35
0
def reporte_pdf(request):
    # Create the HttpResponse object with the appropriate PDF headers.
    response = HttpResponse(content_type='application/pdf')
    # Para descargar directo
    #response['Content-Disposition'] = 'attachment; filename=reporte.pdf'
 
    # Create the PDF object, using the response object as its "file."
    buffer = BytesIO()
    p = canvas.Canvas(buffer, A4)

    # Instanciar Cuenta
    num = request.GET['numero']
    cuent = Cuenta.objects.get(numero = num)
    #Instanciar Lista de transacciones
    listTransaccion = Transaccion.objects.all().filter(cuenta = cuent).order_by('fecha')

    # HEADER
    p.setLineWidth(.3)
    p.setFont('Helvetica', 10)
    p.drawString(180, 800, "COOPERATIVA DE AHORRO Y CREDITO")

    p.setFont('Helvetica-Bold', 17)
    p.drawString(160, 780, "COOPERATIVA JONNATHAN")

    p.setFont('Helvetica', 15)
    p.drawString(180, 762, "CUENTA TIPO: " + cuent.tipoCuenta)

    p.setFont('Helvetica-Bold', 12)
    p.drawString(30, 730, "Oficina:")

    p.setFont('Helvetica', 12)
    p.drawString(95, 730, "Loja")

    p.setFont('Helvetica-Bold', 12)
    p.drawString(325, 730, "N. de Cuenta: ")
    p.setFont('Helvetica', 12)
    p.drawString(425, 730, cuent.numero)
    p.line(420, 727, 560, 727)#start X, height end y , height
    
    p.setFont('Helvetica-Bold', 12)
    p.drawString(30, 710, "Nombres:")

    p.setFont('Helvetica', 12)
    p.drawString(95, 710, cuent.cliente.apellidos + ' ' + cuent.cliente.nombres)

    p.setFont('Helvetica-Bold', 12)
    p.drawString(30, 690, "Domicilio:")

    p.setFont('Helvetica', 12)
    p.drawString(95, 690, cuent.cliente.direccion)

    p.setFont('Helvetica-Bold', 12)
    p.drawString(348, 690, "Telefono:")
    p.setFont('Helvetica', 12)
    p.drawString(425, 690, cuent.cliente.telefono)

    # Cliente table
    transacciones = []
    transacciones.append({'fecha':cuent.fechaApertura, 'name':"Apertura", 'b1':cuent.saldoApertura, 'b2':cuent.saldoApertura})
    for ltr in listTransaccion:
        transacciones.append({'fecha':ltr.fecha, 'name':ltr.tipo, 'b1':ltr.valor, 'b2':ltr.saldoFinal})
    #transacciones = [{'fecha':'1','name':'Jonnathan', 'b1':'3.4', 'b2':'3.5'}]

    # Table header
    styles = getSampleStyleSheet()
    styleBH = styles["Normal"]
    styleBH.alignment = TA_CENTER
    styleBH.fontSize = 10

    fecha = Paragraph('''Fecha''', styleBH)
    tipo = Paragraph('''Tipo Operacion''', styleBH)
    monto = Paragraph('''Monto''', styleBH)
    saldo = Paragraph('''Saldo''', styleBH)

    data = []
    data.append([fecha, tipo, monto, saldo])

    # Table body
    styleN = styles["BodyText"]
    styleN.alignment = TA_CENTER
    styleN.fontSize = 7

    high = 640
    for t in transacciones:
        this_t = [t['fecha'], t['name'], t['b1'], t['b2']]
        data.append(this_t)
        high = high - 18
    
    # Table size
    table = Table(data, colWidths=[6 * cm, 6.4 * cm, 3 * cm, 3 * cm])
    table.setStyle(TableStyle([# estilos de la tabla
        ('INNERGRID', (0,0), (-1,-1), 0.25, colors.black),
        ('BOX', (0,0), (-1,-1), 0.25, colors.black),
    ]))
    # pdf size
    width, height = A4
    table.wrapOn(p, width, height)
    table.drawOn(p, 30, high)
    # Close the PDF object cleanly, and we're done.
    p.showPage()# save page
    p.save() # save pdf
    # get the value of BytesIO buffer and write response
    pdf = buffer.getvalue()
    buffer.close()
    response.write(pdf)
    return response
示例#36
0
    def draw_footer(self, y_pos):
        """
        Draws the footer.
        """

        para_style = getSampleStyleSheet()["Normal"]
        para_style.fontSize = 8

        footer_para = Paragraph(self.footer_text.replace("\n", "<br/>"), para_style)
        disclaimer_para = Paragraph(self.disclaimer_text.replace("\n", "<br/>"), para_style)
        billing_address_para = Paragraph(self.billing_address_text.replace("\n", "<br/>"), para_style)

        footer_data = [
            ["", footer_para],
            [(_("Billing Address")), ""],
            ["", billing_address_para],
            [(_("Disclaimer")), ""],
            ["", disclaimer_para],
        ]

        footer_style = [
            # Styling for the entire footer table.
            ("ALIGN", (0, 0), (-1, -1), "LEFT"),
            ("VALIGN", (0, 0), (-1, -1), "MIDDLE"),
            ("TEXTCOLOR", (0, 0), (-1, -1), colors.black),
            ("FONTSIZE", (0, 0), (-1, -1), 9),
            ("TEXTCOLOR", (0, 0), (-1, -1), "#AAAAAA"),
            # Billing Address Header styling
            ("LEFTPADDING", (0, 1), (0, 1), 5 * mm),
            # Disclaimer Header styling
            ("LEFTPADDING", (0, 3), (0, 3), 5 * mm),
            ("TOPPADDING", (0, 3), (0, 3), 2 * mm),
            # Footer Body styling
            # ('BACKGROUND', (1, 0), (1, 0), '#EEEEEE'),
            # Billing Address Body styling
            ("BACKGROUND", (1, 2), (1, 2), "#EEEEEE"),
            # Disclaimer Body styling
            ("BACKGROUND", (1, 4), (1, 4), "#EEEEEE"),
        ]

        if self.is_invoice:
            terms_conditions_para = Paragraph(self.terms_conditions_text.replace("\n", "<br/>"), para_style)
            footer_data.append([(_("TERMS AND CONDITIONS")), ""])
            footer_data.append(["", terms_conditions_para])

            # TERMS AND CONDITIONS header styling
            footer_style.append(("LEFTPADDING", (0, 5), (0, 5), 5 * mm))
            footer_style.append(("TOPPADDING", (0, 5), (0, 5), 2 * mm))

            # TERMS AND CONDITIONS body styling
            footer_style.append(("BACKGROUND", (1, 6), (1, 6), "#EEEEEE"))

        footer_table = Table(footer_data, [5 * mm, 176 * mm])

        footer_table.setStyle(TableStyle(footer_style))
        __, rendered_height = footer_table.wrap(0, 0)

        if y_pos - (self.margin + self.min_clearance) <= rendered_height:
            self.prepare_new_page()

        footer_table.drawOn(self.pdf, self.margin, self.margin + 5 * mm)
示例#37
0
class TableOfContents(IndexingFlowable):
    """This creates a formatted table of contents.

    It presumes a correct block of data is passed in.
    The data block contains a list of (level, text, pageNumber)
    triplets.  You can supply a paragraph style for each level
    (starting at zero).
    Set dotsMinLevel to determine from which level on a line of
    dots should be drawn between the text and the page number.
    If dotsMinLevel is set to a negative value, no dotted lines are drawn.
    """

    def __init__(self):
        self.rightColumnWidth = 72
        self.levelStyles = defaultLevelStyles
        self.tableStyle = defaultTableStyle
        self.dotsMinLevel = 1
        self._table = None
        self._entries = []
        self._lastEntries = []

    def beforeBuild(self):
        # keep track of the last run
        self._lastEntries = self._entries[:]
        self.clearEntries()

    def isIndexing(self):
        return 1

    def isSatisfied(self):
        return (self._entries == self._lastEntries)

    def notify(self, kind, stuff):
        """The notification hook called to register all kinds of events.

        Here we are interested in 'TOCEntry' events only.
        """
        if kind == 'TOCEntry':
            self.addEntry(*stuff)

    def clearEntries(self):
        self._entries = []

    def getLevelStyle(self, n):
        '''Returns the style for level n, generating and caching styles on demand if not present.'''
        try:
            return self.levelStyles[n]
        except IndexError:
            prevstyle = self.getLevelStyle(n-1)
            self.levelStyles.append(ParagraphStyle(
                    name='%s-%d-indented' % (prevstyle.name, n),
                    parent=prevstyle,
                    firstLineIndent = prevstyle.firstLineIndent+delta,
                    leftIndent = prevstyle.leftIndent+delta))
            return self.levelStyles[n]

    def addEntry(self, level, text, pageNum, key=None):
        """Adds one entry to the table of contents.

        This allows incremental buildup by a doctemplate.
        Requires that enough styles are defined."""

        assert type(level) == type(1), "Level must be an integer"
        self._entries.append((level, text, pageNum, key))


    def addEntries(self, listOfEntries):
        """Bulk creation of entries in the table of contents.

        If you knew the titles but not the page numbers, you could
        supply them to get sensible output on the first run."""

        for entryargs in listOfEntries:
            self.addEntry(*entryargs)


    def wrap(self, availWidth, availHeight):
        "All table properties should be known by now."

        # makes an internal table which does all the work.
        # we draw the LAST RUN's entries!  If there are
        # none, we make some dummy data to keep the table
        # from complaining
        if len(self._lastEntries) == 0:
            _tempEntries = [(0,'Placeholder for table of contents',0,None)]
        else:
            _tempEntries = self._lastEntries

        def drawTOCEntryEnd(canvas, kind, label):
            '''Callback to draw dots and page numbers after each entry.'''
            label = label.split(',')
            page, level, key = int(label[0]), int(label[1]), eval(label[2],{})
            style = self.getLevelStyle(level)
            if self.dotsMinLevel >= 0 and level >= self.dotsMinLevel:
                dot = ' . '
            else:
                dot = ''
            drawPageNumbers(canvas, style, [(page, key)], availWidth, availHeight, dot)
        self.canv.drawTOCEntryEnd = drawTOCEntryEnd

        tableData = []
        for (level, text, pageNum, key) in _tempEntries:
            style = self.getLevelStyle(level)
            if key:
                text = '<a href="#%s">%s</a>' % (key, text)
                keyVal = repr(key).replace(',','\\x2c').replace('"','\\x2c')
            else:
                keyVal = None
            para = Paragraph('%s<onDraw name="drawTOCEntryEnd" label="%d,%d,%s"/>' % (text, pageNum, level, keyVal), style)
            if style.spaceBefore:
                tableData.append([Spacer(1, style.spaceBefore),])
            tableData.append([para,])

        self._table = Table(tableData, colWidths=(availWidth,), style=self.tableStyle)

        self.width, self.height = self._table.wrapOn(self.canv,availWidth, availHeight)
        return (self.width, self.height)


    def split(self, availWidth, availHeight):
        """At this stage we do not care about splitting the entries,
        we will just return a list of platypus tables.  Presumably the
        calling app has a pointer to the original TableOfContents object;
        Platypus just sees tables.
        """
        return self._table.splitOn(self.canv,availWidth, availHeight)


    def drawOn(self, canvas, x, y, _sW=0):
        """Don't do this at home!  The standard calls for implementing
        draw(); we are hooking this in order to delegate ALL the drawing
        work to the embedded table object.
        """
        self._table.drawOn(canvas, x, y, _sW)
示例#38
0
文件: reports.py 项目: HCCB/janus
class MasterInfo(Flowable):
    KEYS = {
        'master': ['patient', 'date', 'room_number',
                   'case_number', 'physician'],
        'patient': ['fullname', 'age', 'gender'],
    }

    def process_kwarg(self, data, kwargs):
        for objname in self.KEYS.keys():
            if objname in kwargs.keys():
                o = kwargs[objname]
                for k in self.KEYS[objname]:
                    display = 'get_%s_display' % k
                    if hasattr(o, display):
                        data[k] = getattr(o, display)()
                    else:
                        data[k] = getattr(o, k)
                del kwargs[objname]

        p = data.get('patient', None)
        for k in chain(*self.KEYS.values()):
            if k in kwargs.keys():
                data[k] = kwargs[k]
                del kwargs[k]
            elif p and hasattr(p, k):
                display = 'get_%s_display' % k
                if hasattr(p, display):
                    data[k] = getattr(p, display)()
                else:
                    data[k] = getattr(p, k)

    def __init__(self, **kwargs):
        data = {}
        self.process_kwarg(data, kwargs)

        self.config = {}
        for k in ['font', 'fontsize', 'offset', 'width',
                  'leftmargin', 'rightmargin']:
            if k in kwargs:
                # setattr(self, k, kwargs[k])
                self.config[k] = kwargs[k]
                del kwargs[k]

        if len(kwargs):
            raise TypeError("__init__ got an unxepected keyworkd '%s'" %
                            kwargs.keys()[0])
        self.init_table(data)

    def init_table(self, data):

        styles = getSampleStyleSheet()
        sN = styles['Normal']
        if 'font' in self.config:
            sN.fontName = self.config['font']
        if 'fontsize' in self.config:
            sN.fontSize = self.config['fontsize']
            sN.leading = sN.fontSize * 1.1

        cell_data = [["" for x in range(12)] for y in range(3)]
        # Row 1
        cell_data[0][0] = Paragraph("<b>Name:</b><u> %s</u>" %
                                    data.get('fullname', 'NO_VALUE'),
                                    sN)
        date_type = type(data['date'])
        if date_type in [datetime.datetime, datetime.date]:
            date = datetime.datetime.strftime(data['date'], "%m/%d/%Y")
        else:
            date = data['date']
        cell_data[0][6] = Paragraph("<b>Date:</b><u> %s</u>" %
                                    date,
                                    sN)
        cell_data[0][9] = Paragraph("<b>Case #:</b><u> %s</u>" %
                                    data.get('case_number', 'NO_VALUE'),
                                    sN)
        # Row 2
        cell_data[1][0] = Paragraph("<b>Room #:</b><u> %s</u>" %
                                    data.get('room_number', 'NO_VALUE'),
                                    sN)
        cell_data[1][4] = Paragraph("<b>Age:</b><u> %s</u>" %
                                    data['age'],
                                    sN)
        cell_data[1][8] = Paragraph("<b>Sex:</b><u> %s</u>" %
                                    data.get('gender', 'NO_VALUE'),
                                    sN)
        # Row 3
        cell_data[2][0] = Paragraph("<b>Requesting Physician:</b><u> %s</u>" %
                                    data.get('physician', 'NO_VALUE'),
                                    sN)
        if 'width' in self.config:
            width = self.config['width']
        else:
            width, height = landscape(A5)
            self.config['width'] = width

        lm = self.config.get('leftmargin', 10)
        rm = self.config.get('rightmargin', 10)
        width -= lm + rm

        self.table = Table(cell_data, colWidths=[width/12]*12)
        self.table.setStyle(TableStyle([
            # ('GRID', (0, 0), (-1, -1), 1, black),
            ('TOPPADDING', (0, 0), (-1, -1), 0),
            ('BOTTOMPADDING', (0, 0), (-1, -1), 0),
            ('BOTTOMPADDING', (0, -1), (0, -1), 3),
            ('LINEBELOW', (0, -1), (-1, -1), 1, black),
            # Row 1
            ('SPAN', (0, 0), (5, 0)),
            ('SPAN', (6, 0), (8, 0)),
            ('SPAN', (9, 0), (11, 0)),
            # Row 2
            ('SPAN', (0, 1), (3, 1)),
            ('SPAN', (4, 1), (7, 1)),
            ('SPAN', (8, 1), (11, 1)),
            # Row 3
            ('SPAN', (0, 2), (11, 2)),
        ]))

    def split(self, availWidth, availHeight):
        return []

    def wrap(self, availWidth, availHeight):
        width, height = self.table.wrap(availWidth, availHeight)
        return (width, height)

    def drawOn(self, canvas, x, y, _sW=0):
        return self.table.drawOn(canvas, x, y, _sW)
示例#39
0
    def body():
        # Body

        size_y = 0.62
        data = [["Sold", "Cash", "Card", "Contingent", "Reserved", "Expected", "Unsold Reserv."]]
        for cat, value in report_result_dict.iteritems():
            size_y = size_y + 1.86
            """
            if cat == 'all':
                report_cat_name = 'All'
            else:
                report_cat_name = self.report_cat_list[event_id][cat]
            """
            if cat == "all":
                categorie_name = "All"
            else:
                categorie_name = cat_name[cat]

            p = Paragraph('<para alignment="center"><b>' + categorie_name + "</b></para>", styles["Normal"])
            data.append([p, "", "", "", "", "", ""])
            if cat == "all":
                data_for_pie = [
                    value["a_total_sold"],
                    value["a_sold_cash"],
                    value["a_sold_card"],
                    value["a_sold_conti"],
                    value["a_reserved"],
                    value["a_not_visited"],
                ]

            data.append(
                [
                    value["a_total_sold"],
                    value["a_sold_cash"],
                    value["a_sold_card"],
                    value["a_sold_conti"],
                    value["a_reserved"],
                    value["a_total_pre"],
                    value["a_not_visited"],
                ]
            )

            data.append(
                [
                    str(value["m_total_sold"]) + unichr(8364),
                    str(value["m_sold_cash"]) + unichr(8364),
                    str(value["m_sold_card"]) + unichr(8364),
                    "-",
                    str(value["m_reserved"]) + unichr(8364),
                    str(value["m_total_pre"]) + unichr(8364),
                    str(value["m_not_visited"]) + unichr(8364),
                ]
            )

        tstyle = [
            ("INNERGRID", (0, 0), (-1, -1), 0.25, colors.grey),
            ("BOX", (0, 0), (-1, -1), 0.25, colors.black),
            ("ALIGN", (0, 1), (-1, -1), "RIGHT"),
            (
                "COLBACKGROUNDS",
                (0, 0),
                (-1, -1),
                [
                    colors.lightpink,
                    colors.lightpink,
                    colors.lightpink,
                    colors.lightpink,
                    colors.lightyellow,
                    colors.lightgrey,
                    colors.lightyellow,
                ],
            ),
            ("ROWBACKGROUNDS", (0, 1), (-1, -1), [colors.lightslategray, None, None]),
        ]

        t = Table(data)
        t.setStyle(TableStyle(tstyle))
        t.wrapOn(c, 19 * cm, 0 * cm)
        pos_y = 26.5 - size_y
        t.drawOn(c, 1 * cm, pos_y * cm)

        # Price Details
        # size_y = 0.62

        pdata = []
        for cat, value in report_result_dict.iteritems():
            size_y = size_y + 1.86

            if cat == "all":
                pass
            else:
                categorie_name = cat_name[cat]

                p = Paragraph('<para alignment="center"><b>' + categorie_name + "</b></para>", styles["Normal"])
                pdata.append([p])

                data_price_titles = []
                data_price_amount = []
                data_price_total = []
                for prow in p_result:
                    if cat == "cat_" + str(prow["cat_id"]):
                        data_price_titles.append(prow["name"])
                        try:
                            data_price_amount.append(str(value["a_prices"][str(prow["id"])]))
                        except KeyError:
                            data_price_amount.append("0")

                        try:
                            data_price_total.append(str(value["m_prices"][str(prow["id"])]) + unichr(8364))
                        except KeyError:
                            data_price_total.append("0" + unichr(8364))

                print data_price_titles
                pdata.append(data_price_titles)
                pdata.append(data_price_amount)
                pdata.append(data_price_total)

        tstyle = [
            ("INNERGRID", (0, 0), (-1, -1), 0.25, colors.grey),
            ("BOX", (0, 0), (-1, -1), 0.25, colors.black),
            ("ALIGN", (0, 1), (-1, -1), "RIGHT"),
            ("COLBACKGROUNDS", (0, 0), (-1, -1), [colors.lightgrey, colors.whitesmoke]),
            ("ROWBACKGROUNDS", (0, 0), (-1, -1), [colors.lightslategray, None, None, None]),
        ]

        t = Table(pdata)
        t.setStyle(TableStyle(tstyle))
        t.wrapOn(c, 19 * cm, 0 * cm)
        pos_y = 25 - size_y
        t.drawOn(c, 1 * cm, pos_y * cm)

        """
        #Pie Chart

        d = Drawing(500, 500)
        pc = Pie()
        pc.x = 65
        pc.y = 15
        pc.width = 200
        pc.height = 200
        pc.data = data_for_pie
        pc.labels = ['Sold','Cash','Card','Contingent','Reserved','Unsold Reserv.']
        pc.slices.strokeWidth=0.5
        pc.slices[0].popout = 10
        #pc.slices[0].strokeWidth = 2
        #pc.slices[0].strokeDashArray = [2,2]
        pc.slices[0].labelRadius = 1.3
        pc.slices[0].fontColor = colors.red
        pc.slices[0].fillColor = colors.lightpink
        pc.slices[1].fillColor = colors.lightpink
        pc.slices[2].fillColor = colors.lightpink
        pc.slices[3].fillColor = colors.lightpink
        pc.slices[4].fillColor = colors.lightyellow
        pc.slices[5].fillColor = colors.lightyellow
        d.add(pc)
        d.wrapOn(c, 5*cm, 5*cm)
        d.drawOn(c, 1*cm, 1*cm)
        """
        if event_date == "all":
            data = []
            sold = []
            reserved = []
            unsold_reserved = []
            sold_contingent = []

            for key, value in sorted(report_date_dict.iteritems(), key=lambda report_date_dict: report_date_dict[0]):
                date_day_dt = dt.datetime.strptime(key, "%Y-%m-%d")
                date_day = date_day_dt.strftime("%Y%m%d")

                sold.append((int(date_day), value["sold"]))

                reserved.append((int(date_day), value["reserved"]))

                unsold_reserved.append((int(date_day), value["unsold_reserved"]))

                sold_contingent.append((int(date_day), value["sold_contingent"]))

            data.append(sold)
            data.append(reserved)
            data.append(unsold_reserved)
            data.append(sold_contingent)

            print data

            # sample data
            _colors = (
                Color(0.90, 0, 0),
                Color(0.801961, 0.801961, 0),
                Color(0.380392, 0.380392, 0),
                Color(0.580392, 0, 0),
            )
            _catNames = "Sold", "Reserved", "Unsold Reserved", "Contingents"

            d = Drawing(400, 200)
            # adding the actual chart here.
            plot = GridLinePlot()
            plot.y = 50
            plot.x = 15
            plot.width = 525
            plot.height = 125
            plot.xValueAxis.xLabelFormat = "{ddd} {dd}. {mm}."
            plot.lineLabels.fontSize = 6
            plot.lineLabels.boxStrokeWidth = 0.5
            plot.lineLabels.visible = 1
            plot.lineLabels.boxAnchor = "c"
            plot.lineLabels.angle = 0
            plot.lineLabelNudge = 10
            plot.joinedLines = 1
            plot.lines.strokeWidth = 1.5
            plot.lines[0].strokeColor = _colors[0]
            plot.lines[1].strokeColor = _colors[1]
            plot.lines[2].strokeColor = _colors[2]
            plot.lines[3].strokeColor = _colors[3]
            # sample data
            plot.data = data
            """
            plot.data  = [[(20010630, 1000),
                           (20011231, 101),
                           (20020630, 100.05),
                           (20021231, 102),
                           (20030630, 103),
                           (20031230, 104),
                           (20040630, 99.200000000000003),
                           (20041231, 99.099999999999994)],

                          [(20010630, 100.8),
                           (20011231, 100.90000000000001),
                           (20020630, 100.2),
                           (20021231, 100.09999999999999),
                           (20030630, 100),
                           (20031230, 100.05),
                           (20040630, 99.900000000000006),
                           (20041231, 99.799999999999997)],

                          [(20010630, 99.700000000000003),
                           (20011231, 99.799999999999997),
                           (20020630, 100),
                           (20021231, 100.01000000000001),
                           (20030630, 95),
                           (20031230, 90),
                           (20040630, 85),
                           (20041231, 80)]]
            """
            # y axis
            plot.yValueAxis.tickRight = 0
            plot.yValueAxis.maximumTicks = 10
            # plot.yValueAxis.leftAxisPercent        = 0
            plot.yValueAxis.tickLeft = 5
            plot.yValueAxis.valueMax = None
            plot.yValueAxis.valueMin = None
            plot.yValueAxis.rangeRound = "both"
            plot.yValueAxis.requiredRange = 30
            plot.yValueAxis.valueSteps = None
            plot.yValueAxis.valueStep = None
            plot.yValueAxis.forceZero = 0
            plot.yValueAxis.labels.fontSize = 7
            plot.yValueAxis.labels.dy = 0
            plot.yValueAxis.avoidBoundFrac = 0.1
            # x axis
            plot.xValueAxis.labels.fontName = "Helvetica"
            plot.xValueAxis.labels.fontSize = 7
            plot.xValueAxis.valueSteps = None
            plot.xValueAxis.dailyFreq = 0
            plot.xValueAxis.gridStrokeWidth = 0.25
            plot.xValueAxis.labels.angle = 90
            plot.xValueAxis.maximumTicks = 20
            plot.xValueAxis.tickDown = 3
            plot.xValueAxis.dailyFreq = 0
            plot.xValueAxis.bottomAxisLabelSlack = 0
            plot.xValueAxis.minimumTickSpacing = 10
            plot.xValueAxis.visibleGrid = 0
            plot.xValueAxis.gridEnd = 0
            plot.xValueAxis.gridStart = 0
            plot.xValueAxis.labels.angle = 45
            plot.xValueAxis.labels.boxAnchor = "e"
            plot.xValueAxis.labels.dx = 0
            plot.xValueAxis.labels.dy = -5

            # adding legend
            legend = LineLegend()
            legend.boxAnchor = "sw"
            legend.x = 20
            legend.y = -2
            legend.columnMaximum = 1
            legend.yGap = 0
            legend.deltax = 50
            legend.deltay = 0
            legend.dx = 10
            legend.dy = 1.5
            legend.fontSize = 7
            legend.alignment = "right"
            legend.dxTextSpace = 5
            legend.colorNamePairs = [(_colors[i], _catNames[i]) for i in xrange(len(plot.data))]

            d.add(plot)
            d.add(legend)

            d.wrapOn(c, 18 * cm, 5 * cm)
            d.drawOn(c, 1 * cm, 1 * cm)

        c.showPage()
示例#40
0
    def draw_footer(self, y_pos):
        """
        Draws the footer.
        """

        para_style = getSampleStyleSheet()['Normal']
        para_style.fontSize = 8

        footer_para = Paragraph(self.footer_text.replace("\n", "<br/>"), para_style)
        disclaimer_para = Paragraph(self.disclaimer_text.replace("\n", "<br/>"), para_style)
        billing_address_para = Paragraph(self.billing_address_text.replace("\n", "<br/>"), para_style)

        footer_data = [
            ['', footer_para],
            [(_('Billing Address')), ''],
            ['', billing_address_para],
            [(_('Disclaimer')), ''],
            ['', disclaimer_para]
        ]

        footer_style = [
            # Styling for the entire footer table.
            ('ALIGN', (0, 0), (-1, -1), 'LEFT'),
            ('VALIGN', (0, 0), (-1, -1), 'MIDDLE'),
            ('TEXTCOLOR', (0, 0), (-1, -1), colors.black),
            ('FONTSIZE', (0, 0), (-1, -1), 9),
            ('TEXTCOLOR', (0, 0), (-1, -1), '#AAAAAA'),

            # Billing Address Header styling
            ('LEFTPADDING', (0, 1), (0, 1), 5 * mm),

            # Disclaimer Header styling
            ('LEFTPADDING', (0, 3), (0, 3), 5 * mm),
            ('TOPPADDING', (0, 3), (0, 3), 2 * mm),

            # Footer Body styling
            # ('BACKGROUND', (1, 0), (1, 0), '#EEEEEE'),

            # Billing Address Body styling
            ('BACKGROUND', (1, 2), (1, 2), '#EEEEEE'),

            # Disclaimer Body styling
            ('BACKGROUND', (1, 4), (1, 4), '#EEEEEE'),
        ]

        if self.is_invoice:
            terms_conditions_para = Paragraph(self.terms_conditions_text.replace("\n", "<br/>"), para_style)
            footer_data.append([(_('TERMS AND CONDITIONS')), ''])
            footer_data.append(['', terms_conditions_para])

            # TERMS AND CONDITIONS header styling
            footer_style.append(('LEFTPADDING', (0, 5), (0, 5), 5 * mm))
            footer_style.append(('TOPPADDING', (0, 5), (0, 5), 2 * mm))

            # TERMS AND CONDITIONS body styling
            footer_style.append(('BACKGROUND', (1, 6), (1, 6), '#EEEEEE'))

        footer_table = Table(footer_data, [5 * mm, 176 * mm])

        footer_table.setStyle(TableStyle(footer_style))
        __, rendered_height = footer_table.wrap(0, 0)

        if y_pos - (self.margin + self.min_clearance) <= rendered_height:
            self.prepare_new_page()

        footer_table.drawOn(self.pdf, self.margin, self.margin + 5 * mm)
示例#41
0
class SimpleIndex(IndexingFlowable):
    """This creates a very simple index.

    Entries have a string key, and appear with a page number on
    the right.  Prototype for more sophisticated multi-level index."""
    def __init__(self):
        #keep stuff in a dictionary while building
        self._entries = {}
        self._lastEntries = {}
        self._table = None
        self.textStyle = ParagraphStyle(name='index',
                                        fontName='Times-Roman',
                                        fontSize=12)
    def isIndexing(self):
        return 1

    def isSatisfied(self):
        return (self._entries == self._lastEntries)

    def beforeBuild(self):
        # keep track of the last run
        self._lastEntries = self._entries.copy()
        self.clearEntries()

    def clearEntries(self):
        self._entries = {}

    def notify(self, kind, stuff):
        """The notification hook called to register all kinds of events.

        Here we are interested in 'IndexEntry' events only.
        """
        if kind == 'IndexEntry':
            (text, pageNum) = stuff
            self.addEntry(text, pageNum)

    def addEntry(self, text, pageNum):
        """Allows incremental buildup"""
        if self._entries.has_key(text):
            self._entries[text].append(str(pageNum))
        else:
            self._entries[text] = [pageNum]

    def split(self, availWidth, availHeight):
        """At this stage we do not care about splitting the entries,
        we will just return a list of platypus tables.  Presumably the
        calling app has a pointer to the original TableOfContents object;
        Platypus just sees tables.
        """
        return self._table.splitOn(self.canv,availWidth, availHeight)

    def wrap(self, availWidth, availHeight):
        "All table properties should be known by now."
        # makes an internal table which does all the work.
        # we draw the LAST RUN's entries!  If there are
        # none, we make some dummy data to keep the table
        # from complaining
        if len(self._lastEntries) == 0:
            _tempEntries = [('Placeholder for index',[0,1,2])]
        else:
            _tempEntries = self._lastEntries.items()
            _tempEntries.sort()

        tableData = []
        for (text, pageNumbers) in _tempEntries:
            #right col style is right aligned
            allText = text + ': ' + string.join(map(str, pageNumbers), ', ')
            para = Paragraph(allText, self.textStyle)
            tableData.append([para])

        self._table = Table(tableData, colWidths=[availWidth])

        self.width, self.height = self._table.wrapOn(self.canv,availWidth, availHeight)
        return (self.width, self.height)

    def drawOn(self, canvas, x, y, _sW=0):
        """Don't do this at home!  The standard calls for implementing
        draw(); we are hooking this in order to delegate ALL the drawing
        work to the embedded table object.
        """
        self._table.drawOn(canvas, x, y, _sW)
示例#42
0
    def save(self):
        self.draw_header()

        self.canvas.drawCentredString(cm(10.5), cm(19), "REFUND NOTE {0} FOR INVOICE NUMBER {1}".format(self.refundid, self.invoicenum))

        self.canvas.drawString(cm(2), cm(18), "Reason for refund: {0}".format(self.reason))

        tblpaid = [
            ["Amount paid"],
            ["Item", "Amount"],
            ["Amount", "{0:.2f} {1}".format(self.invoiceamount, settings.CURRENCY_SYMBOL)],
        ]
        tblrefunded = [
            ["Amount refunded"],
            ["Item", "Amount"],
            ["Amount", "{0:.2f} {1}".format(self.refundamount, settings.CURRENCY_SYMBOL)],
        ]
        tblprevious = [
            ["Amount previously refunded"],
            ["Item", "Amount"],
            ["Amount", "{0:.2f} {1}".format(self.previousamount, settings.CURRENCY_SYMBOL)],
        ]
        if self.invoicevat:
            tblpaid.extend([
                ["VAT", "{0:.2f} {1}".format(self.invoicevat, settings.CURRENCY_SYMBOL)],
                ["", "{0:.2f} {1}".format(self.invoiceamount + self.invoicevat, settings.CURRENCY_SYMBOL)],
            ])
            tblrefunded.extend([
                ["VAT", "{0:.2f} {1}".format(self.refundvat, settings.CURRENCY_SYMBOL)],
                ["", "{0:.2f} {1}".format(self.refundamount + self.refundvat, settings.CURRENCY_SYMBOL)],
            ])
            tblprevious .extend([
                ["VAT", "{0:.2f} {1}".format(self.previousvat, settings.CURRENCY_SYMBOL)],
                ["", "{0:.2f} {1}".format(self.previousamount + self.previousvat, settings.CURRENCY_SYMBOL)],
            ])

        style = [
            ('SPAN', (0, 0), (1, 0)),
            ('BACKGROUND', (0, 0), (-1, 0), colors.lightgrey),
            ('ALIGN', (0, 0), (0, 0), 'CENTER'),
            ('ALIGN', (1, 1), (1, -1), 'RIGHT'),
            ('LINEBELOW', (0, 1), (-1, 1), 1, colors.black),
            ('OUTLINE', (0, 0), (-1, -1), 1, colors.black),
        ]
        if self.invoicevat:
            style.append(
                ('LINEABOVE', (-1, -1), (-1, -1), 2, colors.black),
            )

        t = Table(tblpaid, [cm(10.5), cm(2.5), cm(1.5), cm(2.5)])
        t.setStyle(TableStyle(style))
        w, h = t.wrapOn(self.canvas, cm(10), cm(10))
        t.drawOn(self.canvas, (self.canvas._pagesize[0] - w) // 2, cm(17) - h)

        if self.previousamount:
            t = Table(tblprevious, [cm(10.5), cm(2.5), cm(1.5), cm(2.5)])
            t.setStyle(TableStyle(style))
            w, h = t.wrapOn(self.canvas, cm(10), cm(10))
            t.drawOn(self.canvas, (self.canvas._pagesize[0] - w) // 2, cm(17) - h * 2 - cm(1))
            extraofs = h + cm(1)
        else:
            extraofs = 0

        t = Table(tblrefunded, [cm(10.5), cm(2.5), cm(1.5), cm(2.5)])
        t.setStyle(TableStyle(style))
        w, h = t.wrapOn(self.canvas, cm(10), cm(10))
        t.drawOn(self.canvas, (self.canvas._pagesize[0] - w) // 2, cm(17) - h * 2 - cm(1) - extraofs)

        self.canvas.drawCentredString(cm(10.5), cm(16.3) - h * 2 - cm(2) - extraofs, "This refund was issued {0}".format(timezone.localtime(self.refunddate).strftime("%B %d, %Y")))

        if self.paymentmethod:
            self.canvas.drawCentredString(cm(10.5), cm(16.3) - h * 2 - cm(3) - extraofs, "Refunded to the original form of payment: {0}.".format(self.paymentmethod))

        self.canvas.showPage()
        self.canvas.save()

        return self.pdfdata
示例#43
0
    def draw_course_info(self, y_pos):
        """
        Draws the main table containing the data items.
        """
        course_items_data = [[
            '', (_('Description')), (_('Quantity')),
            (_('List Price\nper item')), (_('Discount\nper item')),
            (_('Amount')), ''
        ]]
        for row_item in self.items_data:
            course_items_data.append([
                '',
                Paragraph(row_item['item_description'],
                          getSampleStyleSheet()['Normal']),
                row_item['quantity'], '{list_price:.2f} {currency}'.format(
                    list_price=row_item['list_price'], currency=self.currency),
                '{discount:.2f} {currency}'.format(
                    discount=row_item['discount'], currency=self.currency),
                '{item_total:.2f} {currency}'.format(
                    item_total=row_item['item_total'],
                    currency=self.currency), ''
            ])

        padding_width = 7 * mm
        desc_col_width = 60 * mm
        qty_col_width = 26 * mm
        list_price_col_width = 21 * mm
        discount_col_width = 21 * mm
        amount_col_width = 40 * mm
        course_items_table = Table(course_items_data, [
            padding_width, desc_col_width, qty_col_width, list_price_col_width,
            discount_col_width, amount_col_width, padding_width
        ],
                                   splitByRow=1,
                                   repeatRows=1)

        course_items_table.setStyle(
            TableStyle([
                #List Price, Discount, Amount data items
                ('ALIGN', (3, 1), (5, -1), 'RIGHT'),

                # Amount header
                ('ALIGN', (5, 0), (5, 0), 'RIGHT'),

                # Amount column (header + data items)
                ('RIGHTPADDING', (5, 0), (5, -1), 7 * mm),

                # Quantity, List Price, Discount header
                ('ALIGN', (2, 0), (4, 0), 'CENTER'),

                # Description header
                ('ALIGN', (1, 0), (1, -1), 'LEFT'),

                # Quantity data items
                ('ALIGN', (2, 1), (2, -1), 'CENTER'),

                # Lines below the header and at the end of the table.
                ('LINEBELOW', (0, 0), (-1, 0), 1.00, '#cccccc'),
                ('LINEBELOW', (0, -1), (-1, -1), 1.00, '#cccccc'),

                # Innergrid around the data rows.
                ('INNERGRID', (1, 1), (-2, -1), 0.50, '#cccccc'),

                # Entire table
                ('VALIGN', (0, 0), (-1, -1), 'MIDDLE'),
                ('TOPPADDING', (0, 0), (-1, -1), 2 * mm),
                ('BOTTOMPADDING', (0, 0), (-1, -1), 2 * mm),
                ('TEXTCOLOR', (0, 0), (-1, -1), colors.black),
            ]))
        rendered_width, rendered_height = course_items_table.wrap(0, 0)
        table_left_padding = (self.page_width - rendered_width) / 2

        split_tables = course_items_table.split(
            0, self.first_page_available_height)
        if len(split_tables) > 1:
            # The entire Table won't fit in the available space and requires splitting.
            # Draw the part that can fit, start a new page
            # and repeat the process with the rest of the table.
            split_table = split_tables[0]
            __, rendered_height = split_table.wrap(0, 0)
            split_table.drawOn(self.pdf, table_left_padding,
                               y_pos - rendered_height)

            self.prepare_new_page()
            split_tables = split_tables[1].split(
                0, self.second_page_available_height)
            while len(split_tables) > 1:
                split_table = split_tables[0]
                __, rendered_height = split_table.wrap(0, 0)
                split_table.drawOn(
                    self.pdf, table_left_padding,
                    self.second_page_start_y_pos - rendered_height)

                self.prepare_new_page()
                split_tables = split_tables[1].split(
                    0, self.second_page_available_height)
            split_table = split_tables[0]
            __, rendered_height = split_table.wrap(0, 0)
            split_table.drawOn(self.pdf, table_left_padding,
                               self.second_page_start_y_pos - rendered_height)
        else:
            # Table will fit without the need for splitting.
            course_items_table.drawOn(self.pdf, table_left_padding,
                                      y_pos - rendered_height)

        if not self.is_on_first_page():
            y_pos = self.second_page_start_y_pos

        return y_pos - rendered_height - self.min_clearance
示例#44
0
class TableOfContents(IndexingFlowable):
    """This creates a formatted table of contents.

    It presumes a correct block of data is passed in.
    The data block contains a list of (level, text, pageNumber)
    triplets.  You can supply a paragraph style for each level
    (starting at zero).
    """

    def __init__(self):
        self.entries = []
        self.rightColumnWidth = 72
        self.levelStyles = [levelZeroParaStyle,
                            levelOneParaStyle,
                            levelTwoParaStyle,
                            levelThreeParaStyle,
                            levelFourParaStyle]
        self.tableStyle = defaultTableStyle
        self._table = None
        self._entries = []
        self._lastEntries = []


    def beforeBuild(self):
        # keep track of the last run
        self._lastEntries = self._entries[:]
        self.clearEntries()


    def isIndexing(self):
        return 1


    def isSatisfied(self):
        return (self._entries == self._lastEntries)

    def notify(self, kind, stuff):
        """The notification hook called to register all kinds of events.

        Here we are interested in 'TOCEntry' events only.
        """
        if kind == 'TOCEntry':
            (level, text, pageNum) = stuff
            self.addEntry(level, text, pageNum)


    def clearEntries(self):
        self._entries = []


    def addEntry(self, level, text, pageNum):
        """Adds one entry to the table of contents.

        This allows incremental buildup by a doctemplate.
        Requires that enough styles are defined."""

        assert type(level) == type(1), "Level must be an integer"
        assert level < len(self.levelStyles), \
               "Table of contents must have a style defined " \
               "for paragraph level %d before you add an entry" % level

        self._entries.append((level, text, pageNum))


    def addEntries(self, listOfEntries):
        """Bulk creation of entries in the table of contents.

        If you knew the titles but not the page numbers, you could
        supply them to get sensible output on the first run."""

        for (level, text, pageNum) in listOfEntries:
            self.addEntry(level, text, pageNum)


    def wrap(self, availWidth, availHeight):
        "All table properties should be known by now."

        widths = (availWidth - self.rightColumnWidth,
                  self.rightColumnWidth)

        # makes an internal table which does all the work.
        # we draw the LAST RUN's entries!  If there are
        # none, we make some dummy data to keep the table
        # from complaining
        if len(self._lastEntries) == 0:
            _tempEntries = [(0,'Placeholder for table of contents',0)]
        else:
            _tempEntries = self._lastEntries

        tableData = []
        for (level, text, pageNum) in _tempEntries:
            leftColStyle = self.levelStyles[level]
            #right col style is right aligned
            rightColStyle = ParagraphStyle(name='leftColLevel%d' % level,
                                           parent=leftColStyle,
                                           leftIndent=0,
                                           alignment=enums.TA_RIGHT)
            leftPara = Paragraph(text, leftColStyle)
            rightPara = Paragraph(str(pageNum), rightColStyle)
            tableData.append([leftPara, rightPara])

        self._table = Table(tableData, colWidths=widths,
                            style=self.tableStyle)

        self.width, self.height = self._table.wrapOn(self.canv,availWidth, availHeight)
        return (self.width, self.height)


    def split(self, availWidth, availHeight):
        """At this stage we do not care about splitting the entries,
        we will just return a list of platypus tables.  Presumably the
        calling app has a pointer to the original TableOfContents object;
        Platypus just sees tables.
        """
        return self._table.splitOn(self.canv,availWidth, availHeight)


    def drawOn(self, canvas, x, y, _sW=0):
        """Don't do this at home!  The standard calls for implementing
        draw(); we are hooking this in order to delegate ALL the drawing
        work to the embedded table object.
        """
        self._table.drawOn(canvas, x, y, _sW)
示例#45
0
def HeaderFooterSolicitudes(canvas,doc):
		canvas.saveState()
		title = "Reporte de las solicitudes - SolicitudeDV"
		canvas.setTitle(title)
		
		Story=[]
		styles = getSampleStyleSheet()
		
		archivo_imagen = finders.find('img/MDHV.png')
		canvas.drawImage(archivo_imagen, 30, 740, width=540,height=100,preserveAspectRatio=True)

		fecha = datetime.now().strftime('%d/%m/%Y ')
		# Estilos de Párrafos
		ta_c = ParagraphStyle('parrafos', 
							alignestt = TA_CENTER,
							fontSize = 11,
							fontName="Helvetica-Bold",
							)	
		ta_l = ParagraphStyle('parrafos', 
							alignestt = TA_LEFT,
							fontSize = 13,
							fontName="Helvetica-Bold",
							)
		ta_l7 = ParagraphStyle('parrafos', 
							alignestt = TA_LEFT,
							fontSize = 7,
							fontName="Helvetica-Bold",
							)
		ta_r = ParagraphStyle('parrafos', 
							alignestt = TA_RIGHT,
							fontSize = 13,
							fontName="Helvetica-Bold",
							)

		# Header
		header = Paragraph("<u>REPORTE DE LAS SOLICITUDES</u> ",ta_l,)
		w,h = header.wrap(doc.width-130, doc.topMargin)
		header.drawOn(canvas, 35, doc.height +10 + doc.topMargin - 25)

		header1 = Paragraph("<u>MINISTERIO DE HÁBITAT Y VIVIENDA</u> ",ta_r,)
		w,h = header1.wrap(doc.width-115, doc.topMargin)
		header1.drawOn(canvas, 180, doc.height +40 + doc.topMargin - 2)

		P1 = Paragraph('''<b>N°</b>''',ta_c)
		P2 = Paragraph('''<b>NUMERO DE OFICIO</b>''',ta_c)
		P3 = Paragraph('''<b>SOLICITANTE</b>''',ta_c)
		P4 = Paragraph('''<b>FECHA</b>''',ta_c)
		data= [[P1, P2, P3, P4]]
		header2 = Table(data, colWidths = [35,150,150,80,255])
		header2.setStyle(TableStyle( 
			[	
				('GRID', (0, -1), (-1, -1), 1, colors.black),
				('BACKGROUND', (0, 0), (-1, 0), colors.lightyellow)
			]
			))
		w,h = header2.wrap(doc.width-115, doc.topMargin)
		header2.drawOn(canvas, 75, doc.height +5 + doc.topMargin - 60)

		# Llamado del Modelo Director
		#director = get_object_or_404(Director)

		#if director.sexo == "Feestino":
		#	sexo = "DIRECTORA"
		#else:
		#	sexo = "DIRECTOR"

		# FOOTER
		footer = Paragraph("Atentamente,",ta_c)
		w, h = footer.wrap(doc.width -125, doc.bottomMargin -275) 
		footer.drawOn(canvas, doc.height -230, doc.topMargin +35, h)

		footer1 = Paragraph("_______________________________",ta_c)
		w, h = footer1.wrap(doc.width -120, doc.bottomMargin - 15) 
		footer1.drawOn(canvas, doc.height -290, doc.topMargin -1, w)

		footer2 = Paragraph("Luis R" + " Jiménez R",ta_c)
		w, h = footer2.wrap(doc.width -240, doc.bottomMargin -275) 
		footer2.drawOn(canvas,doc.height -240, doc.topMargin -15, h)

		footer3 = Paragraph("Director Estadal"+" De  Hábitat" + " y Vivienda",ta_c)
		w, h = footer3.wrap(doc.width -250, doc.bottomMargin) 
		footer3.drawOn(canvas,doc.height -290, doc.topMargin -30, h)

		footer4 = Paragraph("Del Estado "+"Portuguesa",ta_c)
		w, h = footer4.wrap(doc.width -300, doc.bottomMargin) 
		footer4.drawOn(canvas,doc.height -250, doc.topMargin -45, h)

		footer5 = Paragraph("Publicada en gaceta oficial Nº "+ " 41.356 " + " de fecha 08/03/2018",ta_c)
		w, h = footer5.wrap(doc.width -200, doc.bottomMargin) 
		footer5.drawOn(canvas,doc.height -355, doc.topMargin -60, h)

		footer6 = Paragraph("Designada mendiante resolución Nº"+" 055 de fecha 06/03/2018",ta_c)
		w, h = footer6.wrap(doc.width -150, doc.bottomMargin) 
		footer6.drawOn(canvas,doc.height -360, doc.topMargin -75, h)

		footer7 = Paragraph("Fecha de expedición: "+str(fecha),ta_l7)
		w, h = footer7.wrap(doc.width -200, doc.bottomMargin) 
		footer7.drawOn(canvas,doc.height -470, doc.topMargin -185, h)

		canvas.restoreState()
示例#46
0
def HeaderFooterTrans(canvas, doc):
    canvas.saveState()
    title = "Reporte de Transacciones"
    canvas.setTitle(title)

    Story = []
    styles = getSampleStyleSheet()

    archivo_imagen = finders.find('assets/img/logo.jpg')
    canvas.drawImage(archivo_imagen,
                     30,
                     720,
                     width=540,
                     height=100,
                     preserveAspectRatio=True)

    fecha = datetime.now().strftime('%d/%m/%Y ')
    # Estilos de Párrafos
    ta_c = ParagraphStyle(
        'parrafos',
        alignment=TA_CENTER,
        fontSize=10,
        fontName="Helvetica",
    )
    ta_l = ParagraphStyle(
        'parrafos',
        alignment=TA_LEFT,
        fontSize=13,
        fontName="Helvetica-Bold",
    )
    ta_l7 = ParagraphStyle(
        'parrafos',
        alignment=TA_LEFT,
        fontSize=7,
        fontName="Helvetica-Bold",
    )
    ta_r = ParagraphStyle(
        'parrafos',
        alignment=TA_CENTER,
        fontSize=11,
        fontName="Helvetica-Bold",
    )

    # Header
    header = Paragraph(
        "REPORTE DE TRANSACCIONES ",
        ta_l,
    )
    w, h = header.wrap(doc.width + 250, doc.topMargin)
    header.drawOn(canvas, 215, doc.height - 10 + doc.topMargin - 80)

    total1 = Paragraph(
        "Total: " + str(total) + " bs.",
        ta_l,
    )
    w, h = total1.wrap(doc.width + 250, doc.topMargin)
    total1.drawOn(canvas, 425, doc.height - 10 + doc.topMargin - 60)

    meses = Paragraph(
        "Mes: " + str(mes1) + ".",
        ta_l,
    )
    w, h = meses.wrap(doc.width + 250, doc.topMargin)
    meses.drawOn(canvas, 75, doc.height - 10 + doc.topMargin - 60)

    #header1 = Paragraph("<u>DIRECCIÓN DE AGRICULTURA Y TIERRA</u> ",ta_r,)
    #w,h = header1.wrap(doc.width-115, doc.topMargin)
    #header1.drawOn(canvas, 140, doc.height -10 + doc.topMargin - 2)

    P1 = Paragraph('''N°''', ta_c)
    P2 = Paragraph('''FECHA''', ta_c)
    P3 = Paragraph('''TIPO''', ta_c)
    P4 = Paragraph('''MONTO''', ta_c)
    data = [[P1, P2, P3, P4]]
    header2 = Table(data, colWidths=[35, 85, 80, 250])
    header2.setStyle(
        TableStyle([
            ('GRID', (0, -1), (-1, -1), 1, colors.black),
            ('BACKGROUND', (0, 0), (-1, 0), '#50b7e6'),
            ('ALIGN', (0, 0), (-1, -3), "CENTER"),
        ]))
    w, h = header2.wrap(doc.width - 115, doc.topMargin)
    header2.drawOn(canvas, 72.5, doc.height - 40 + doc.topMargin - 93)

    # FOOTER

    footer4 = Paragraph("Fecha: " + str(fecha), ta_l7)
    w, h = footer4.wrap(doc.width - 200, doc.bottomMargin)
    footer4.drawOn(canvas, doc.height - 105, doc.topMargin + 620, h)

    canvas.restoreState()