pdfinvoice

This commit is contained in:
mdipierro
2013-08-21 05:07:53 -05:00
parent 70a8284cb5
commit d162499e73
2 changed files with 162 additions and 1 deletions
+1 -1
View File
@@ -1 +1 @@
Version 2.6.0-development+timestamp.2013.08.21.04.38.11
Version 2.6.0-development+timestamp.2013.08.21.05.07.02
+161
View File
@@ -0,0 +1,161 @@
"""
BSD license - created by Massimo Di Pierro
"""
from reportlab.pdfgen.canvas import Canvas
from reportlab.platypus import Table
from reportlab.lib.pagesizes import A4
from reportlab.lib.units import cm
from decimal import Decimal
import cStringIO
import datetime
def listify(item):
if isinstance(item,basestring):
item = item.split('\n')
return item
class PDF(object):
def __init__(self, page_size=A4, font_face='Helvetica'):
self.page_size = page_size
self.font_face = font_face
self.logo = None
def format_currency(self,value):
a = list(str(int(value)))
for k in range(len(a)-3,0,-3):
a.insert(k,',')
a = ''.join(a)
b = ("%.2f" % (value-int(value)))[2:]
return "%s.%s" % (a,b)
def draw(self, invoice, items_page=10):
""" Draws the invoice """
buffer = cStringIO.StringIO()
invoice_items = invoice['items']
pages = max((len(invoice_items)-2)/items_page+1,1)
canvas = Canvas(buffer, pagesize=self.page_size)
for page in range(pages):
canvas.translate(0, 29.7 * cm)
canvas.setFont(self.font_face, 10)
canvas.saveState()
canvas.setStrokeColorRGB(0.9, 0.5, 0.2)
canvas.setFillColorRGB(0.2, 0.2, 0.2)
canvas.setFont(self.font_face, 16)
canvas.drawString(1 * cm, -1 * cm, invoice.get('title',''))
if self.logo:
canvas.drawInlineImage(self.logo, 1 * cm, -1 * cm, 250, 16)
canvas.setLineWidth(4)
canvas.line(0, -1.25 * cm, 21.7 * cm, -1.25 * cm)
canvas.restoreState()
canvas.saveState()
notes = listify(invoice.get('notes',''))
textobject = canvas.beginText(1 * cm, -25 * cm)
for line in notes:
textobject.textLine(line)
canvas.drawText(textobject)
textobject = canvas.beginText(18 * cm, -28 * cm)
textobject.textLine('Pag.%s/%s' % (page+1,pages))
canvas.drawText(textobject)
canvas.restoreState()
canvas.saveState()
business_details = listify(invoice.get('from','FROM:'))
canvas.setFont(self.font_face, 9)
textobject = canvas.beginText(13 * cm, -2.5 * cm)
for line in business_details:
textobject.textLine(line)
canvas.drawText(textobject)
canvas.restoreState()
canvas.saveState()
client_info = listify(invoice.get('to','TO:'))
textobject = canvas.beginText(1.5 * cm, -2.5 * cm)
for line in client_info:
textobject.textLine(line)
canvas.drawText(textobject)
canvas.restoreState()
textobject = canvas.beginText(1.5 * cm, -6.75 * cm)
textobject.textLine(u'Invoice ID: %s' % invoice.get('id','<invoice id>'))
textobject.textLine(u'Invoice Date: %s' % invoice.get('date',datetime.date.today()))
textobject.textLine(u'Client: %s' % invoice.get('client_name','<invoice client>'))
canvas.drawText(textobject)
items = invoice_items[1:][page*items_page:(page+1)*items_page]
if items:
data = [invoice_items[0]]
for item in items:
data.append([
self.format_currency(x)
if isinstance(x,float) else x
for x in item])
righta = [k for k,v in enumerate(items[0])
if isinstance(v,(int,float,Decimal))]
if page == pages-1:
total = self.format_currency(invoice['total'])
else:
total = ''
data.append(['']*(len(items[0])-1)+[total])
colWidths = [2.5*cm]*len(items[0])
colWidths[1] = (21.5-2.5*len(items[0]))*cm
table = Table(data, colWidths=colWidths)
table.setStyle([
('FONT', (0, 0), (-1, -1), self.font_face),
('FONTSIZE', (0, 0), (-1, -1), 8),
('TEXTCOLOR', (0, 0), (-1, -1), (0.2, 0.2, 0.2)),
('GRID', (0, 0), (-1, -2), 1, (0.7, 0.7, 0.7)),
('GRID', (-1, -1), (-1, -1), 1, (0.7, 0.7, 0.7)),
('BACKGROUND', (0, 0), (-1, 0), (0.8, 0.8, 0.8)),
]+[('ALIGN',(k,0),(k,-1),'RIGHT') for k in righta])
tw, th, = table.wrapOn(canvas, 15 * cm, 19 * cm)
table.drawOn(canvas, 1 * cm, -8 * cm - th)
if page == pages-1:
items = invoice['totals'][1:]
if items:
data = [invoice['totals'][0]]
for item in items:
data.append([
self.format_currency(x)
if isinstance(x,float) else x
for x in item])
righta = [k for k,v in enumerate(items[0])
if isinstance(v,(int,float,Decimal))]
total = self.format_currency(invoice['total'])
data.append(['']*(len(items[0])-1)+[total])
colWidths = [2.5*cm]*len(items[0])
colWidths[1] = (21.5-2.5*len(items[0]))*cm
table = Table(data, colWidths=colWidths)
table.setStyle([
('FONT', (0, 0), (-1, -1), self.font_face),
('FONTSIZE', (0, 0), (-1, -1), 8),
('TEXTCOLOR', (0, 0), (-1, -1), (0.2, 0.2, 0.2)),
('GRID', (0, 0), (-1, -2), 1, (0.7, 0.7, 0.7)),
('GRID', (-1, -1), (-1, -1), 1, (0.7, 0.7, 0.7)),
('BACKGROUND', (0, 0), (-1, 0), (0.8, 0.8, 0.8)),
]+[('ALIGN',(k,0),(k,-1),'RIGHT') for k in righta])
tw, th, = table.wrapOn(canvas, 15 * cm, 19 * cm)
table.drawOn(canvas, 1 * cm, -18 * cm - th)
canvas.showPage()
canvas.save()
return buffer.getvalue()
if __name__=='__main__':
invoice = {
'title': 'Invoice - web2py.com',
'id': '00001',
'date': '10/10/2013',
'client_name': 'Nobody',
'from': 'FROM:\nweb2py.com\nWabash ave\nChicago',
'to': 'TO:\nNobody\nHis address',
'notes': 'no comment!',
'total': 650.00,
'items': [
['Codice','Desc','Quantity','Unit price','Total']]+[
['000001','Chair',2,10.0,20.0] for k in range(30)],
'totals': [
['Codice','Desc','Total']]+[
['000001','Chairs',600.0],
['','Tax',50.0]],
}
print PDF().draw(invoice,items_page=20)