Table headings & page breaks not working in wkhtmltopdf - wkhtmltopdf

I'm using verison 0.12.5 of wkhtmltopdf on Debian Buster. I cannot get it to do any of the following behaviors that control table display and pagination with CSS declarations:
Print table headers at the top of each page
Control page orientation (setting to Landscape)
Inserting a page break
The production table I am working with is very tall (100s of rows) and I need the table header to print at the top of each page. I would also like to avoid breaking in the middle of a row.
I have successfully gotten it to add a page break at the end of a table and I can specify the page orientation on the command line, but I need to control all of these behaviors using CSS (stylesheet or inline is fine) on the actual document.
Sample code:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Test Page</title>
<style type="text/css">
thead { display: table-header-group }
tfoot { display: table-row-group }
tr { page-break-inside: avoid }
</style>
</head>
<body>
<h1>Title Here</h1>
<div>
<span id="filterModeLabel" class="FilterMode">Show all</span>
<table>
<thead>
<tr><th>FirstName</th><th>LastName</th></tr>
</thead>
<tbody>
<tr><td>John</td><td>Smith</td></tr>
<tr><td>John</td><td>Smith</td></tr>
<!-- Enough lines to push it onto two pages -->
<tr><td>John</td><td>Smith</td></tr>
<tr><td>John</td><td>Smith</td></tr>
</tbody>
</table>
</div>
</body>
</html>
I have also tried the following stylesheet variations with no luck:
#page {
size: letter;
size: landscape;
margin-top: .40in;
margin-left: .40in;
margin-right: .40in;
margin-bottom: .25in;
font-size: 10px;
#bottom-right { content: "Page " counter(page) " of " counter(pages)};
}
thead{
display: table-header-group
}
tfoot {
display: table-row-group
}
tr {
page-break-inside: avoid
}
table {
page-break-inside:auto;
word-wrap: break-word;
page-break-after: always;
border-collapse:collapse;
}
table tbody tr{
page-break-inside:avoid;
}
table.standard thead {
display:table-header-group;
font-size: 12px;
}
table tfoot { display: table-row-group; }
table tbody tr td
,table thead tr th {
font-size: 12px;
line-height: 10pt;
border: 1px solid black;
}
This is the call I am running on the command line:
wkhtmltopdf p1.html p1a.pdf
Here are screenshots of the result I get (top of pages 1 and 2):
Top of page 1
Split between pages 1 and 2

debian buster installs without patched QT
this resolved my issue.
wget https://github.com/wkhtmltopdf/packaging/releases/download/0.12.6-1/wkhtmltox_0.12.6-1.buster_amd64.deb
apt install ./wkhtmltox_0.12.6-1.buster_amd64.deb

Related

Convert html to PDF with wkhtmltopdf

I using wkhtmltopdf tool to convert html to pdf. On my linux computer it outputs everything right with css rules. But after installing the same tool on a Mac, the output does not look the same. The bold tag does not work. The margin to the top does not work and the font size over all looks smaller.
What can be the problem here? The html file is very simple and I think the wkhtmltopdf should behave the same way here independent of platform.
Here is a part of the html file:
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<style>
td {
border:solid windowtext 1.0pt;
background:white;
padding:0cm 5.4pt 0cm 5.4pt;
height:19.65pt;
}
td.table_header {
background:#D9D9D9;
}
.text_right {
text-align: right;
}
table {
width: 100%;
border-collapse:collapse;
border:none;
line-height: 80%;
}
html {
background:white;
font-family: "Arial Unicode MS", sans-serif;
}
.header {
font-size:18.0pt;
text-align:center;
}
.address1 {
text-align:right;
}
.text {
line-height: 160%;
}
.space {
line-height:80%;
}
</style>
</head>
<body style="margin:100px 100px;">

dompdf: top-margin after page break not working

I'm experimenting with Wordpress and (the recent version of) dompdf at the moment and ran into an annoying problem regarding the formating.
My Problem: The top-margin of the main content seems not to be considered on the second page generated, resulting in an overlapping with my logo. You can view the generated PDF under this link.
The relevant code from which the PDF is generated reads as follows (it is not perfect yet as i want to resolve the issue first):
function ppt_pdf_output() {
// post-ID of referring page needed
$post=get_post($_POST['postid']);
$output = '<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>'.$post->post_title.'</title>
<style>
body {
margin: 30px 0 0 0;
font-family:sans-serif;
text-align:left;
}
img {
margin: 15px 0;
}
#header,
#footer {
position: fixed;
left: 0;
right: 0;
color: #aaa;
font-size: 0.9em;
line-height:1.2em;
}
#header {
top: -30px;
/*border-bottom: 0.1pt solid #aaa;*/
}
#footer {
bottom: 0;
border-top: 0.1pt solid #aaa;
}
#header table,
#footer table {
width: 100%;
border-collapse: collapse;
border: none;
text-align: center;
color: #000;
font-size: 24px;
}
.entry-content {
margin: 100px auto 35px auto;
top: 0; left: 0; bottom: 0; right: 0;
background-color: #d1d977;
width:90%; height:auto;
}
.entry-title {
font-size: 18px;
text-align: center;
}
#header td,
#footer td {
padding: 0;
width: 50%;
}
#footer .page-number {
text-align: center;
}
.page-number:before {
content: "Seite " counter(page);
}
.gallery-item {
display:inline-block;
}
br[style] {
display:none;
}
.gallery + p {
clear:left;
}
</style>
</head>
<body><div id="header">
<table>
<tr>
<td>ANTRAG</td>
<td style="text-align: right;"><img src="path/to/logo.png" /></td>
</tr>
</table>
</div>
<div id="footer">
<div class="page-number"></div>
</div>';
$output .='
<!--<h1 class="entry-title">'. $post->post_title .'</h1>-->
<div class="entry-content">' .
apply_filters('the_content',$post->post_content) . '</div>';
$output .= '</body></html>';
return $output;
}
As you can see, the formatting on the first page is as it should be (or at least as I intended it to be), but after the page break the content area (for visualization reasons provided with a green background) just starts at the beginning of the page, regardless of which number I give the margin.
Has anybody an idea how to resolve this issue? I've been working on this for countless hours and just don't know what to do at this point.
Any help would be greatly appreciated.
Kind regards
Olli
UPDATE: Of course I found this solution only just. I will try this and see if I can get the issue resolved with this.
UPDATE2: Still no luck. I'm now stuck with the following code (the output can be found under the link provided earlier):
function ppt_pdf_output() {
// post-ID of referring page needed
$post=get_post($_POST['postid']);
$output = '<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>'.$post->post_title.'</title>
<style>
#page {
margin: 120px 50px 80px 50px;}
#header {
position: fixed;
top: -82px;
width: 100%;
height: 109px;
background: #aaa url("path/to/logo.png") no-repeat right;
}
#content {
width: 100%;
height: 85%;
background-color: #d1d977;
}
footer {
position: fixed;
bottom: -65px;
height: 30px;
background-color: #333399;
}
footer .page-number {
text-align: center;
}
.page-number:before {
content: "Seite " counter(page);
}
br[style] {
display:none;
}
</style>
</head>
<body><div id="header">
<h2>ANTRAG</h2>
</div>
<footer>
<div class="page-number"></div>
</footer>';
$output .='<h1>'. $post->post_title .'</h1>
<div id="content">' .
apply_filters('the_content',$post->post_content) . '</div>';
$output .= '</body></html>';
return $output;
}
It seems just so fragile. For example, as soon as I change the font-size of the h1 element, it gets overlapped by the logo. After the page break, it looks okay, but that just seems an coincidence - as soon as I change the font-size or the text, the text again gets overlapped. Will absolute positioning change anything or do you have any other tipps as how to resolve this anoying issue? Margins of any kind don't seem to work either.
You're on the right track. As you've seen, when an element is split across pages (as your content area is) some of the formatting information does not follow. This is by design.
The correct tact is to define the page margins so that they are large enough to hold your header/footer content and place the header/footer into that space. The content will then just fill the "body" of the document (i.e. the space inside the page margins). This is what you've attempted, but you haven't given enough space for the header. The header is positioned 82px inside the page margin but the height of the header is 109px. Because of this any content that has a small margin will still fall under the header.
Try this instead:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>"Kaffeefahrten" in Bornheim: hart durchgreifen, Senioren vor Betrügern schützen</title>
<style>
#page {
margin: 120px 50px 80px 50px;
}
#header {
position: fixed;
top: -115px;
width: 100%;
height: 109px;
background: #aaa url("path/to/logo.png") no-repeat right;
}
#content {
background-color: #d1d977;
}
footer {
position: fixed;
bottom: -65px;
height: 30px;
background-color: #333399;
}
footer .page-number {
text-align: center;
}
.page-number:before {
content: "Seite " counter(page);
}
br[style] {
display:none;
}
</style>
</head>
<body>
<div id="header">
<h2>ANTRAG</h2>
</div>
<footer>
<div class="page-number"></div>
</footer>
<h1>"Kaffeefahrten" in Bornheim: hart durchgreifen, Senioren vor Betrügern schützen</h1>
<div id="content">
...
</div>
</body>
</html>
Note that you also don't have to specify any height/width for the content element (unless you want to further constrict the space it uses).
With CSS3 you could go with your original styling and re-use the margins by applying the box-decoration-break property. However as of writing dompdf does not yet support this property.

IE8 display inline-block issue

For some reason, IE-8 doesn't display my menu inline. (see picture attached)
My code is:
#navigation #main-menu {
display: inline-block;
float: none;
margin: 0 auto;
padding: 0;
position: relative;
text-align: center;
line-height: 18px;
font-size: 12px;
list-style: none;
}
I have found the following post IE8 display inline-block not working. Tried adding the Doctype, as well as added this code:
<!-- [if lt IE 8]>
<style type="text/css">
#navigation #main-menu {
display: inline;
}
</style>
<![endif]-->
Still doesn't work, any advice? you can see a picture with the issue here: http://preciseos.com/PreciseOs/Untitled.jpg
Here is the html code:
<ul style="margin-top:20px;margin-right: 10%;" class="nav-collapse collapse" id="main-menu">
<li class="active">Home</li>
<li class="">About</li>
<li>Services</li>
<li>Work</li>
<li>Contact</li>
You can also see the issue at www.preciseos.com.
Thanks,
Oz
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
Why dont you add this?? which is the answer of your source. Give it try
IE8 will treat it as a block level element unless you use float
Note:
I posted doctype as comment but it was corrupted, so posting this as answer
Updated:
HTML
<ul id="main-menu">
<li class="actives">Home
</li>
<li class="actives">About
</li>
<li class="actives">Services
</li>
<li class="actives">Work
</li>
<li class="actives">Contact
</li>
</ul>
CSS
.actives {
display: inline;
padding:10px;
float: left;
}
a {
text-decoration:none;
}
Demo
The reason it breaks the layout is IE8 does'nt support HTML5 Elements such as nav.
Instead you can use <div> tag or try including javascript Workaround HTML5shiv to support IE
First, make sure you target the li element with your selector
#navigation #main-menu li
as well try using float instead of display: inline;
#navigation #main-menu li {
display: block;
float: left;
margin-right: 10px;
}
As Surjith SM said, the IE8 doesn't support HTML5 elements such as nav.
The problem was solved by adding the following code:
<!--[if lte IE 8]>
<script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
html5shi(m|v) creates doc elements for all the html5 elements so the styles from your CSS can kick in. Default behaviour for IE is to ignore unknown elements. For more info see header/footer/nav tags - what happens to these in IE7, IE8 and browsers than don't support HTML5?

Why my image doesn't respect its parent's (section) padding

I have a strange situation with an image and a section. You can download html, css and img1 from my github
The situation: I have a section tag which has padding:15px from all sides. In the section I have an img, floated left, then a p and a span with two buttons. The section has also a border and margin:35px
My problem: The image doesn't respect the section's bottom padding and goes through the sections bottom border.
I tried to put the img in a div inside the section, and also tried to give a height value for the section and 100% for the image's height but it didn't change anything
What is the best solution for this problem, so that the picture takes all the height of the section respecting the section's top, left and bottom paddings?
In the github, one step back, is a ppt-file TASKS.ppt. The third slide is what I try to achieve.
EDIT: Since code is requested, here it is:
HTML:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Music categories</title>
<link href="Ex03MusicCategories.css" rel="stylesheet" />
</head>
<body>
<header>
<h1>Music Categories</h1>
</header>
<section>
<img src="img1.png" />
<div>
<p>Even more websites all about website templates on <span>Just Web Templates</span> .</p>
<span>
<input type="button" value="Listen" />
<input type="button" value="Add" />
</span>
</div>
</section>
</body>
</html>
CSS:
body {
background-color: #EEE;
padding-top: 14px;
padding-left: 12px;
padding-right: 8px;
padding-bottom: 25px;
}
body header h1 {
font-weight: lighter;
font-size: 1.5em;
font-family: Arial;
letter-spacing: -2px;
}
section {
border-style: solid;
border-color: #989898;
border-width: 2px;
padding: 15px;
margin: 35px 0px;
}
section img {
float: left;
}
section img:after {
clear: both;
}
image img1.png
This is a classic, search for clearfix. One possible solution is
section {
overflow: hidden;
}
See JSFiddle
Update:
There's an article about CSS float and clear at CSS-Tricks - All About Floats.
Essentially, you need clear, when
an element should stay below a floated element
and some clearfix, when
the parent of a floated element collapses and you want the parent wrap around/include the floated children
You can also look at Stackoverflow css-float tag wiki (an alias of css-clear) or clearfix

jquery Auto search result is not updating the value to textbox after clicking

Below code display the list populated from database(DB code is not included). If I click on the search results, then the selected option will not show in textbox. Help please.
Below code works fine to show list of options from Database while typing characters. The issue is it will not show the selected drop down option into textbox.
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>jQuery Auto Complete</title>
<script src="jquery/jquery.js" type="text/javascript"></script>
<script type="text/javascript">
function lookup(inputString) {
if(inputString.length == 0) {
$('#suggestions').hide();
} else {
$.post("states.jsp", {queryString: ""+inputString+""}, function(data){
if(data.length >0) {
$('#suggestions').show();
$('#autoSuggestionsList').html(data);
}
});
}
}
function fill(thisValue) {
$('#inputString').val(thisValue);
setTimeout("$('#suggestions').hide();", 200);
}
</script>
<style type="text/css">
body {
font-family: Helvetica;
font-size: 13px;
color: #000;
}
h3 {
margin: 0px;
padding: 0px;
}
.suggestionsBox {
position: relative;
left: 260px;
margin: 0px 0px 0px 0px;
width: 200px;
background-color: #7845DD;
-moz-border-radius: 7px;
-webkit-border-radius: 7px;
border: 2px solid #000;
color: #fff;
}
.suggestionList {
margin: 0px;
padding: 0px;
}
.suggestionList li {
margin: 0px 0px 3px 0px;
padding: 3px;
cursor: pointer;
}
.suggestionList li:hover {
background-color: #DD45CD;
}
</style>
</head>
<body>
<div>
<form>
<div> <h3><font color="red">Indian States</states></font></h3>
<br /> Enter India State Name to see autocomplete
<input type="text" size="30" value="" id="inputString"
onkeyup="lookup(this.value);" onblur="fill();" />
</div>
<div class="suggestionsBox" id="suggestions" style="display: none;">
<div class="suggestionList" id="autoSuggestionsList">
</div>
</div>
</form>
</div>
</body>
</html>
<%
String name=request.getParameter("queryString");
try {
Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver").newInstance();
Connection con = DriverManager.getConnection("jdbc:sqlserver://localhost", "user", "password");
Statement st=con.createStatement();
//Add the data into the database
String sql = "SELECT EMP_EMPLOYEE_ID, EMP_FNAME, EMP_LNAME FROM UAP_EMPLOYEE where EMP_FNAME LIKE '%"+name+"%' OR EMP_LNAME LIKE '%"+name+"%';";
Statement stm = con.createStatement();
stm.executeQuery(sql);
ResultSet rs= stm.getResultSet();
while (rs.next ()){
out.println("<li onclick='fill("+rs.getString("EMP_FNAME")+");>"+rs.getString("EMP_FNAME")+" </i>");
}}catch(Exception e){
out.println("Exception is ;"+e);
}
%>
In this line
$('#autoSuggestionsList').html(data);
you are setting some html that I assume consists of a list of div tags with your auto-suggestions. If you want the user to be able to click on the list, you need to have a click handler attached to the suggestions that loads the value. Like
$(document).ready(function() {
$("#autoSuggestionsList div").on("click", function() {
//put your click actions here.. load the textbox, hide the list
});
}
The on command is live, meaning it will automatically be bound to elements that are loaded dynamically.
EDIT
Since you're using li instead of div, change the above to
$(document).ready(function() {
$("#autoSuggestionsList li").on("click", function() {
fill($(this).text());
});
}
EDIT 2
In the new code you added, this line is incorrect
out.println("<li onclick='fill("+rs.getString("EMP_FNAME")+");>"+rs.getString("EMP_FNAME")+" </i>");
It will produce incorrect HTML/Javascript that looks like this:
<li onclick='fill(some text);>some text</i>
Your code should look like this:
out.println("<li onclick='fill(\""+rs.getString("EMP_FNAME")+"\");'>"+rs.getString("EMP_FNAME")+" </li>");
It will produce the following correct HTML/JavascriptL
<li onclick='fill("some text");'>some text</li>

Resources