Пример #1
0
 def tabela(self, largura, altura, dados, colWidths=None, rowHeights=None, style=None, repeatRows=0, repeatCols=0, splitByRow=1, emptyTableAction=None, ident=None, hAlign=None, vAlign=None):
     # Escape dados str ou unicode
     dados = [[escape(d) if isinstance(d, (str, unicode)) else d for d in l] for l in dados]
     # Renderizar 1 linha
     tabela = Table(dados[:1], colWidths, rowHeights, style, repeatRows, repeatCols, splitByRow, emptyTableAction, ident, hAlign, vAlign)
     l, a = tabela.wrapOn(self.canvas, largura, altura)
     # Quantas linhas dessa altura cabem
     linhas = int(altura/a)
     # Renderizar linhas
     tabela = Table(dados[:linhas], colWidths, rowHeights, style, repeatRows, repeatCols, splitByRow, emptyTableAction, ident, hAlign, vAlign)
     l, a = tabela.wrapOn(self.canvas, largura, altura)
     # Se não couber, vou tirando de 1 em 1
     if a > altura:
         for i in range(linhas, 0, -1):
             tabela = Table(dados[:i], colWidths, rowHeights, style, repeatRows, repeatCols, splitByRow, emptyTableAction, ident, hAlign, vAlign)
             l, a = tabela.wrapOn(self.canvas, largura, altura)
             if a <= altura:
                 break
         return (tabela, i, a)
     # Se couber, vou colocando de 1 em 1
     i = linhas
     for i in range(linhas, len(dados)):
         tabela = Table(dados[:i], colWidths, rowHeights, style, repeatRows, repeatCols, splitByRow, emptyTableAction, ident, hAlign, vAlign)
         l, a = tabela.wrapOn(self.canvas, largura, altura)
         if a > altura:
             break
     i -= 1
     tabela = Table(dados[:i], colWidths, rowHeights, style, repeatRows, repeatCols, splitByRow, emptyTableAction, ident, hAlign, vAlign)
     l, a = tabela.wrapOn(self.canvas, largura, altura)
     return (tabela, i, a)
Пример #2
0
 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
 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
 def tabela(self,
            largura,
            altura,
            dados,
            colWidths=None,
            rowHeights=None,
            style=None,
            repeatRows=0,
            repeatCols=0,
            splitByRow=1,
            emptyTableAction=None,
            ident=None,
            hAlign=None,
            vAlign=None):
     # Escape dados str ou unicode
     dados = [[
         escape(d) if isinstance(d, (str, unicode)) else d for d in l
     ] for l in dados]
     # Renderizar 1 linha
     tabela = Table(dados[:1], colWidths, rowHeights, style, repeatRows,
                    repeatCols, splitByRow, emptyTableAction, ident, hAlign,
                    vAlign)
     l, a = tabela.wrapOn(self.canvas, largura, altura)
     # Quantas linhas dessa altura cabem
     linhas = int(altura / a)
     # Renderizar linhas
     tabela = Table(dados[:linhas], colWidths, rowHeights, style,
                    repeatRows, repeatCols, splitByRow, emptyTableAction,
                    ident, hAlign, vAlign)
     l, a = tabela.wrapOn(self.canvas, largura, altura)
     # Se não couber, vou tirando de 1 em 1
     if a > altura:
         for i in range(linhas, 0, -1):
             tabela = Table(dados[:i], colWidths, rowHeights, style,
                            repeatRows, repeatCols, splitByRow,
                            emptyTableAction, ident, hAlign, vAlign)
             l, a = tabela.wrapOn(self.canvas, largura, altura)
             if a <= altura:
                 break
         return (tabela, i, a)
     # Se couber, vou colocando de 1 em 1
     i = linhas
     for i in range(linhas, len(dados)):
         tabela = Table(dados[:i], colWidths, rowHeights, style, repeatRows,
                        repeatCols, splitByRow, emptyTableAction, ident,
                        hAlign, vAlign)
         l, a = tabela.wrapOn(self.canvas, largura, altura)
         if a > altura:
             break
     i -= 1
     tabela = Table(dados[:i], colWidths, rowHeights, style, repeatRows,
                    repeatCols, splitByRow, emptyTableAction, ident, hAlign,
                    vAlign)
     l, a = tabela.wrapOn(self.canvas, largura, altura)
     return (tabela, i, a)
Пример #5
0
	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)
Пример #6
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)
Пример #7
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()
Пример #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 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)
Пример #13
0
class PmlTableOfContents(TableOfContents):

    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

        i = 0
        lastMargin = 0
        tableData = []
        tableStyle = [
            ('VALIGN', (0, 0), (- 1, - 1), 'TOP'),
            ('LEFTPADDING', (0, 0), (- 1, - 1), 0),
            ('RIGHTPADDING', (0, 0), (- 1, - 1), 0),
            ('TOPPADDING', (0, 0), (- 1, - 1), 0),
            ('BOTTOMPADDING', (0, 0), (- 1, - 1), 0),
            ]
        for entry in _tempEntries:
            level, text, pageNum = entry[:3]
            leftColStyle = self.levelStyles[level]
            if i:  # Not for first element
                tableStyle.append((
                    'TOPPADDING',
                    (0, i), (- 1, i),
                    max(lastMargin, leftColStyle.spaceBefore)))
            # print leftColStyle.leftIndent
            lastMargin = leftColStyle.spaceAfter
            #right col style is right aligned
            rightColStyle = ParagraphStyle(name='leftColLevel%d' % level,
                                           parent=leftColStyle,
                                           leftIndent=0,
                                           alignment=TA_RIGHT)
            leftPara = Paragraph(text, leftColStyle)
            rightPara = Paragraph(str(pageNum), rightColStyle)
            tableData.append([leftPara, rightPara])
            i += 1

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

        self.width, self.height = self._table.wrapOn(self.canv, availWidth, availHeight)
        return (self.width, self.height)
Пример #14
0
class PmlTableOfContents(TableOfContents):

    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

        i = 0
        lastMargin = 0
        tableData = []
        tableStyle = [
            ('VALIGN', (0, 0), (- 1, - 1), 'TOP'),
            ('LEFTPADDING', (0, 0), (- 1, - 1), 0),
            ('RIGHTPADDING', (0, 0), (- 1, - 1), 0),
            ('TOPPADDING', (0, 0), (- 1, - 1), 0),
            ('BOTTOMPADDING', (0, 0), (- 1, - 1), 0),
            ]
        for entry in _tempEntries:
            level, text, pageNum = entry[:3]
            leftColStyle = self.levelStyles[level]
            if i:  # Not for first element
                tableStyle.append((
                    'TOPPADDING',
                    (0, i), (- 1, i),
                    max(lastMargin, leftColStyle.spaceBefore)))
            # print leftColStyle.leftIndent
            lastMargin = leftColStyle.spaceAfter
            #right col style is right aligned
            rightColStyle = ParagraphStyle(name='leftColLevel%d' % level,
                                           parent=leftColStyle,
                                           leftIndent=0,
                                           alignment=TA_RIGHT)
            leftPara = Paragraph(text, leftColStyle)
            rightPara = Paragraph(str(pageNum), rightColStyle)
            tableData.append([leftPara, rightPara])
            i += 1

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

        self.width, self.height = self._table.wrapOn(self.canv, availWidth, availHeight)
        return (self.width, self.height)
Пример #15
0
	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()
	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()
Пример #18
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]
Пример #19
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)
Пример #20
0
def pdf(group, username, list, show_header=True, show_footer=True):
    """PDF version of list"""

    content = BytesIO()

    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

    grid_style = TableStyle(parent=GRID_STYLE)

    # 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, f"{group}: {list.name}"
        )
        p.setFont(font_name, font_size_small)
        p.drawString(
            margin,
            height - margin - font_size - font_size + 2,
            "%s: %s %s %s"
            % (_("Printed"), str(date.today()), _("by"), username),
        )

    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, " - ".join(footer))

        blacklisted_note = _("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 = _("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 = _(
            "Sorry, this list isn't set up correctly, "
            "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 = [_("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(_("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
Пример #21
0
        data.append(aux[:max_page])
        aux = aux[max_page:]
    data.append(aux)

for d in data:
    table_height = (len(d) * rowHeight)
    table = Table(thead, colWidths=colWidth, rowHeights=20)
    table.setStyle(
        TableStyle([
            ('INNERGRID', (0, 0), (-1, -1), 0.25, colors.red),
            ('BOX', (0, 0), (-1, -1), 0.25, colors.black),
            ('ALIGN', (0, 0), (-1, -1), 'CENTER'),
            ('TEXTCOLOR', (0, 0), (-1, 0), colors.red),
        ]))

    table.wrapOn(c, width, height)
    table.drawOn(c, 0, 200 * mm - 20)

    table = Table(d, colWidths=colWidth, rowHeights=rowHeight)
    table.setStyle(
        TableStyle([
            ('INNERGRID', (0, 0), (-1, -1), 0.25, colors.black),
            ('BOX', (0, 0), (-1, -1), 0.25, colors.black),
            ('ALIGN', (0, 0), (-1, -1), 'CENTER'),
            ('TEXTCOLOR', (0, 0), (-1, 0), colors.red),
        ]))

    table.wrapOn(c, height, width)
    table.drawOn(c, 0, 200 * mm - table_height - 20)

    c.drawString(2 * mm, 205 * mm, "Welcome to Reportlab!")
Пример #22
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)
Пример #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
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)
Пример #26
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
Пример #27
0
    def save(self):
        # We can fit ROWS_PER_PAGE 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) // self.ROWS_PER_PAGE + 1):
            self.draw_header()
            islastpage = (pagenum == (len(self.rows) - 1) // self.ROWS_PER_PAGE)

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

            self.canvas.setFont('DejaVu Serif Bold', 12)
            self.canvas.setFillColor(colors.black)
            # Center between 2 and 19 is 10.5
            self.canvas.drawCentredString(cm(10.5), cm(19), self.title)
            self.canvas.setFont('DejaVu Serif', 9)

            if self.invoicenum:
                if self.receipt:
                    self.canvas.drawCentredString(cm(10.5), cm(18.5), "Receipt for invoice number %s%s" % (self.invoicenum, suffix))
                else:
                    self.canvas.drawCentredString(cm(10.5), cm(18.5), "Invoice number %s - %s%s" % (self.invoicenum, timezone.localtime(self.invoicedate).strftime("%B %d, %Y"), suffix))
                self.canvas.setFont('DejaVu Serif Bold', 10)
                if self.receipt:
                    self.canvas.drawString(cm(15), cm(28), "Receipt #%s" % self.invoicenum)
                else:
                    self.canvas.drawString(cm(15), cm(28), "Invoice #%s" % self.invoicenum)
                    if self.bankinfo:
                        self.canvas.setFont('DejaVu Serif Bold', 8)
                        self.canvas.drawString(cm(15), cm(27.5), "Payment ref: %s" % self.paymentref)
            else:
                self.canvas.drawCentredString(cm(10.5), cm(18.5), "Receipt - %s%s" % (timezone.localtime(self.invoicedate).strftime("%B %d, %Y"), suffix))

            if pagenum == 0:
                firstcol = "Item"
            else:
                firstcol = "Item - continued from page %s" % pagenum

            if settings.EU_VAT:
                tbldata = [[firstcol, "Quantity", "Ex VAT", "VAT", "Incl VAT"]]
            else:
                tbldata = [[firstcol, "Quantity", "Price", "Total"]]
            tblcols = len(tbldata[0])

            if settings.EU_VAT:
                tbldata.extend([(self.trimstring(title, cm(9.5), "DejaVu Serif", 8),
                                 count,
                                 "%.2f %s" % (cost, settings.CURRENCY_SYMBOL),
                                 vatrate and vatrate.shortstr or "No VAT",
                                 "%.2f %s" % ((cost * count) * (1 + (vatpercent / Decimal(100))), settings.CURRENCY_SYMBOL))
                                for title, cost, count, vatrate, vatpercent in self.rows[pagenum * self.ROWS_PER_PAGE:(pagenum + 1) * self.ROWS_PER_PAGE]])
            else:
                tbldata.extend([(self.trimstring(title, cm(9.5), "DejaVu Serif", 8),
                                 count,
                                 "%.2f %s" % (cost, settings.CURRENCY_SYMBOL),
                                 "%.2f %s" % ((cost * count), settings.CURRENCY_SYMBOL))
                                for title, cost, count, vatrate, vatpercent in self.rows[pagenum * self.ROWS_PER_PAGE:(pagenum + 1) * self.ROWS_PER_PAGE]])

            style = [
                # Set global font size
                ('FONTSIZE', (0, 0), (-1, -1), 8),
                # Right-align all columnsexcept the first one (item name)
                ('ALIGN', (1, 0), (tblcols - 1, -1), 'RIGHT'),
                # Draw header line background in light gray and line under it
                ('BACKGROUND', (0, 0), (tblcols - 1, 0), colors.lightgrey),
                ('LINEBELOW', (0, 0), (-1, 0), 2, colors.black),
                # Draw an outline around the whole table
                ('OUTLINE', (0, 0), (-1, -1), 1, colors.black),
            ]

            if islastpage:
                totalexcl = sum([cost * count for title, cost, count, vatrate, vatpercent in self.rows])

                if settings.EU_VAT:
                    # When EU vat enabled, calculate total fields both with and without VAT,
                    # and special-case the reverse-VAT situation.
                    totalvat = sum([(cost * count * (vatpercent / Decimal(100))).quantize(Decimal('0.01')) for title, cost, count, vatrate, vatpercent in self.rows])
                    totalincl = sum([(cost * count * (1 + vatpercent / Decimal(100))).quantize(Decimal('0.01')) for title, cost, count, vatrate, vatpercent in self.rows])

                    if self.totalvat > 0 and totalvat != self.totalvat:
                        raise Exception("Specified total VAT {0} does not match calculated VAT {1}".format(self.totalvat, totalvat))

                    if self.reverse_vat:
                        if totalvat != 0:
                            raise Exception("Can't use reverse VAT and specified VAT at the same time!")
                        vathdr = 'Total VAT *'
                        vatstr = "0 %s *" % (settings.CURRENCY_SYMBOL, )
                    else:
                        vathdr = 'Total VAT'
                        vatstr = '%.2f %s' % (totalvat, settings.CURRENCY_SYMBOL)

                    tbldata.extend([
                        ('Total excl VAT', '', '', '', '%.2f %s' % (totalexcl, settings.CURRENCY_SYMBOL)),
                        (vathdr, '', '', '', vatstr),
                        ('Total incl VAT', '', '', '', '%.2f %s' % (totalincl, settings.CURRENCY_SYMBOL)),
                    ])

                    style.extend([
                        # For the tree "total excl", "cat", "total incl" lines, span the
                        # cells together and alight right, and draw a line above them.
                        ('SPAN', (0, -3), (3, -3)),
                        ('SPAN', (0, -2), (3, -2)),
                        ('SPAN', (0, -1), (3, -1)),
                        ('ALIGN', (0, -3), (0, -1), 'RIGHT'),
                        ('LINEABOVE', (-4, -3), (-1, -3), 2, colors.black),
                    ])
                else:
                    # No EU vat, so just a simple total
                    tbldata.extend([
                        ('Total', '', '',
                         '%.2f %s' % (totalexcl, settings.CURRENCY_SYMBOL)),
                    ])

                    # Merge the cells of the total line together, right-align them, and
                    # draw a line above them.
                    style.extend([
                        ('SPAN', (0, -1), (2, -1)),
                        ('ALIGN', (0, -1), (0, -1), 'RIGHT'),
                        ('LINEABOVE', (-3, -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), 'DejaVu Serif Italic'))

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

            self.canvas.setFont('DejaVu Serif Bold', 10)
            if self.receipt:
                self.canvas.drawCentredString(cm(10.5), cm(17.3) - h, "This invoice was paid %s" % timezone.localtime(self.duedate).strftime("%B %d, %Y"))
            else:
                self.canvas.drawCentredString(cm(10.5), cm(17.3) - h, "This invoice is due: %s" % timezone.localtime(self.duedate).strftime("%B %d, %Y"))
                if self.bankinfo:
                    self.canvas.setFont('DejaVu Serif', 8)
                    self.canvas.drawCentredString(cm(10.5), cm(16.8) - h, "If paying with bank transfer, use payment reference %s" % self.paymentref)

            if islastpage:
                self.draw_footer()

            # 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
Пример #28
0
def makeRampart(fire, days, dates, maps, sim_output, scores):
    """!
    Make summary page for RamPART and risk
    @param fire Fire name to use
    @param days Array of days simulation created output for
    @param dates Array of dates simulation created output for
    @param maps List of maps to use for cover page thumbnails
    @param sim_output Array of simulation output, by line
    @param scores Array of scores for simulation output dates
    @return Path of RamPART summary page PDF
    """
    size = float(
        find_line(sim_output, 'Fire starting with size', 'size ')[:-2])
    sizes = find_lines(sim_output, ' size at end of day')
    confirmed = find_line(sim_output, 'Initialized WxShield with date')[-16:]
    numSims = int(find_line(sim_output, 'simulations', 'Ran ').split(' ')[0])
    showSims = "{:,}".format(numSims)
    score = scores[-1]
    showScore = score
    lat_find = "Using ignition point ("
    lat_long = find_line(sim_output, lat_find, lat_find)[:-1].split(',')
    lat = float(lat_long[0].strip())
    lon = float(lat_long[1].strip())
    loc_find = 'UTM coordinates are: '
    location = find_line(sim_output, loc_find, loc_find)
    runTime = sim_output[1][1:20]
    startup = find_lines(sim_output, 'Startup indices ')
    startup = startup[0] if (
        len(startup) > 0) else "Startup indices are not valid"
    txtStartup = startup[startup.find("Startup indices "):]
    rampart = os.path.join(os.path.dirname(maps[0]), fire + "_rampart.pdf")
    title = "{} - {}".format(fire, dates[0])
    #
    c = canvas.Canvas(rampart, LANDSCAPE)
    c.rect(MARGIN / 3,
           MARGIN / 3,
           PAGE_WIDTH - 2 * MARGIN / 3,
           PAGE_HEIGHT - 2 * MARGIN / 3,
           fill=0)
    c.setFillColor(colors.white)
    c.rect(MARGIN / 2, PAGE_HEIGHT - MARGIN, 220, 20, fill=1)
    c.setFillColor(colors.black)
    c.setFont(NORMAL, 20)
    c.drawString(MARGIN, PAGE_HEIGHT - MARGIN, 'Part 2: Impact & Risk')
    c.setFont(BOLD, 36)
    c.drawCentredString(IMAGE_WIDTH / 2, PAGE_HEIGHT - 3 * MARGIN, title)
    c.drawInlineImage(r'C:\FireGUARD\mapping\logo_all.png', MARGIN / 2,
                      PAGE_HEIGHT - (3.5 * MARGIN + LOGO_HEIGHT), LOGO_WIDTH,
                      LOGO_HEIGHT)
    c.setFont(BOLD, 20)
    c.drawCentredString(MARGIN + 1.4 * LOGO_WIDTH, PAGE_HEIGHT - (5 * MARGIN),
                        'Total Risk')
    c.setFont(BOLD, 12)
    c.drawCentredString(MARGIN + 1.4 * LOGO_WIDTH, PAGE_HEIGHT - (6 * MARGIN),
                        '(on day 14)')
    c.setFont(BOLD, 36)
    c.drawCentredString(MARGIN + 1.4 * LOGO_WIDTH, PAGE_HEIGHT - (9 * MARGIN),
                        showScore)
    #
    c.setFont(BOLD, 12)
    t = Table([['Simulation Start', confirmed], ['Location', location],
               ['Initial size (ha)', "{:,}".format(size)],
               ['Model run', runTime], ['Simulations', showSims]])
    t.setStyle(
        TableStyle([
            ('INNERGRID', (0, 0), (-1, -1), 0.25, colors.black),
            ('BOX', (0, 0), (-1, -1), 0.25, colors.black),
        ]))
    #
    w, h = t.wrapOn(c, 0, 0)
    t.drawOn(c, 2 * LOGO_WIDTH + MARGIN, PAGE_HEIGHT - (9.7 * MARGIN))
    c.drawInlineImage(maps[1], MARGIN + IMAGE_WIDTH, MARGIN + 2 * IMAGE_HEIGHT,
                      IMAGE_WIDTH, IMAGE_HEIGHT)
    c.drawInlineImage(maps[0], MARGIN + 2 * IMAGE_WIDTH,
                      MARGIN + 2 * IMAGE_HEIGHT, IMAGE_WIDTH, IMAGE_HEIGHT)
    c.drawInlineImage(maps[2], MARGIN + IMAGE_WIDTH, MARGIN + IMAGE_HEIGHT,
                      IMAGE_WIDTH, IMAGE_HEIGHT)
    c.drawInlineImage(maps[4], MARGIN + 2 * IMAGE_WIDTH, MARGIN + IMAGE_HEIGHT,
                      IMAGE_WIDTH, IMAGE_HEIGHT)
    c.drawInlineImage(maps[3], MARGIN + IMAGE_WIDTH, MARGIN, IMAGE_WIDTH,
                      IMAGE_HEIGHT)
    c.drawInlineImage(maps[5], MARGIN + 2 * IMAGE_WIDTH, MARGIN, IMAGE_WIDTH,
                      IMAGE_HEIGHT)
    #
    c.setFont(BOLD, 20)
    c.drawString(MARGIN, 630, 'Check:')

    def mkPoint(title, text, y):
        c.setFont(BOLD, 10)
        c.drawString(MARGIN, y, "- " + title)
        c.setFont(NORMAL, 10)
        c.drawString(110, y, text)

    mkPoint("Burn Probability",
            "Is it accurate? Does it make sense? What were the assumptions?",
            615)
    mkPoint("ARs",
            'Can they be burnt? Are they located in areas of "non-fuel"?', 600)
    c.setFont(BOLD, 20)
    c.drawString(MARGIN, 580, "Product Description:")
    mkPoint("Potential Impact",
            "What would happen if the entire area were to burn with 100%", 565)
    c.drawString(110, 550, "certainty at a high fire intensity?")
    mkPoint("Total Risk", "The sum of the risk per cell for the entire area.",
            535)
    mkPoint(
        "Risk Map",
        "The impact (adjusted for different fire intensities) times the likelihood",
        520)
    c.drawString(110, 505, "that a cell is burnt, giving the risk per cell.")
    c.setFont(BOLD, 20)
    c.drawString(MARGIN, 485, "Terminology:")
    #
    mkPoint(
        "Risk",
        'Is impact times likelihood, literally the "average" loss, as if the',
        470)
    c.drawString(110, 455, "situation was repeated many times.")
    mkPoint(
        "ARs",
        'Assests and Resources (ARs) are physical things on the landscape.',
        440)
    mkPoint("Resources", 'Are biological and other natural elements.', 425)
    mkPoint("Assets", 'Are objects built by people.', 410)
    mkPoint(
        "Fire Effects",
        'Are the physical, biological, and ecological changes to ARs and their',
        395)
    c.drawString(
        110, 380,
        'functioning caused by fire. Only "direct" effects happening')
    c.drawString(
        110, 365,
        'immediately or soon after the passage of fire are considered.')
    mkPoint(
        "Fire Impacts",
        'Are the changes in worth, as judged by people, that are caused by',
        350)
    c.drawString(
        110, 335,
        'fire effects. Impact represents loss and positive impacts are not')
    c.drawString(
        110, 320,
        'considered. There are three impact types that make up total impact:')
    c.drawString(110, 305, 'Social, Economic, and Emergency Response.')
    c.drawInlineImage(r'C:\FireGUARD\mapping\impact_flow.png', MARGIN, 200,
                      IMAGE_WIDTH, 366.0 / 1435 * IMAGE_WIDTH)
    c.drawString(MARGIN, 185, 'Q: What is the impact and risk scale?')
    c.drawString(
        MARGIN, 170,
        'A: Staff scored impacts on a 1-10 scale for each of 52 different ARs.'
    )
    data = [
        ['', 'Total Potential Impact', 'Risk (average loss)', ''],
        ['', '(HFI 4000+ kW/m)', '50% prob', '90% prob'],
        ['1 structure', '6.6', '3.3', '5.9'],
        ['100 ha of timber', '5.9', '3.0', '5.3'],
        ['1 km of hydro line', '7.0', '3.5', '6.3'],
        [
            'Example sum in 1 ha (3 structures,\n50 m of hydro line, 1 ha of timber)',
            '20.2', '10.1', '18.2'
        ]
    ]
    t = Table(data, colWidths=[170, 105, 60, 60])
    t.setStyle(
        TableStyle([
            ('GRID', (0, 0), (-1, -1), 0.25, colors.black),
            ('FONTNAME', (0, 0), (-1, 1), BOLD),
            ('FONTSIZE', (0, 0), (-1, -1), 10),
            ('ALIGN', (1, 0), (-1, 1), 'CENTER'),
            ('SPAN', (-2, 0), (-1, 0)),
        ]))
    #
    w, h = t.wrapOn(c, 0, 0)
    t.drawOn(c, MARGIN, 45)
    c.setFont(BOLD, 10)
    c.drawString(MARGIN, 30, 'Interpretation:')
    c.setFont(NORMAL, 10)
    c.drawString(
        MARGIN, 15,
        'A risk of 10 is "like" the loss of 200 ha of timber, or worse than the loss of a structure.'
    )
    c.drawCentredString(PAGE_WIDTH / 2, 5, Settings.ACTIVE_OFFER)
    c.save()
    return rampart
Пример #29
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
Пример #30
0
def makeCover(fire, days, dates, maps, sim_output, scores):
    """!
    Make cover page pdf summarizing FireSTARR results
    @param fire Fire name to use
    @param days Array of days simulation created output for
    @param dates Array of dates simulation created output for
    @param maps List of maps to use for cover page thumbnails
    @param sim_output Array of simulation output, by line
    @param scores Array of scores for simulation output dates
    @return Path of cover page PDF
    """
    size = float(
        find_line(sim_output, 'Fire starting with size', 'size ')[:-2])
    sizes = find_lines(sim_output, ' size at end of day')
    confirmed = find_line(sim_output, 'Initialized WxShield with date')[-16:]
    numSims = int(find_line(sim_output, 'simulations', 'Ran ').split(' ')[0])
    showSims = "{:,}".format(numSims)
    score = scores[-1]
    showScore = score
    lat_find = "Using ignition point ("
    lat_long = find_line(sim_output, lat_find, lat_find)[:-1].split(',')
    lat = float(lat_long[0].strip())
    lon = float(lat_long[1].strip())
    loc_find = 'UTM coordinates are: '
    location = find_line(sim_output, loc_find, loc_find)
    runTime = sim_output[1][1:20]
    startup = find_lines(sim_output, 'Startup indices ')
    startup = startup[0] if (
        len(startup) > 0) else "Startup indices are not valid"
    txtStartup = startup[startup.find("Startup indices "):]
    cover = os.path.join(os.path.dirname(maps[0]), fire + "_cover.pdf")
    title = "{} - {}".format(fire, dates[0])
    #
    c = canvas.Canvas(cover, LANDSCAPE)
    c.rect(MARGIN / 3,
           MARGIN / 3,
           PAGE_WIDTH - 2 * MARGIN / 3,
           PAGE_HEIGHT - 2 * MARGIN / 3,
           fill=0)
    c.setFillColor(colors.white)
    c.rect(MARGIN / 2, PAGE_HEIGHT - MARGIN, 220, 20, fill=1)
    c.setFillColor(colors.black)
    c.setFont(NORMAL, 20)
    c.drawString(MARGIN, PAGE_HEIGHT - MARGIN, 'Part 1: Burn Probability')
    c.setFont(BOLD, 36)
    c.drawCentredString(IMAGE_WIDTH / 2, PAGE_HEIGHT - 3 * MARGIN, title)
    c.drawInlineImage(r'C:\FireGUARD\mapping\logo_all.png', MARGIN / 2,
                      PAGE_HEIGHT - (3.5 * MARGIN + LOGO_HEIGHT), LOGO_WIDTH,
                      LOGO_HEIGHT)
    c.setFont(BOLD, 20)
    c.drawCentredString(MARGIN + 1.4 * LOGO_WIDTH, PAGE_HEIGHT - (5 * MARGIN),
                        'Total Risk')
    c.setFont(BOLD, 12)
    c.drawCentredString(MARGIN + 1.4 * LOGO_WIDTH, PAGE_HEIGHT - (6 * MARGIN),
                        '(on day 14)')
    c.setFont(BOLD, 36)
    c.drawCentredString(MARGIN + 1.4 * LOGO_WIDTH, PAGE_HEIGHT - (9 * MARGIN),
                        showScore)
    #
    c.setFont(BOLD, 12)
    t = Table([['Simulation Start', confirmed], ['Location', location],
               ['Initial size (ha)', "{:,}".format(size)],
               ['Model run', runTime], ['Simulations', showSims]])
    t.setStyle(
        TableStyle([
            ('INNERGRID', (0, 0), (-1, -1), 0.25, colors.black),
            ('BOX', (0, 0), (-1, -1), 0.25, colors.black),
        ]))
    #
    w, h = t.wrapOn(c, 0, 0)
    t.drawOn(c, 2 * LOGO_WIDTH + MARGIN, PAGE_HEIGHT - (9.7 * MARGIN))
    c.drawInlineImage(maps[1], MARGIN + IMAGE_WIDTH, MARGIN + 2 * IMAGE_HEIGHT,
                      IMAGE_WIDTH, IMAGE_HEIGHT)
    c.drawInlineImage(maps[0], MARGIN + 2 * IMAGE_WIDTH,
                      MARGIN + 2 * IMAGE_HEIGHT, IMAGE_WIDTH, IMAGE_HEIGHT)
    c.drawInlineImage(maps[2], MARGIN + IMAGE_WIDTH, MARGIN + IMAGE_HEIGHT,
                      IMAGE_WIDTH, IMAGE_HEIGHT)
    c.drawInlineImage(maps[4], MARGIN + 2 * IMAGE_WIDTH, MARGIN + IMAGE_HEIGHT,
                      IMAGE_WIDTH, IMAGE_HEIGHT)
    c.drawInlineImage(maps[3], MARGIN + IMAGE_WIDTH, MARGIN, IMAGE_WIDTH,
                      IMAGE_HEIGHT)
    c.drawInlineImage(maps[5], MARGIN + 2 * IMAGE_WIDTH, MARGIN, IMAGE_WIDTH,
                      IMAGE_HEIGHT)
    #
    c.setFont(BOLD, 10)
    c.drawCentredString(MARGIN + IMAGE_WIDTH / 2, 630, txtStartup)
    data = [['Simulated fire statistics', '', '', '', '', '', ''],
            ['', 'Date', 'Size (ha)', '', '', '', 'Total Risk'],
            [
                'Day*', '(23:59 local)', 'Min', 'Average', 'Median**', 'Max',
                '(Avg Loss)'
            ]]
    for i in xrange(len(days)):
        sizeline = 'size at end of day ' + str(days[i]) + ': '
        size = [x for x in sizes if -1 != x.find(sizeline)]
        size_split = size[0][(size[0].find(sizeline) +
                              len(sizeline)):].split(' ')
        size_min = "{:,}".format(int(round(float(size_split[0]))))
        size_max = "{:,}".format(int(round(float(size_split[3]))))
        size_median = "{:,}".format(int(round(float(size_split[9]))))
        size_mean = "{:,}".format(int(round(float(size_split[6]))))
        risk = scores[i]
        data.append([
            str(days[i]), dates[i], size_min, size_mean, size_median, size_max,
            risk
        ])
    t = Table(data, colWidths=[40, 65, 55, 55, 55, 55, 55])
    t.setStyle(
        TableStyle([
            ('GRID', (0, 0), (-1, -1), 0.25, colors.black),
            ('FONTNAME', (0, 0), (-1, 2), BOLD),
            ('ALIGN', (0, 0), (-1, -1), 'CENTER'),
            ('SPAN', (2, 1), (-2, 1)),
            ('SPAN', (0, 0), (-1, 0)),
        ]))
    #
    w, h = t.wrapOn(c, 0, 0)
    t.drawOn(c, MARGIN, 470)
    c.setFont(NORMAL, 10)
    c.drawString(MARGIN, 460, '* Day 1 is the simulation start date')
    c.drawString(
        MARGIN, 450,
        '** Half of the fires are smaller than and larger than the median size'
    )
    #
    form = c.acroForm
    #
    c.setFont(NORMAL, 12)

    def addQuestion(q, y):
        global question
        c.drawString(MARGIN, y + 8, q)
        group = 'radio' + str(question)
        form.radio(name=group,
                   tooltip='Field radio1',
                   value='yes',
                   selected=False,
                   x=170,
                   y=y,
                   buttonStyle='circle',
                   borderStyle='solid',
                   shape='circle')
        form.radio(name=group,
                   tooltip='Field radio1',
                   value='no',
                   selected=False,
                   x=195,
                   y=y,
                   buttonStyle='circle',
                   borderStyle='solid',
                   shape='circle')
        form.textfield(name='reason' + str(question),
                       tooltip='Explanation',
                       x=225,
                       y=y,
                       borderStyle='inset',
                       borderColor=colors.black,
                       fillColor=colors.white,
                       width=180,
                       height=20,
                       textColor=colors.black,
                       forceBorder=True)
        question = question + 1

    c.drawString(170, 425, 'Yes  No')
    addQuestion('Start location accurate', 400)
    addQuestion('Start size correct', 380)
    addQuestion('Perimeter most recent', 360)
    addQuestion('Fuel map accurate', 340)
    addQuestion('Startup indices appropriate', 320)
    addQuestion('Spread matches weather', 300)
    addQuestion('Projection is reasonable', 280)
    c.drawString(
        MARGIN, 260,
        'If no to any question, explain why this is still operationally useful:'
    )
    form.textfield(name='notes',
                   tooltip='Notes',
                   x=MARGIN,
                   y=235,
                   borderStyle='inset',
                   borderColor=colors.black,
                   fillColor=colors.white,
                   width=405 - MARGIN,
                   height=20,
                   textColor=colors.black,
                   forceBorder=True)
    #
    c.setFont(BOLD, 20)
    c.drawString(MARGIN, 215, 'Reviewed by:')
    form.textfield(name='reviewer',
                   tooltip='Reviewed by',
                   x=145,
                   y=213,
                   borderStyle='inset',
                   borderColor=colors.black,
                   fillColor=colors.white,
                   width=260,
                   height=20,
                   textColor=colors.black,
                   forceBorder=True)
    #
    c.setFont(BOLD, 13)
    c.drawString(MARGIN, 195, 'Interpreting the burn probability maps:')
    c.setFont(NORMAL, 12)
    c.drawString(
        MARGIN, 180,
        'Fire growth is simulated for thousands of individual weather and fire'
    )
    c.drawString(
        MARGIN, 164,
        'behaviour scenarios. The burn probability is the fraction of scenarios in'
    )
    c.drawString(
        MARGIN, 148,
        'which each cell burned. It is extremely unlikely that the whole coloured'
    )
    c.drawString(MARGIN, 132, 'area burned in a single scenario.')
    #
    c.setFont(BOLD, 13)
    c.drawString(MARGIN, 116, 'Warning - Experimental Model')
    c.setFont(NORMAL, 12)
    c.drawString(
        MARGIN, 100,
        'Any operational use should only be done with caution and awareness of'
    )
    c.drawString(
        MARGIN, 84,
        'the assumptions and simplifications. The model spreads over a virtual grid'
    )
    c.drawString(
        MARGIN, 68,
        'of 1 ha cells derived from Ontario\'s FBP Fuel Model. Assumes no')
    c.drawString(
        MARGIN, 52,
        'suppression. Does not represent fine scale barriers (small creeks, etc.) or'
    )
    c.drawString(
        MARGIN, 36,
        'long-range spotting. This model is under continuous development, and can'
    )
    c.drawString(MARGIN, 20, 'change at any time.')
    c.setFont(BOLD, 10)
    c.drawCentredString(PAGE_WIDTH / 2, 5, Settings.ACTIVE_OFFER)
    c.save()
    return cover
Пример #31
0
stylesTable = fontsize = 7

# Inicializa altura para empezar a escribir
high = 650

# Se declaran las ventas
ventas = [
	{'id' : '1', 'name' : 'Tupper', 'price' : '$130', 'quantity' : '3'},
	{'id' : '2', 'name' : 'Cuchara', 'price' : '$10', 'quantity' : '2'},
	{'id' : '2', 'name' : 'Vaso', 'price' : '$40', 'quantity' : '4'},
]

# Se agrega la informacion de las ventas a la lista
for venta in ventas:
	this_venta = [venta['id'], venta['name'], venta['price'], venta['quantity']]
	ticket.append(this_venta)
	high = high - 18

#  Se dibuja el contorno de la tabla
width, heigth = A4
table = Table(ticket, colWidths = [1.9 * cm, 9.5 * cm, 1.9 * cm, 1.9 * cm])
table.setStyle(TableStyle([
	('INNERGRID', (0, 0), (-1, -1), 0.25, colors.black),
	('BOX', (0, 0), (-1, -1), 0.25, colors.black), ]))

table.wrapOn(c, width, heigth)
table.drawOn(c, 30, high)
c.showPage()

# Save PDF
c.save()
Пример #32
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
Пример #33
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)
Пример #34
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)
Пример #35
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)
Пример #36
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()
Пример #37
0
class MyTableOfContents(TableOfContents):
    """
    Subclass of reportlab.platypus.tableofcontents.TableOfContents
    which supports hyperlinks to corresponding sections.
    """
    def __init__(self, *args, **kwargs):

        # The parent argument is to define the locality of
        # the TOC. If it's none, it's a global TOC and
        # any heading it's notified about is accepted.

        # If it's a node, then the heading needs to be "inside"
        # that node. This can be figured out because
        # the heading flowable keeps a reference to the title
        # node it was creatd from.
        #
        # Yes, this is gross.

        self.parent = kwargs.pop('parent')
        TableOfContents.__init__(self, *args, **kwargs)
        # reference ids for which this TOC should be notified
        self.refids = []
        # revese lookup table from (level, text) to refid
        self.refid_lut = {}
        self.linkColor = "#0000ff"

    def notify(self, kind, stuff):
        # stuff includes (level, text, pagenum, label)
        level, text, pageNum, label, node = stuff
        rlabel = '-'.join(label.split('-')[:-1])

        def islocal(_node):
            """See if this node is "local enough" for this TOC.
            This is for Issue 196"""
            if self.parent is None:
                return True
            while _node.parent:
                if _node.parent == self.parent:
                    return True
                _node = _node.parent
            return False

        if rlabel in self.refids and islocal(node):
            self.addEntry(level, text, pageNum)
            self.refid_lut[(level, text, pageNum)] = label

    def wrap(self, availWidth, availHeight):
        """Adds hyperlink to toc entry."""

        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, None)]
        else:
            _tempEntries = self._lastEntries

        if _tempEntries:
            base_level = _tempEntries[0][0]
        else:
            base_level = 0
        tableData = []
        for entry in _tempEntries:
            level, text, pageNum = entry[:3]
            left_col_level = level - base_level
            leftColStyle = self.getLevelStyle(left_col_level)
            label = self.refid_lut.get((level, text, pageNum), None)
            if label:
                pre = u'<a href="#%s" color="%s">' % (label, self.linkColor)
                post = u'</a>'
                if isinstance(text, bytes):
                    text = text.decode('utf-8')
                text = pre + text + post
            else:
                pre = ''
                post = ''
            # right col style is right aligned
            rightColStyle = ParagraphStyle(
                name='leftColLevel%d' % left_col_level,
                parent=leftColStyle,
                leftIndent=0,
                alignment=TA_RIGHT,
            )
            leftPara = Paragraph(text, leftColStyle)
            rightPara = Paragraph(pre + str(pageNum) + post, 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, aW, aH):
        # Make sure _table exists before splitting.
        # This was only triggered in rare cases using sphinx.
        if not self._table:
            self.wrap(aW, aH)
        return TableOfContents.split(self, aW, aH)

    def isSatisfied(self):
        if self._entries == self._lastEntries:
            log.debug('Table Of Contents is stable')
            return True
        else:
            if len(self._entries) != len(self._lastEntries):
                log.info('Number of items in TOC changed '
                         'from %d to %d, not satisfied' %
                         (len(self._lastEntries), len(self._entries)))
                return False

            log.info('TOC entries that moved in this pass:')
            for i in range(len(self._entries)):
                if self._entries[i] != self._lastEntries[i]:
                    log.info(str(self._entries[i]))
                    log.info(str(self._lastEntries[i]))

        return False
Пример #38
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)
Пример #39
0
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
Пример #40
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
Пример #41
0
class PmlTableOfContents(TableOfContents):
    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]), literal_eval(
                label[2])
            if level == 2:
                return
            style = self.getLevelStyle(level)
            if level <= 1:
                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 = TocParagraph(
                '%s<onDraw name="drawTOCEntryEnd" label="%d,%d,%s"/>' %
                (text, pageNum, level, keyVal),
                style,
                level=level)
            # import ipdb; ipdb.set_trace()
            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)