kittiu
January 23, 2023, 4:47pm
1
Hello, at first I was looking sample print format for the ways to make preprinted forms with big header and footer. But after some research I think I almost reach what I need. Which is for something like this,
The main technique is from here, The Ultimate Print HTML Template with Header & Footer | by Idan Cohen | Medium
Note: If anyone got any other example or tips, please let me know. Thanks!
3 Likes
kittiu
January 23, 2023, 4:50pm
2
I will just put my work for Sales Invoice here, in case anyone find it useful.
HTML
<!--Reference: https://medium.com/@Idan_Co/the-ultimate-print-html-template-with-header-footer-568f415f6d2a-->
{% set sales_persons = [] %}
{% for l in doc.sales_team %}
{% set sales_persons = sales_persons.append(l.sales_person) %}
{% endfor %}
<div class="page-header">
<!--Left Header -->
<div id="customer_name" >
{{ doc.customer_name }}
</div>
<div id="address_display" >
{{ doc.address_display | replace("Thailand", "") | replace("<br>", " ") }}
</div>
<div id="tax_id" >
{{ doc.tax_id }}
</div>
<!--Right Header -->
<div id="doc_name" >
{{ doc.name }}
</div>
<div id="doc_date" >
{{ frappe.format(doc.posting_date, 'Date') }}
</div>
<div id="sales_person" >
{{ sales_persons|join(', ') }}
</div>
<div id="payment_term" >
{{ doc.payment_terms_template }}
</div>
<div id="po_no" >
{{ doc.po_no }}
</div>
<div id="po_date" >
{{ frappe.format(doc.po_date, 'Date') }}
</div>
</div>
<div class="page-footer">
<div id="terms">
{{ doc.terms }}
</div>
<div id="amount_in_text">
{{ '(' ~ amount_in_bahttext(doc.grand_total) ~ ')' }}
</div>
<div id="printed_by">
{{ frappe.get_fullname(doc.owner) }}
</div>
<div id="total">
{{ frappe.format(doc.total, 'Currency') }}
</div>
<div id="discount_amount">
{{ frappe.format(doc.discount_amount, 'Currency')}}
</div>
<div id="net_total">
{{ frappe.format(doc.net_total, 'Currency')}}
</div>
<div id="total_taxes_and_charges">
{{ frappe.format(doc.total_taxes_and_charges, 'Currency') }}
</div>
<div id="grand_total">
{{ frappe.format(doc.grand_total, 'Currency') }}
</div>
</div>
<table>
<thead>
<tr>
<td id="col1"><div class="page-header-space"></div></td>
<td id="col2"><div class="page-header-space"></div></td>
<td id="col3"><div class="page-header-space"></div></td>
<td id="col4"><div class="page-header-space"></div></td>
<td id="col5"><div class="page-header-space"></div></td>
</tr>
</thead>
<tbody>
{% for l in doc.items %}
<tr>
<td id="col1">{{ l.qty ~ ' ' ~ l.uom }}</td>
<td id="col2">{{ l.description }}</td>
<td id="col3">{{ frappe.format(l.rate, {'fieldtype': 'Currency'}) }}</td>
<td id="col4">{{ frappe.format(l.discount_percentage, {'fieldtype': 'Percent'}) if l.discount_percentage else '' }}</td>
<td id="col5">{{ frappe.format(l.amount, {'fieldtype': 'Currency'}) }}</td>
</tr>
{% endfor %}
</tbody>
<tfoot>
<tr>
<td><div class="page-footer-space"></div></td>
<td><div class="page-footer-space"></div></td>
<td><div class="page-footer-space"></div></td>
<td><div class="page-footer-space"></div></td>
<td><div class="page-footer-space"></div></td>
</tr>
</tfoot>
</table>
CSS
/* Styles go here */
.print-format {
padding: 0px;
margin-right: 0mm;
margin-left: 0mm;
margin-top: 0mm;
margin-bottom: 0mm;
font-size: 12px;
}
table tr td { font-size: 12px; }
.page-header, .page-header-space {
height: 230px; /* Max is 230px */
margin: 0;
}
.page-footer, .page-footer-space {
height: 230px; /* Max is 230px */
margin: 0;
}
.page-footer {
position: fixed;
bottom: 0;
width: 100%;
border-top: 1px solid; /* for demo */
}
.page-header {
position: fixed;
top: 0mm;
width: 100%;
border-bottom: 1px solid; /* for demo */
}
.page {
page-break-after: always;
}
@page {
/* this affects the margin in the printer settings */
margin: 20mm 0mm 30mm 0mm
}
@media print {
thead {display: table-header-group;}
tfoot {display: table-footer-group;}
}
/* Start of positioning*/
#customer_name {
position: absolute;
top: 100px;
left: 40px;
}
#address_display {
position: absolute;
top: 100px;
left: 55px;
width: 450px;
white-space: pre-line;
}
#tax_id {
position: absolute;
top: 170px;
left: 30px;
}
#doc_name {
position: absolute;
top: 100px;
left: 520px;
}
#doc_date {
position: absolute;
top: 100px;
left: 685px;
}
#sales_person {
position: absolute;
top: 130px;
left: 520px;
}
#payment_term {
position: absolute;
top: 130px;
left: 710px;
}
#po_no {
position: absolute;
top: 170px;
left: 550px;
}
#po_date {
position: absolute;
top: 170px;
left: 700px;
}
#col1 {
width: 158px;
text-align: right;
vertical-align: bottom;
border: solid 1px;
}
#col2 {
width: 580px;
text-align: left;
vertical-align: top;
border: solid 1px;
}
#col3 {
width: 105px;
text-align: right;
vertical-align: top;
border: solid 1px;
}
#col4 {
width: 52px;
text-align: right;
vertical-align: top;
border: solid 1px;
}
#col5 {
width: 158px;
text-align: right;
vertical-align: top;
border: solid 1px;
}
#terms {
position: absolute;
top: 60px;
left: 30px;
width: 400px;
height: 60px;
overflow:hidden;
border: 1px solid;
}
#amount_in_text {
position: absolute;
top: 140px;
left: 30px;
border: 1px solid;
}
#printed_by {
position: absolute;
top: 180px;
left: 560px;
border: 1px solid;
}
/*Total*/
#total {
position: absolute;
top: 0px;
right: 5px;
}
#discount_amount {
position: absolute;
top: 30px;
right: 5px;
}
#net_total {
position: absolute;
top: 60px;
right: 5px;
}
#total_taxes_and_charges {
position: absolute;
top: 90px;
right: 5px;
}
#grand_total {
position: absolute;
top: 120px;
right: 5px;
}
5 Likes
kittiu
January 24, 2023, 2:20am
3
Also I found that, with big header and footer exceed 230px, Google Chrom overflow the table like there is no theader / tfooter. But in Firefox, it still work fine.
I am not sure how to fix this in Chrome or is this its bug.
1 Like
@kittiu Thank you very much sharing this code. Really appreciatable. I am searching solution for this since a month… This works as It required in excellent way. I have only one problem, like heading Qty,Description,Rate and amount also must show in each page… But presently it is not showing… Can you pls help…
@kittiu found it. It is in the page-header… But now I am having another problem. In PDF the page header is not showing in second page. In html it is showing… pls help me to solve this.