[enhancement] PDF: Footer option in Letter Head and show page number at the bottom
This commit is contained in:
parent
78bd12d8b0
commit
8b0b93a3a8
7 changed files with 121 additions and 58 deletions
|
|
@ -25,6 +25,7 @@
|
|||
"oldfieldtype": "Data",
|
||||
"permlevel": 0,
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 1,
|
||||
|
|
@ -50,6 +51,7 @@
|
|||
"oldfieldtype": "Check",
|
||||
"permlevel": 0,
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
|
|
@ -76,6 +78,7 @@
|
|||
"oldfieldtype": "Check",
|
||||
"permlevel": 0,
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
|
|
@ -102,6 +105,31 @@
|
|||
"oldfieldtype": "Text Editor",
|
||||
"permlevel": 0,
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"fieldname": "footer",
|
||||
"fieldtype": "Text Editor",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"in_filter": 0,
|
||||
"in_list_view": 0,
|
||||
"label": "Footer",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
|
|
@ -120,7 +148,7 @@
|
|||
"issingle": 0,
|
||||
"istable": 0,
|
||||
"max_attachments": 3,
|
||||
"modified": "2015-11-16 06:29:49.706229",
|
||||
"modified": "2016-01-28 02:03:23.139628",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Print",
|
||||
"name": "Letter Head",
|
||||
|
|
@ -168,5 +196,6 @@
|
|||
}
|
||||
],
|
||||
"read_only": 0,
|
||||
"read_only_onload": 0
|
||||
"read_only_onload": 0,
|
||||
"sort_order": "ASC"
|
||||
}
|
||||
|
|
@ -106,13 +106,15 @@ def get_html(doc, name=None, print_format=None, meta=None,
|
|||
if template == "standard":
|
||||
template = jenv.get_template(standard_format)
|
||||
|
||||
letter_head = get_letter_head(doc, no_letterhead)
|
||||
args = {
|
||||
"doc": doc,
|
||||
"meta": frappe.get_meta(doc.doctype),
|
||||
"layout": make_layout(doc, meta, format_data),
|
||||
"no_letterhead": no_letterhead,
|
||||
"trigger_print": cint(trigger_print),
|
||||
"letter_head": get_letter_head(doc, no_letterhead)
|
||||
"letter_head": letter_head.content,
|
||||
"footer": letter_head.footer
|
||||
}
|
||||
|
||||
html = template.render(args, filters={"len": len})
|
||||
|
|
@ -161,9 +163,9 @@ def get_letter_head(doc, no_letterhead):
|
|||
if no_letterhead:
|
||||
return ""
|
||||
if doc.get("letter_head"):
|
||||
return frappe.db.get_value("Letter Head", doc.letter_head, "content")
|
||||
return frappe.db.get_value("Letter Head", doc.letter_head, ["content", "footer"], as_dict=True)
|
||||
else:
|
||||
return frappe.db.get_value("Letter Head", {"is_default": 1}, "content") or ""
|
||||
return frappe.db.get_value("Letter Head", {"is_default": 1}, ["content", "footer"], as_dict=True) or {}
|
||||
|
||||
def get_print_format(doctype, print_format):
|
||||
if print_format.disabled:
|
||||
|
|
|
|||
|
|
@ -1,49 +1,65 @@
|
|||
<!DOCTYPE html>
|
||||
<head>
|
||||
<style>
|
||||
body {
|
||||
margin: 0 !important;
|
||||
border: 0 !important;
|
||||
padding: 15mm 0 5mm !important;
|
||||
}
|
||||
<html>
|
||||
<head>
|
||||
{% if html_id=="footer-html" %}
|
||||
{# a workaround for auto footer height in wkhtmltopdf #}
|
||||
<link type="text/css" rel="stylesheet" media="print"
|
||||
href="/assets/frappe/css/bootstrap.css">
|
||||
<link type="text/css" rel="stylesheet" media="print"
|
||||
href="/assets/frappe/css/font-awesome.css">
|
||||
|
||||
.letter-head {
|
||||
margin-top: -15mm !important;
|
||||
}
|
||||
</style>
|
||||
{% else %}
|
||||
|
||||
{{ head.prettify() }}
|
||||
|
||||
<!-- from: http://wkhtmltopdf.org/usage/wkhtmltopdf.txt -->
|
||||
<script>
|
||||
function subst() {
|
||||
var vars = {};
|
||||
var x = window.location.search.substring(1).split('&');
|
||||
for (var i in x) {
|
||||
var z = x[i].split('=',2);
|
||||
vars[z[0]] = unescape(z[1]);
|
||||
}
|
||||
var x = ['frompage','topage','page','webpage','section','subsection','subsubsection'];
|
||||
for (var i in x) {
|
||||
var y = document.getElementsByClassName(x[i]);
|
||||
for (var j=0; j<y.length; ++j) {
|
||||
y[j].textContent = vars[x[i]];
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
{% for tag in styles -%}
|
||||
{{ tag.prettify() }}
|
||||
{%- endfor %}
|
||||
|
||||
</head>
|
||||
<body onload="subst()">
|
||||
<div class="print-format">
|
||||
<div class="wrapper">
|
||||
{% for tag in content -%}
|
||||
{% for tag in head -%}
|
||||
{{ tag | string }}
|
||||
{%- endfor %}
|
||||
|
||||
{% endif %}
|
||||
|
||||
<style>
|
||||
body {
|
||||
margin: 0 !important;
|
||||
border: 0 !important;
|
||||
padding: 15mm 0 5mm !important;
|
||||
}
|
||||
|
||||
.letter-head,
|
||||
.letter-head-footer {
|
||||
margin-top: -15mm !important;
|
||||
}
|
||||
</style>
|
||||
|
||||
<!-- from: http://wkhtmltopdf.org/usage/wkhtmltopdf.txt -->
|
||||
<script>
|
||||
function subst() {
|
||||
var vars = {};
|
||||
var x = window.location.search.substring(1).split('&');
|
||||
for (var i in x) {
|
||||
var z = x[i].split('=',2);
|
||||
vars[z[0]] = unescape(z[1]);
|
||||
}
|
||||
var x = ['frompage','topage','page','webpage','section','subsection','subsubsection'];
|
||||
for (var i in x) {
|
||||
var y = document.getElementsByClassName(x[i]);
|
||||
for (var j=0; j<y.length; ++j) {
|
||||
y[j].textContent = vars[x[i]];
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
{% for tag in styles -%}
|
||||
{{ tag | string }}
|
||||
{%- endfor %}
|
||||
|
||||
</head>
|
||||
<body onload="subst()">
|
||||
<div class="print-format">
|
||||
<div class="wrapper">
|
||||
{% for tag in content -%}
|
||||
{{ tag | string }}
|
||||
{%- endfor %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
|||
|
|
@ -4,7 +4,17 @@
|
|||
{% for page in layout %}
|
||||
<div class="page-break">
|
||||
<div id="header-html" class="hidden-pdf">
|
||||
{{ add_header(loop.index, layout|len, doc, letter_head, no_letterhead) }}
|
||||
{{ add_header(loop.index, layout|len, doc, letter_head, no_letterhead, footer) }}
|
||||
</div>
|
||||
<div id="footer-html" class="visible-pdf">
|
||||
{% if not no_letterhead and footer %}
|
||||
<div class="letter-head-footer">
|
||||
{{ footer }}
|
||||
</div>
|
||||
{% endif %}
|
||||
<p class="page-number visible-pdf">
|
||||
{{ _("Page {0} of {1}").format('<span class="page"></span>', '<span class="topage"></span>') }}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{% for section in page %}
|
||||
|
|
|
|||
|
|
@ -110,7 +110,7 @@ data-fieldname="{{ df.fieldname }}" data-fieldtype="{{ df.fieldtype }}"
|
|||
{%- endif -%}
|
||||
{% endmacro %}
|
||||
|
||||
{%- macro add_header(page_num, max_pages, doc, letter_head, no_letterhead) -%}
|
||||
{%- macro add_header(page_num, max_pages, doc, letter_head, no_letterhead, footer) -%}
|
||||
{% if letter_head and not no_letterhead %}
|
||||
<div class="letter-head">{{ letter_head }}</div>
|
||||
{% endif %}
|
||||
|
|
@ -125,9 +125,6 @@ data-fieldname="{{ df.fieldname }}" data-fieldtype="{{ df.fieldtype }}"
|
|||
</h2>
|
||||
</div>
|
||||
{% endif %}
|
||||
<p class="text-right page-number visible-pdf">
|
||||
{{ _("Page #{0} of {1}").format('<span class="page"></span>', '<span class="topage"></span>') }}
|
||||
</p>
|
||||
{%- if doc.meta.is_submittable and doc.docstatus==0-%}
|
||||
<div class="text-center" document-status="draft">
|
||||
<h4 style="margin: 0px;">{{ _("DRAFT") }}</h4>
|
||||
|
|
|
|||
|
|
@ -105,3 +105,8 @@ table td div {
|
|||
[document-status] {
|
||||
margin-bottom: 5mm;
|
||||
}
|
||||
|
||||
.page-number {
|
||||
text-align: center;
|
||||
font-size: 85%;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -73,8 +73,6 @@ def read_options_from_html(html):
|
|||
options = {}
|
||||
soup = BeautifulSoup(html, "html5lib")
|
||||
|
||||
options.update(prepare_header_footer(soup))
|
||||
|
||||
# extract pdfkit options from html
|
||||
for html_id in ("margin-top", "margin-bottom", "margin-left", "margin-right", "page-size"):
|
||||
try:
|
||||
|
|
@ -84,6 +82,8 @@ def read_options_from_html(html):
|
|||
except:
|
||||
pass
|
||||
|
||||
options.update(prepare_header_footer(soup))
|
||||
|
||||
toggle_visible_pdf(soup)
|
||||
|
||||
return soup.prettify(), options
|
||||
|
|
@ -91,19 +91,23 @@ def read_options_from_html(html):
|
|||
def prepare_header_footer(soup):
|
||||
options = {}
|
||||
|
||||
head = soup.find("head")
|
||||
head = soup.find("head").contents
|
||||
styles = soup.find_all("style")
|
||||
|
||||
# extract header and footer
|
||||
for html_id in ("header-html", "footer-html"):
|
||||
content = soup.find(id=html_id)
|
||||
if content:
|
||||
content.extract()
|
||||
# there could be multiple instances of header-html/footer-html
|
||||
for tag in soup.find_all(id=html_id):
|
||||
tag.extract()
|
||||
|
||||
toggle_visible_pdf(content)
|
||||
html = frappe.render_template("templates/print_formats/pdf_header_footer.html", {
|
||||
"head": head,
|
||||
"styles": styles,
|
||||
"content": content
|
||||
"content": content,
|
||||
"html_id": html_id
|
||||
})
|
||||
|
||||
# create temp file
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue