Code: Alles auswählen
class myPDF(BaseDocTemplate):
def __init__(self, filename, work, **kw):
self.allowSplitting = 0
BaseDocTemplate.__init__(*(self, filename), **kw)
self.format = A4
self.breite, self.hoehe = self.format
self.author = 'noisefloor'
self.title = 'ReportLab Document'
self.subject = 'ReportLab Demo'
[self.NAME, self.NAME2, self.NAME_ADDITION, self.STREET,
self.PLZ, self.ORT, self.FIRMA, self.TELEFON, self.FAX,
self.EMAIL, self.INTERNET, self.BANK, self.BIC, self.IBAN,
self.UST_IDENT, self.RECHTSFORM] = IDENT
if work['RECHNUNG']:
invoice, table = work['RECHNUNG']
(self.adresse, self.invoice_data, self.invoice_head,
self.invoice_widths, self.invoice_style) = invoice
(self.data, self.table_head, self.table_widths,
self.table_style) = table
self.encrypt = pdfencrypt.StandardEncryption('',
ownerPassword='noisefloor',
canPrint=1,
canModify=0,
canCopy=0,
canAnnotate=1,
strength=40)
self.style = getSampleStyleSheet()
self.story = []
@staticmethod
def buildHeadFoot(canvas, doc):
print('buildHeadFoot', doc.page)
canvas.saveState()
canvas.setFillColorRGB(0, 0, 0)
# Head
grafik = '{}{}'.format(Path('reportlab'), 'Firmenkopf.png')
canvas.drawImage(grafik, doc.breite-(7.8*cm), doc.hoehe-( 2.2*cm),
width=6.8* cm, height=1.7* cm)
# Foot
canvas.line(2*cm, 2.25 * cm, doc.breite-(0.5*cm), 2.25 * cm)
canvas.setStrokeColor('#BFBFBF')
canvas.setFont('Helvetica', 8.5)
# Spalte 1 Adresse
canvas.drawString(doc.breite-(19*cm), 1.75 *cm, doc.FIRMA)
canvas.drawString(doc.breite-(19*cm), 1.35 *cm, doc.NAME2)
canvas.drawString(doc.breite-(19*cm), 0.95 *cm, doc.STREET)
canvas.drawString(doc.breite-(19*cm), 0.55 *cm,
doc.PLZ + ' ' + doc.ORT)
# Spalte 2 Komunikation-Definition
canvas.drawString(doc.breite-(15.05*cm), 1.75 *cm, 'Telefon:')
canvas.drawString(doc.breite-(15.05*cm), 1.35 *cm, 'Fax:')
canvas.drawString(doc.breite-(15.05*cm), 0.95 *cm, 'E-Mail:')
canvas.drawString(doc.breite-(15.05*cm), 0.55 *cm, 'Internet:')
canvas.drawString(doc.breite-(13.8*cm), 1.75 *cm, doc.TELEFON)
canvas.drawString(doc.breite-(13.8*cm), 1.35 *cm, doc.FAX)
canvas.drawString(doc.breite-(13.8*cm), 0.95 *cm, doc.EMAIL)
canvas.drawString(doc.breite-(13.8*cm), 0.55 *cm, doc.INTERNET)
# Spalte 3 Bank-Definition
canvas.drawString(doc.breite-(10.6*cm), 1.75 *cm, doc.BANK)
canvas.drawString(doc.breite-(10.6*cm), 1.35 *cm, 'BIC:')
canvas.drawString(doc.breite-(10.6*cm), 0.95 *cm, 'IBAN:')
canvas.drawString(doc.breite-(9.7*cm), 1.35 *cm, doc.BIC)
canvas.drawString(doc.breite-(9.7*cm), 0.95 *cm, doc.IBAN)
# Spalte 5 Definition Inhaber, USt-Ident-Nr
canvas.drawString(doc.breite-(5*cm), 1.75 *cm, 'Inhaber:')
canvas.drawString(doc.breite-(5*cm), 1.35 *cm, 'Rechtsform:')
canvas.drawString(doc.breite-(5*cm), 0.95 *cm, 'USt-Ident-Nr.:')
canvas.drawString(doc.breite-(3*cm), 1.75 *cm, doc.NAME2)
canvas.drawString(doc.breite-(3*cm), 1.35 *cm, doc.RECHTSFORM)
canvas.drawString(doc.breite-(3*cm), 0.95 *cm, doc.UST_IDENT)
b, h = doc.breite, doc.hoehe
if doc.page == 1:
# Absendeadresse
canvas.drawString(doc.breite-(19*cm), 25.7 *cm,
'{}, {}, {}'.format(doc.FIRMA, doc.STREET,
doc.PLZ + ' ' + doc.ORT))
# Zieladresse
canvas.setFont('Helvetica', 11)
name, name2, street, plz_ort = doc.adresse
canvas.drawString(doc.breite-(19*cm), 25 *cm, name)
canvas.drawString(doc.breite-(19*cm), 24.5 *cm, name2)
canvas.drawString(doc.breite-(19*cm), 23.8 *cm, street)
canvas.drawString(doc.breite-(19*cm), 23.3 *cm, plz_ort)
# Erstelle Rechnung, erste Seite
doc.buildInvoiceFirst(canvas, doc)
if doc.page > 1:
# Erstelle Rechnung, zweite und weitere Seiten
doc.buildInvoiceNext(canvas, doc)
canvas.restoreState()
@staticmethod
def buildInvoiceFirst(canvas, doc):
print('buildInvoiceFirst', doc.page)
canvas.saveState()
canvas.setFillColorRGB(0, 0, 0)
# Rechnungkopf
canvas.setFont('Helvetica', 16)
canvas.drawString(doc.breite-(19*cm), doc.hoehe-(9.1 *cm),
'RECHNUNG')
canvas.setFont('Helvetica', 10)
doc.invoice_data[2] = '{} von {}'.format(doc.page, '3')
t0 = Table([doc.invoice_head, doc.invoice_data],
colWidths=doc.invoice_widths, style=doc.invoice_style)
t0.wrapOn(canvas, doc.breite, doc.hoehe)
t0.drawOn(canvas, *doc.coord(6.8, 9.5, cm))
canvas.setFont('Helvetica', 10)
# Tabellenkopf
new_list = [doc.table_head]
t1 = Table(new_list, colWidths=doc.table_widths,
style=doc.table_style)
t1.wrapOn(canvas, doc.breite, doc.hoehe)
t1.drawOn(canvas, *doc.coord(2, 11.05, cm))
canvas.setFillColorRGB(0, 0, 0)
canvas.setFont('Helvetica', 8)
text = 'LEISTUNGSZEITPUNKT IST IDENTISCH MIT DEM MONAT DES RECHNUNGDATUMS!'
canvas.drawString(doc.breite-(14.2*cm), doc.hoehe-(9.9 *cm), text)
canvas.restoreState()
@staticmethod
def buildInvoiceNext(canvas, doc):
print('buildInvoiceNext', doc.page)
canvas.saveState()
canvas.setFillColorRGB(0, 0, 0)
# Rechnungkopf
canvas.setFont('Helvetica', 16)
canvas.drawString(doc.breite-(19*cm), doc.hoehe-(4.1 *cm), 'RECHNUNG')
canvas.setFont('Helvetica', 10)
doc.invoice_data[2] = '{} von {}'.format(doc.page, '3')
t0 = Table([doc.invoice_head, doc.invoice_data],
colWidths=doc.invoice_widths, style=doc.invoice_style)
t0.wrapOn(canvas, doc.breite, doc.hoehe)
t0.drawOn(canvas, *doc.coord(6.8, 4.5, cm))
canvas.setFont('Helvetica', 10)
# Tabellenkopf
t1 = Table([doc.table_head], colWidths=doc.table_widths,
style=doc.table_style)
t1.wrapOn(canvas, doc.breite, doc.hoehe)
t1.drawOn(canvas, *doc.coord(2, 6.2, cm))
canvas.setFont('Helvetica', 8)
text = 'LEISTUNGSZEITPUNKT IST IDENTISCH MIT DEM MONAT DES RECHNUNGDATUMS!'
canvas.drawString(doc.breite-(14.2*cm), doc.hoehe-(4.9 *cm), text)
canvas.restoreState()
def coord(self, x, y, unit=1):
x, y = x * unit, self.hoehe - y * unit
return x, y
def build_story(self):
#Frame definieren
b, h = self.breite, self.hoehe
# Page 1
f = Frame(1.7*cm, 2*cm, b - (2 * cm), h - (12.2 * cm),
showBoundary=0, leftPadding=0, rightPadding=0, id='firstPage')
f1 = Frame(1.7*cm, 2*cm, b - (2 * cm), h - (7.2 * cm),
showBoundary=0, leftPadding=0, rightPadding=0, id='nextPages')
#PageTemplate definieren
self.addPageTemplates([
PageTemplate(id='firstPage',frames=f, onPage=self.buildHeadFoot),
PageTemplate(id='nextPages',frames=f1, onPage=self.buildHeadFoot)
])
self.story.append(NextPageTemplate('nextPages'))
#Inhalt generieren
for i in self.data:
print(i)
if isinstance(i, str):
self.story.append(Paragraph(i, self.style['BodyText']))
elif isinstance(i, list) or isinstance(i, tuple):
for text in i:
self.story.append(Paragraph(text, self.style['BodyText']))
else:
print('Für Type: %s, gibt es keine Workline!' % type(i))
return
def build_table(self):
#Frame definieren
b, h = self.breite, self.hoehe
# Page 1
f = Frame(1.7*cm, 2*cm, b - (2 * cm), h - (12.8 * cm),
showBoundary=0, leftPadding=0, rightPadding=0, id='firstPage')
f1 = Frame(1.7*cm, 2*cm, b - (2 * cm), h - (8 * cm),
showBoundary=0, leftPadding=0, rightPadding=0, id='nextPages')
#PageTemplate definieren
self.addPageTemplates([
PageTemplate(id='firstPage',frames=f, onPage=self.buildHeadFoot),
PageTemplate(id='nextPages',frames=f1, onPage=self.buildHeadFoot)
])
self.story.append(NextPageTemplate('nextPages'))
new_list = list()
for i, x in enumerate(self.data):
line = list()
for text in x:
line.append(Paragraph(text, self.style['BodyText']))
new_list.append(line)
if i == 20:
self.story.append(Table(new_list, colWidths=self.table_widths,
style=self.table_style))
new_list = list()
self.story.append(Table(new_list, colWidths=self.table_widths,
style=self.table_style))
return
def main():
filename = '/home/pfad/zu/mein.pdf'
invoice_head = ['NUMMER', 'DATUM', 'SEITE', 'POS', 'REFERENZ', 'KUNDE']
invoice_data = ['12345678', '2015.04.09', '1 von 3', '12', 'REFERENZ', 'KUNDE']
invoice_widths=(2.5*cm, 2.5*cm, 2.5*cm, 1.5*cm, 2.3*cm, 2.3*cm)
invoice_style=[('GRID',(0,0),(-1,-1),0.5,'#BFBFBF'),
('ALIGN',(2,0),(2,-1),'CENTER'),
('ALIGN',(3,0),(3,-1),'CENTER'),
('BACKGROUND',(0,0),(-1,0), '#EAEAEA'),
('FONTSIZE',(0,0),(-1,-1), 10)]
story = [['001', '50', 'STÜCK', '100000', 'TEST', '12345678901234567890123456789012345678901234567890 TEST ENTHÄLT TEXT', '0.75', '37.50'],
['002', '5000', 'STÜCK', '100000', '4711ABC', 'KARTOFFELCHIPS', '0.75', '3.75'],
['003', '50', 'STÜCK', '100000', '9999ABC', 'BLEISTIFT HB', '0.25', '12.50'],
['004', '1', 'PALETTE', '100000', '750089123', 'KOPIERPAPIER A4', '700.00', '700.00'],
['005', '1', 'PALETTE', '100000', '750089123', 'KOPIERPAPIER A4', '700.00', '700.00'],
['006', '50', 'STÜCK', '100000', 'TEST', '12345678901234567890123456789012345678901234567890 TEST ENTHÄLT TEXT', '0.75', '37.50'],
['007', '5000', 'STÜCK', '100000', '4711ABC', 'KARTOFFELCHIPS', '0.75', '3.75'],
['008', '50', 'STÜCK', '100000', '9999ABC', 'BLEISTIFT HB', '0.25', '12.50'],
['009', '1', 'PALETTE', '100000', '750089123', 'KOPIERPAPIER A4', '700.00', '700.00'],
['010', '1', 'PALETTE', '100000', '750089123', 'KOPIERPAPIER A4', '700.00', '700.00'],
['011', '50', 'STÜCK', '100000', 'TEST', '12345678901234567890123456789012345678901234567890 TEST ENTHÄLT TEXT', '0.75', '37.50'],
['012', '5000', 'STÜCK', '100000', '4711ABC', 'KARTOFFELCHIPS', '0.75', '3.75'],
['013', '50', 'STÜCK', '100000', '9999ABC', 'BLEISTIFT HB', '0.25', '12.50'],
['014', '1', 'PALETTE', '100000', '750089123', 'KOPIERPAPIER A4', '700.00', '700.00'],
['015', '1', 'PALETTE', '100000', '750089123', 'KOPIERPAPIER A4', '700.00', '700.00'],
['016', '50', 'STÜCK', '100000', 'TEST', '12345678901234567890123456789012345678901234567890 TEST ENTHÄLT TEXT', '0.75', '37.50'],
['017', '5000', 'STÜCK', '100000', '4711ABC', 'KARTOFFELCHIPS', '0.75', '3.75'],
['018', '50', 'STÜCK', '100000', '9999ABC', 'BLEISTIFT HB', '0.25', '12.50'],
['019', '1', 'PALETTE', '100000', '750089123', 'KOPIERPAPIER A4', '700.00', '700.00'],
['020', '1', 'PALETTE', '100000', '750089123', 'KOPIERPAPIER A4', '700.00', '700.00'],
['021', '50', 'STÜCK', '100000', 'TEST', '12345678901234567890123456789012345678901234567890 TEST ENTHÄLT TEXT', '0.75', '37.50'],
['022', '5000', 'STÜCK', '100000', '4711ABC', 'KARTOFFELCHIPS', '0.75', '3.75'],
['023', '50', 'STÜCK', '100000', '9999ABC', 'BLEISTIFT HB', '0.25', '12.50'],
['024', '1', 'PALETTE', '100000', '750089123', 'KOPIERPAPIER A4', '700.00', '700.00'],
['025', '1', 'PALETTE', '100000', '750089123', 'KOPIERPAPIER A4', '700.00', '700.00'],
['026', '50', 'STÜCK', '100000', 'TEST', '12345678901234567890123456789012345678901234567890 TEST ENTHÄLT TEXT', '0.75', '37.50'],
['027', '5000', 'STÜCK', '100000', '4711ABC', 'KARTOFFELCHIPS', '0.75', '3.75'],
['028', '50', 'STÜCK', '100000', '9999ABC', 'BLEISTIFT HB', '0.25', '12.50'],
['029', '1', 'PALETTE', '100000', '750089123', 'KOPIERPAPIER A4', '700.00', '700.00'],
['030', '1', 'PALETTE', '100000', '750089123', 'KOPIERPAPIER A4', '700.00', '700.00'],
['031', '50', 'STÜCK', '100000', 'TEST', '12345678901234567890123456789012345678901234567890 TEST ENTHÄLT TEXT', '0.75', '37.50'],
['032', '5000', 'STÜCK', '100000', '4711ABC', 'KARTOFFELCHIPS', '0.75', '3.75'],
['033', '50', 'STÜCK', '100000', '9999ABC', 'BLEISTIFT HB', '0.25', '12.50'],
['034', '1', 'PALETTE', '100000', '750089123', 'KOPIERPAPIER A4', '700.00', '700.00'],
['035', '1', 'PALETTE', '100000', '750089123', 'KOPIERPAPIER A4', '700.00', '700.00'],
['036', '50', 'STÜCK', '100000', 'TEST', '12345678901234567890123456789012345678901234567890 TEST ENTHÄLT TEXT', '0.75', '37.50'],
['037', '5000', 'STÜCK', '100000', '4711ABC', 'KARTOFFELCHIPS', '0.75', '3.75'],
['038', '50', 'STÜCK', '100000', '9999ABC', 'BLEISTIFT HB', '0.25', '12.50'],
['039', '1', 'PALETTE', '100000', '750089123', 'KOPIERPAPIER A4', '700.00', '700.00'],
['040', '1', 'PALETTE', '100000', '750089123', 'KOPIERPAPIER A4', '700.00', '700.00'],
['041', '50', 'STÜCK', '100000', 'TEST', '12345678901234567890123456789012345678901234567890 TEST ENTHÄLT TEXT', '0.75', '37.50'],
['042', '5000', 'STÜCK', '100000', '4711ABC', 'KARTOFFELCHIPS', '0.75', '3.75'],
['043', '50', 'STÜCK', '100000', '9999ABC', 'BLEISTIFT HB', '0.25', '12.50'],
['044', '1', 'PALETTE', '100000', '750089123', 'KOPIERPAPIER A4', '700.00', '700.00'],
['045', '1', 'PALETTE', '100000', '750089123', 'KOPIERPAPIER A4', '700.00', '700.00'],
['046', '50', 'STÜCK', '100000', 'TEST', '12345678901234567890123456789012345678901234567890 TEST ENTHÄLT TEXT', '0.75', '37.50'],
['047', '5000', 'STÜCK', '100000', '4711ABC', 'KARTOFFELCHIPS', '0.75', '3.75'],
['048', '50', 'STÜCK', '100000', '9999ABC', 'BLEISTIFT HB', '0.25', '12.50'],
['049', '1', 'PALETTE', '100000', '750089123', 'KOPIERPAPIER A4', '700.00', '700.00'],
['050', '1', 'PALETTE', '100000', '750089123', 'KOPIERPAPIER A4', '700.00', '700.00'],
['051', '50', 'STÜCK', '100000', 'TEST', '12345678901234567890123456789012345678901234567890 TEST ENTHÄLT TEXT', '0.75', '37.50'],
['052', '5000', 'STÜCK', '100000', '4711ABC', 'KARTOFFELCHIPS', '0.75', '3.75'],
['053', '50', 'STÜCK', '100000', '9999ABC', 'BLEISTIFT HB', '0.25', '12.50'],
['054', '1', 'PALETTE', '100000', '750089123', 'KOPIERPAPIER A4', '700.00', '700.00'],
['055', '1', 'PALETTE', '100000', '750089123', 'KOPIERPAPIER A4', '700.00', '700.00'],]
table_head = ['POS', 'ME', 'VE', 'INHALT', 'ARTIKEL',
'BENENNUNG, # ZEILENINFO', 'EP', 'GP']
table_widths=(1.05*cm, 1.25*cm, 2*cm, 1.7*cm, 2.3*cm, 5.5*cm, 2.3*cm, 2.3*cm)
table_style=[('GRID',(0,0),(-1,-1),0.5,'#BFBFBF'),
('LINEABOVE',(0,0),(7,0),1,'#BFBFBF'),
('LINEABOVE',(0,1),(7,1),1,'#BFBFBF'),
('VALIGN',(0,0),(-1,-1),'TOP'),
('ALIGN',(0,0),(1,-1),'CENTER'),
('ALIGN',(5,0),(5,-1),'CENTER'),
('ALIGN',(6,0),(6,-1),'CENTER'),
('ALIGN',(1,1),(1,-1),'RIGHT'),
('ALIGN',(6,1),(6,-1),'RIGHT'),
('ALIGN',(7,1),(7,-1),'RIGHT'),
('BACKGROUND',(0,0),(-1,0), '#EAEAEA'),
('FONTSIZE',(0,0),(-1,-1), 10)]
adresse = ['Müller AG', 'Maschinenteile', 'Teststr. 75', '12345 Piepshausen']
work = {'RECHNUNG' : [[adresse, invoice_data, invoice_head,
invoice_widths, invoice_style], [story, table_head, table_widths,
table_style]]}
with open(filename, 'wb') as f:
pdf = myPDF(filename, work)
pdf.build_table()
#pdf.build_story()
pdf.multiBuild(pdf.story)
if __name__ == '__main__':
main()
Seite 1 kann ein anderes Layout, als die Folgeseiten besitzen.
Die Tabelle passt sich nun den Seiten entsprechend an.
Was noch fehlt, ist die Aktualisierung der Seitenangaben (Page of AllPages).
Tips und Verbesserungen, gerne jeder Zeit.