Stampe HTML e PDFvelocemente e usando solo Python
Saverio Porcari - Stampe HTML e PDF, velocemente con Python
Chi sono
• [email protected] • Sviluppatore del framework Genropy • Sviluppatore di gestionali in Genropy • Nerd e giocatore incallito • Strimpellatore di ukulele • Papà
Saverio Porcari - Stampe HTML e PDF, velocemente con Python
Di cosa vi parlerò
• La problematica delle stampe • Come l’ abbiamo affrontata noi di Genropy • La libreria gnrhtml • Esempi pratici di utilizzo di gnrhtml • Integrazione con l'adapter sql Genropy • Strumenti più evoluti in Genropy • Utilizzo di gnrhtml da django
Saverio Porcari - Stampe HTML e PDF, velocemente con Python
Oh no! Le stampe...
• Noiose e laboriose • Codice su misura e scarsamente riutilizzabile • Difficile separazione tra grafica e dati • Problemi nel passaggio da schermo a carta
• Dati variabili in spazi fissi • Salti pagina, margini, dimensioni in millimetri
Saverio Porcari - Stampe HTML e PDF, velocemente con Python
Tipi di stampa
• Lettere, documenti testuali • Grafici, elementi geometrici vettoriali • Griglie con testata, righe e colonne • Moduli complessi e annidati
Printforce Australia Pty Ltd
ABN 43 009 354 643
PO Box 6386
EAST PERTH WA 6892
Ph: 08 9223 2400
Fax: 08 9223 2402 (Accounts)
Email: [email protected]
Account
Professionals Edge Hill
PO Box 635
EDGE HILL QLD 4870
Invoice Nr.
P16069533
Invoice date
29/06/16
Page
1/1
Doc type
Tax invoice
Account Number
003642
ABN
85053524931
Deliver to
120 Collins Avenue EDGE HILL QLD 4870
Job/Online Nr. Description Qty Total
P16N059669.004
250000402701
Total Magnet Calendar DL
BRIAN KOVACS- STYLE E FINANCIAL YEAR JUN-JUL 2017
Extras
Gloss Lam 1 Side 210x96
1,000 690.00
P16N059669.003
250000402501
Total Magnet Calendar DL
LEVEAUX GARTNER - STYLE E FINANCIAL YEAR JUN-JUL 2017
Extras
Gloss Lam 1 Side 210x96
3,000 1,570.00
P16N059669.002
250000402401
Total Magnet Calendar DL
RAY DILLON - STYLE E FINANCIAL YEAR JUN-JUL 2017
Extras
Gloss Lam 1 Side 210x96
2,000 1,130.00
P16N059669.001
250000401301
Total Magnet Calendar DL
BILLY GARTNER - STYLE E FINANCIAL YEAR JUN-JUL 2017
Extras
Gloss Lam 1 Side 210x96
2,000 1,130.00
TERMS OF TRADE, Net 30 days from date of Invoice. All
claims for non delivery or damaged goods must be made in writing
to us within 14 days of the date of this invoice.
Products net
4,109.09
Freight net
0.00
Total net
4,109.09
Total GST
410.91
Total
4,520.00
If you have already made payment, please accept our thanks and retain this invoice for your records Printed on: 29/06/16 3:26 PM
Group
IN
Client code
055082
Date in
29/2/16
Print Loc Div.
P
Year
16
Mode
N
Order
000116Job
001Press Check Production Nr
16000006Deliver by
Client infoCompany
TEST ACCOUNT - See Claire TurtonState
WA
Suburb
EAST PERTH
Post code
6892
Street
PO Box 6386
Phone
08 92232400
Fax
08 92232402
Contact
Dr Evil Badman - Accounts Receivable Offic ()
Email 2
Job alert
TEST ACCOUNT SEE CLAIRE TURTON [email protected]
0434 560646
Input infoEntered by
Claire Turton
Ext
3 205
Mobile
043 4560646
Assigned to
Claire Turton
Ext
3 205
Mobile
043 4560646
Office
Printforce Preston
Product infoProduct code
P.AA.SI.64.006Sides
1C.fr
4C.ba
0C.in
0Quantity
50Product title
6x4 Signboard VIC - Squareline SB35
Size
6x4
Product stock
Single Board
Inventory
No
Paperstock Sample encl.
No
Product details
Base Price
155.54
Extra Price
0.00
Freight
0.00
Total
155.54
Comment
0 - (date) date: 2016-02-22
1 - (unicode) method: Leave to the discretion of the installer
<_valuelabel='Intstallation Method'>
2 - (unicode) instruct: additional instructions
<_valuelabel='Additional Instructions'>
3 - (unicode) xstreet: x street field <_valuelabel='Nearest X
Street'>
Job extras Price Days
Code Destination Del Nr. DT Qty
055082.01TEST ACCOUNT - See Claire Turton: 84 Wellington Street EAST PERTH WA 6004
Phone:03 12345678D16000180 50
Run Number
Web Job Ref.
123456
Original Job
Source
2017-03-24T20:14:58.253365+01:00
Saverio Porcari - Stampe HTML e PDF, velocemente con Python
gnrhtml: le idee chiave
• Generare un html e da lì un pdf • Stesso codice doppio output • Cambiare la grafica toccando solo stylesheet css • Esiste wkhtmltopdf!
• Produrre un html “quotato” • Definendo elementi logici intuitivi e ricorrenti • Usando chiamate funzionali
Saverio Porcari - Stampe HTML e PDF, velocemente con Python
Un HTML quotato?
<div style="right:0mm;bottom:0mm;top:5mm;border-width:0.3mm;height:280mm;width:200mm;border:5;left:5mm;">
<div style="position:absolute;top:0mm;height:29.7mm;">
<div style="width:79.7mm;top:0mm;left:0mm;height:29.7mm;" class="gnrlayout l1_layout x_br">
<div style="" class="content_base">TOP left</div>
</div>
<div style="width:79.7mm;top:0mm;left:80mm;height:29.7mm;" class="gnrlayout l1_layout x_br">
<div style="" class="content_base">Top center</div>
</div>
<div style="width:40mm;top:0mm;left:160mm;height:29.7mm;" class="gnrlayout l1_layout x_b">
<div style="" class="content_base">TOP right</div>
</div>
</div>
</div>
Saverio Porcari - Stampe HTML e PDF, velocemente con Python
Un HTML quotato?
• Ogni elemento ha dimensioni e posizioni fisse • Espresse in millimetri • Lo sviluppatore fornisce solo alcune misure fisse • La logica di rendering calcola
• Tutte le dimensioni rimanenti per differenza • E le posizioni assolute di tutti gli elementi
Saverio Porcari - Stampe HTML e PDF, velocemente con Python
gnrhtml.GnrHtmlBuilder
from gnr.core.gnrhtml import GnrHtmlBuilder
def myprint(body):
pass
if __name__ == ‘__main__’:
builder = GnrHtmlBuilder()
builder.initializeSrc()
builder.styleForLayout()
myprint(builder.body)
builder.toHtml('myprint.html')
builder.toPdf(‘myprint.pdf’)
Saverio Porcari - Stampe HTML e PDF, velocemente con Python
Gli elementi a disposizione
• Non solo quelli corrispondenti a tutti tag HTML • div, style, img, span, link e tutti gli altri
• Ma soprattutto... layout, row, cell
Saverio Porcari - Stampe HTML e PDF, velocemente con Python
layout, row e cell
• layout è un contenitore rettangolare di row • Una row contiene elementi cell affiancati • Ciascuno dei quali può contenere a sua volta… • un layout annidato • E così via all'infinito ;-)
Saverio Porcari - Stampe HTML e PDF, velocemente con Python
layout, row, cell
Saverio Porcari - Stampe HTML e PDF, velocemente con Python
layout, row, cell
• Alla fine sono tutti div • Che quali posso applicare stili e classi CSS
Saverio Porcari - Stampe HTML e PDF, velocemente con Python
Layout
from gnr.core.gnrhtml import GnrHtmlBuilder
def myprint(body):
mylayout = body.layout(height=280, width=200,
top=5,left=5,
border_width=0.3,
border_color=‘red’,
border_style=‘solid’)
Saverio Porcari - Stampe HTML e PDF, velocemente con Python
Layout: i parametri
• width, height : misure• top, left: posizionamento rispetto al foglio • um: unità di misura • border_ (width, color, style): tratto dei bordi • lbl_ (class, height): relativi a tutte alle etichette • content_class : classe css per tutti i testi interni
Saverio Porcari - Stampe HTML e PDF, velocemente con Python
row
• “spaziatore” che serve a dividere il layout in righe • di altezza prefissata se specificato height • o altezza "elastica" ovvero calcolata • Può ridefinire alcuni parametri di layout
• lbl_class • lbl_height • content_class
Saverio Porcari - Stampe HTML e PDF, velocemente con Python
row
from gnr.core.gnrhtml import GnrHtmlBuilder
def myprint(body):
mylayout = body.layout(height=280, width=200,
top=5,left=5, border_width=0.3,
border_color=‘red’,border_style=‘solid’)
r_first= mylayout.row(height=30)
Saverio Porcari - Stampe HTML e PDF, velocemente con Python
cell
• L'unico elemento originale con contenuto • Può avere un’etichetta descrittiva del contenuto • Si può specificare larghezza fissa • Oppure calcolata per differenza
Saverio Porcari - Stampe HTML e PDF, velocemente con Python
cell
from gnr.core.gnrhtml import GnrHtmlBuilder
def myprint(body):
mylayout = body.layout(height=280, width=200,
top=5,left=5, border_width=0.3,
border_color=‘red’,border_style=‘solid’)
r_first= mylayout.row(height=30)
left_cell = r_first.cell(content=‘Left!’, width=23)
right_cell = r_first.cell(content=‘Right!’)
Saverio Porcari - Stampe HTML e PDF, velocemente con Python
Giochiamoci un po’
Saverio Porcari - Stampe HTML e PDF, velocemente con Python
Ancora più pigri…
• Nell’ambiente GenroPy ci sono API più potenti • la classe TableScriptToHtml • integrata con l’adapter sql genropy • integrata con la web application • risorsa definita a livello di table • Gestione dimensioni pagina, salti pagina,
intestazioni, margini
Saverio Porcari - Stampe HTML e PDF, velocemente con Python
TableScriptToHtml
from gnr.web.gnrbaseclasses import TableScriptToHtml
class Main(TableScriptToHtml):
templates='quotation'
maintable = 'pfrc.quotation'
rows_path = 'record.@rows'
doc_header_height = 33
doc_footer_height = 9
title_height=8
sub_headers_height=4
sub_row_height=5
space_between_rows=8
Saverio Porcari - Stampe HTML e PDF, velocemente con Python
E poi implementa questi
• mainLayout • gridLayout • prepareRow • docHeader, pageHeader, docFooter, pageFooter • defineCustomStyles • calc….Height
Saverio Porcari - Stampe HTML e PDF, velocemente con Python
Saverio Porcari - Stampe HTML e PDF, velocemente con Python
Vantaggi
• il metodo field • il metodo rowData • Il lanciatore di stampa integrato nella GUI • Integrazione con il sistema di carte intestate • Salti pagina automatici
Saverio Porcari - Stampe HTML e PDF, velocemente con Python
Un utilizzo da Django
• Creo un modulo che importa gnrhtml • Definisco i metodi di stampa • Li imposto come actions di una table
Saverio Porcari - Stampe HTML e PDF, velocemente con Python
Un utilizzo da Django
from gnr.core.gnrhtml import GnrHtmlBuilder
from django.http import FileResponse
def gnrhtmlbuilder():
builder = GnrHtmlBuilder(page_height=297, page_width=21)
builder.initializeSrc()
builder.styleForLayout()
return builder
Saverio Porcari - Stampe HTML e PDF, velocemente con Python
La action Django
def print_questions(modeladmin, request, queryset):
builder = gnrhtmlbuilder()
l = builder.body.layout(…)
headers = l.row(height=6, content_class='headers')
headers.cell('Pub.Date', width=28)
headers.cell('Question')
headers.cell('Status', width=28)
for x in queryset:
r = l.row(height=8)
r.cell(str(x.pub_date.date()), width=28)
r.cell(x.question_text)
approved = 'Approved' if x.approved else 'Not yet'
r.cell(approved, width=28)
path = '/Users/saverioporcari/esempi_stampa/questions_django.html'
builder.toHtml(path)
response= FileResponse(open(path, 'rb'))
response['Content-Disposition'] = 'attachment; filename=questions.html'
return response
Saverio Porcari - Stampe HTML e PDF, velocemente con Python
Domande?
Top Related