Как сделать нумерацию страниц в htmls верхнего / нижнего колонтитула с wkhtmltopdf?
Я разрабатываю электронную систему выставления счетов, и одной из наших функций является создание PDF-файлов счетов-фактур и их рассылка. У нас есть несколько шаблонов для счетов-фактур, и мы создадим их позже, поэтому мы решили использовать HTML-шаблоны, создать HTML-документ, а затем преобразовать его в PDF. Но мы столкнулись с проблемой с wkhtmltopdf, что, насколько я знаю (я был Googleing в течение нескольких дней, чтобы найти решение), мы не можем просто использовать HTML в качестве верхнего / нижнего колонтитула и показывать номера страниц в их.
в отчете об ошибке (или таком) (http://code.google.com/p/wkhtmltopdf/issues/detail?id=140) я читал, что с JavaScript это достижимо в этой комбинации. Но никакой другой информации о том, как это сделать, можно найти на этой странице, или в другом месте.
Это, конечно, не так важно, чтобы заставить использовать JavaScript, если с wkhtmltopdf некоторые CSS магия может работать, это было бы так же здорово, как и любые другие хакерские решения.
спасибо!
6 ответов
показывать номер страницы и общее количество страниц, вы можете использовать этот фрагмент кода JavaScript в футере или шапке код:
var pdfInfo = {};
var x = document.location.search.substring(1).split('&');
for (var i in x) { var z = x[i].split('=',2); pdfInfo[z[0]] = unescape(z[1]); }
function getPdfInfo() {
var page = pdfInfo.page || 1;
var pageCount = pdfInfo.topage || 1;
document.getElementById('pdfkit_page_current').textContent = page;
document.getElementById('pdfkit_page_count').textContent = pageCount;
}
и вызов getPdfInfo со страницей onload
конечно pdfkit_page_current и pdfkit_page_count будут два элемента, которые показывают номера.
фрагмент взят из здесь
на самом деле это гораздо проще, чем с фрагментом кода. В командной строке можно добавить следующий аргумент:--footer-center [page]/[topage]
.
Как упоминал Ричард, дальнейшие переменные находятся в нижнем колонтитуле и заголовках раздела документация.
среди нескольких других параметров, номер страницы и общий номер страницы передаются в нижний колонтитул HTML в качестве параметров запроса, как указано в официальных документах:
... аргументы [номер страницы]отправляются в HTML-документы верхнего/нижнего колонтитула в GET-режиме.
источник:http://wkhtmltopdf.org/usage/wkhtmltopdf.txt
поэтому решением для извлечения этих параметров, используя немного JS и рендеринга них в шаблон HTML. Вот полный рабочий пример нижнего колонтитула HTML:
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<script>
function substitutePdfVariables() {
function getParameterByName(name) {
var match = RegExp('[?&]' + name + '=([^&]*)').exec(window.location.search);
return match && decodeURIComponent(match[1].replace(/\+/g, ' '));
}
function substitute(name) {
var value = getParameterByName(name);
var elements = document.getElementsByClassName(name);
for (var i = 0; elements && i < elements.length; i++) {
elements[i].textContent = value;
}
}
['frompage', 'topage', 'page', 'webpage', 'section', 'subsection', 'subsubsection']
.forEach(function(param) {
substitute(param);
});
}
</script>
</head>
<body onload="substitutePdfVariables()">
<p>Page <span class="page"></span> of <span class="topage"></span></p>
</body>
</html>
substitutePdfVariables()
вызывается в теле onload
. Затем мы получаем каждую поддерживаемую переменную из строки запроса и заменяем содержимое во всех элементах соответствующим именем класса.
из документации wkhtmltopdf (http://madalgo.au.dk / ~jakobt/wkhtmltoxdoc/wkhtmltopdf-0.9.9-doc.html) под заголовком "колонтитулы и заголовки" есть фрагмент кода для достижения нумерации страниц:
<html><head><script>
function subst() {
var vars={};
var x=document.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></head><body style="border:0; margin: 0;" onload="subst()">
<table style="border-bottom: 1px solid black; width: 100%">
<tr>
<td class="section"></td>
<td style="text-align:right">
Page <span class="page"></span> of <span class="topage"></span>
</td>
</tr>
</table>
</body></html>
есть также более доступные переменные, которые могут быть заменены, кроме номеров страниц для использования в верхних/нижних колонтитулах.
способ, которым это должно быть сделано (то есть, если wkhtmltopdf поддерживает его), будет использовать правильный CSS-носитель:http://www.w3.org/TR/css3-gcpm/
Я смотрю, что это займет сейчас.
безопасный подход, даже если вы используете XHTML (например, с thymeleaf). Единственное отличие от другого решения - использование тегов//.
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8"/>
<script>
/*<![CDATA[*/
function subst() {
var vars = {};
var query_strings_from_url = document.location.search.substring(1).split('&');
for (var query_string in query_strings_from_url) {
if (query_strings_from_url.hasOwnProperty(query_string)) {
var temp_var = query_strings_from_url[query_string].split('=', 2);
vars[temp_var[0]] = decodeURI(temp_var[1]);
}
}
var css_selector_classes = ['page', 'topage'];
for (var css_class in css_selector_classes) {
if (css_selector_classes.hasOwnProperty(css_class)) {
var element = document.getElementsByClassName(css_selector_classes[css_class]);
for (var j = 0; j < element.length; ++j) {
element[j].textContent = vars[css_selector_classes[css_class]];
}
}
}
}
/*]]>*/
</script>
</head>
<body onload="subst()">
<div class="page-counter">Page <span class="page"></span> of <span class="topage"></span></div>
</body>
последнее замечание: при использовании thymeleaf замените <script>
С <script th:inline="javascript">
.