Wkhtmltopdf Characters in single line partially cut between pages - html

I am working in a project using ruby on rails(3.1). My requirement is to produce pdf from the html content. So I use pdfkit gem.
In some pages, characters in single line partially cut between pages. When I convert html convert to pdf using pdfkit gem
version of wkhtmltopdf: wkhtmltopdf -- 0.11.0 rc1
operating system: Linux CentOS 5.5
In the image below showing character partially cut between pages.
Please suggest a solution.
Example 1
Example 2

I did have this problem with a table:
Then I added this to my CSS:
table, img, blockquote {page-break-inside: avoid;}
This fixed the problem:

I just ran across this and found something that resolved the issue for me. In my particular case, there were divs with display: inline-block; margin-bottom: -20px;. Once I changed them to block and reset the margin-bottom, the line splitting disappeared. YMMV.

According to some documentation I found (see Page Breaking), this is a known issue and suggests using CSS page breaks to insert page breaks (assuming you are using patched version of QT):
The current page breaking algorithm of WebKit leaves much to be
desired. Basically webkit will render everything into one long page,
and then cut it up into pages. This means that if you have two columns
of text where one is vertically shifted by half a line. Then webkit
will cut a line into to pieces display the top half on one page. And
the bottom half on another page. It will also break image in two and
so on. If you are using the patched version of QT you can use the CSS
page-break-inside property to remedy this somewhat. There is no easy
solution to this problem, until this is solved try organising your
HTML documents such that it contains many lines on which pages can be
cut cleanly.
See also: http://code.google.com/p/wkhtmltopdf/issues/detail?id=9,
http://code.google.com/p/wkhtmltopdf/issues/detail?id=33 and
http://code.google.com/p/wkhtmltopdf/issues/detail?id=57.

In my case, the issue was resolved by commenting out the following css:
html, body {
overflow-x: hidden;
}
In general, check if any tags have overflow set as hidden and remove it or set it to visible.
Btw, I am using wkhtmltopdf version 0.12.2.1 on Windows 8.

https://github.com/ArthurHub/HTML-Renderer/issues/38
**var head = "<head><style type=\"text/css\"> td, h1, h2, h3, p, b, div, i, span, label, ul, li, tr, table { page-break-inside: avoid; } </style></head>";**
PdfDocument pdf = PdfGenerator.GeneratePdf("html>" + head + "<body>" + m42Notes + "</body></html>", configurationOptions);

I scoured the internet for a couple of weeks, trying to overcome this issue. None of the solutions I found worked for me, but something else did.
I had a two column layout where the text was getting cut off mid-text. In the broken state, my basic structure looked like this:
#media print {
* {
page-break-inside: avoid;
page-break-after: avoid;
page-break-before: avoid;
}
}
.col-9{
display: inline-block;
width: 70%;
}
.col-9{
display: inline-block;
width: 25%;
}
<div class="col-9">
[a lot of text here, that would spill over multiple pages]
</div>
<div class="col-3">
[a short sidebar here]
</div>
I fixed it by changing it to:
#media print {
* {
page-break-inside: avoid;
page-break-after: avoid;
page-break-before: avoid;
}
}
.col-9{
display: block;
float: left;
width: 70%;
}
.col-9{
display: block;
float: left;
width: 25%;
}
.clear{
clear: both;
}
<div class="col-9">
[a lot of text here, that no longer split mid-line.]
</div>
<div class="col-3">
[a short sidebar here]
</div>
<div class="clear"></div>
For some reason, the tool could not handle the display: inline-block setup. It works with floats. I'm running version 0.12.4.

This is old but hopefully will help someone - I was having the issues too, tried everything - even resorting back to old versions mentioned (12.1) but to no avail. I kept tweaking css to play around, trying to throw in page-break avoids everywhere, not having much progress. Then I tweaked css that was on the root div of my html, and it fixed it. I made so many tweaks trying to get it to work so I can't be 100% sure, but I believe the issue was it set to 'display:table' with margin: 0 auto and a specific width on the main outer div. It started working and not cutting off either images or tables mid-row once I removed that. Then the page-break-inside: avoid was working after that as expected.
I believe ultimately the code is trying to guess as best as it can exactly how many pixels high each page is, and where exactly (down to the pixel) is your content. We have to make it easy for the library to detect this by removing as much odd css in there as possible, so it's as simple as possible to calculate down to the pixel where the content lies. That's my guess.

I solved problem adding margin-top and margin-bottom, like this:
$this->get('knp_snappy.pdf')->generateFromHtml($html, $pdfFilepath, [
'default-header' => false,
'header-line' => false,
'footer-line' => false,
'disable-javascript' => true,
'margin-top' => '3mm',
'margin-bottom' => '3mm',
'margin-right' => '5mm',
'margin-left' => '5mm',
'orientation' => 'Landscape',
], true);

The cut text problem is a known webkit problem and it seems developers found a solution inside wkhtmltopdf. Updating to 0.12.1 will fix the cut-text problem (if you don't want to waste time with compilations, you can just take the binary file from here: https://github.com/h4cc/wkhtmltopdf-amd64 ).

Have been putting up with this for months and finally found a fix for my situation. I'm using the github css stylesheet in the html file I'm converting, and code blocks that span multiple pages get the text cut if. Nothing is missing, it's just cut in half.
Bottom of a page:
Start of next page:
So in the github stylesheet overflow is set to auto for <pre> tags.
.markdown-body .highlight pre,
.markdown-body pre {
padding: 16px;
overflow: auto;
...
Switching the overflow property to hidden solved it for me!
.markdown-body .highlight pre,
.markdown-body pre {
padding: 16px;
overflow: hidden;
Think I tried all the other answers on this page, but this is solved for me. Hope it helps someone else out :)

I was able to find a workaround to this issue by installing wkhtmltox_0.12.6-1.bionic_amd64.deb (for Ubuntu) from https://github.com/wkhtmltopdf/packaging/releases/0.12.6-1
After updating this wkhtmltox package, the tables and text will not cut off at the end of the page anymore. This fix introduced a different issue for me, now the generated pdf has no styling. For example font-family, font-size or even text alignment are all gone, and are using some default setting.

Related

How can I remove the gaps between these horizontal and centered navigation tabs?

My code is available here:
https://drive.google.com/open?id=0B1sXI26Zssw2YUVueDdyUHlrVXM
The problem that I'm facing is that there's some space showing up between my navigation tabs, and I didn't have this problem before I used the 'display: inline' function to center my navigation. What can be done? I've tried using "negative pixel margins" but they don't seem to work at all (They did work in another sample navigation I was experimenting with).
Here's a screenshot of the output of the code.
Ok so I downloaded the files and tested it on my server, what I found was rather strange, but the space was only there when the code was on different lines, I ended up fixing it by putting all the <li> elements on one line. You can see the code here: https://gist.github.com/HoogleyB/87de68e1a74480d73150770885e25224
Try to set margin = 0 . If you are running your code on chrome, it adds additional padding and margin of about 8px on its own. So try to fix that.
Have you tried:
ul li{ margin-left:-6px; }
Hope it will helps you.
Just so you know, this bug is because you are using display: inline-block;
With inline-block, if your html has breakline between elements you will see a space.
To remove it there is a tricky css thing :
ul {
font-size: 0;
}
li {
font-size: 12px;
}
If you set the parent with a font-size 0 the space will disappear.

two extra blank page add when printing

I am using using a CSS property for printing,
two extra page always added in my print. for this I tried these thing:-
.print:last-child {
page-break-after: auto;
}
but this is not working
I am also tried:-
html, body {
height: auto;
}
but problem is still there.
and when I using this:-
.print{
page-break-after: always
}
It prints an extra blank page before
please add page-break-after: avoid or page-break-before: avoid and you can reduce element spacing it also affect. if you give me url/js fiddle link it will be easier to fix issue. i have also hanged many times on print version

Strange extra top space in body [duplicate]

This question already has answers here:
How to remove margin space around body or clear default css styles
(7 answers)
Closed 3 years ago.
In this test page, the element has a strange extra amount of space on the top:
http://dl.dropbox.com/u/3085200/canvasTest/index.html
I tried putting margin, padding, top all to 0 for body, and padding to 0 for html, but none of it helped.
html
{
padding:0px;
}
body
{
margin:0px;
padding:0px;
top:0px;
}
Try this in css:
h1 {
margin-top: 0;
}
This is a common scenario (logo image wrapped in h1 tag):
I believe this is actually caused by the margin on your h1 element.
You <h1> has default margin-top added to it, so it's pushing the <body> down from the top of the window.
body > h1:first-child { margin-top: 0; }
My console is showing a 0.67em top margin on the <h1> surrounding your top element.
Try this...
h1 {
margin: 0;
}
Well, I'm sure the experts will laugh at this. I started using Expression Web 4 and tried to place the header info for my pages into a file header.txt to include on every page. I changed the file type from html to shtml and used this line:
All okay, except for a pesky extra space at the top of the file.
The solution was this:
Tools>Page Editor Options>Authoring
Uncheck .txt under "Add a Byte Order Mark when creating or renaming UTF-8 documents with these file extensions."
I hope this helps someone else as naive as I.
You can try to put a display flex on your body, it worked in my case
Hope it will help someone :)
I recognize that space at the top. This often happens to me too. In my case there is a hidden break (<br/>) somewhere between the <head> and <body>. When you find this break and remove it, the top space will be fixed!
html > h1:first-child { margin-top: 0; }
I know this post is old, but I wanted to share a different solution that worked for me, for anyone that might come across this same post, looking for help, as I have.
Every solution I found seemed to be the result of an error, but I didn't have any errors, that could see. After over an hour of problem solving and piecing apart one of my past designs, I found this solution:
In the CSS for the DIV that you want attached to the top of the browser, add this one simple line:
#ContentContainer{
border: 1px solid transparent;
};
I'm not quite sure why it works or why it's needed, but it made the gap disappear.

page-break-inside doesn't work in Chrome?

I have a bunch of paragraphs on a page:
<p> ... </p>
<p> ... </p>
<p> ... </p>
The CSS rule for those paragraphs is:
p {
margin: 20px 0;
page-break-inside: avoid;
}
Live demo: http://jsfiddle.net/KE9je/2/show/
If I understand the page-break-inside property correctly, the above should ensure that no paragraph is split between two pages. (A paragraph is either displayed on the "current" page, or if it doesn't fit completely, it's moved to the next page.)
This doesn't seem to work in Chrome. Open the demo, right-click the page, choose "Print...". You'll see a print preview - the fifth paragraph is split between page 1 and 2.
What am I doing wrong? How can I make this work in Chrome?
Actually, it DOES work in Chrome, and the solution is really silly!!
Both the parent and the element onto which you want to control page-breaking must be declared as:
position: relative;
Check out this fiddle (or in fullscreen)
This is true for:
page-break-before
page-break-after
page-break-inside
However, controlling page-break-inside in Safari does not work (in 5.1.7, at least)
I hope this helps!!!
This worked best for me:
.no-page-break {
display: inline-block;
width: 100%;
page-break-inside: avoid;
}
You can also specify the height if needed.
I've been fighting with this for a while and as well as follow the advice in the other answers I had to make sure that the element and all parent elements had the styling Display: block;.
I know this is an old question but Chrome has changed since it was originally answered and this may help.
It looks like page-break-inside:avoid works in Chrome based on the height of the element, so if you are floating a bunch of elements in a div, page-break-inside:avoid will not work.
It's possible to get around this by explicitly defining the height the element you don't want broken up. jQuery example:
$('#page_break_inside_avoid_element').height($('#page_break_inside_avoid_element').height());
According to SitePoint, Chrome is not supported here, only Opera (and IE 8 buggy)...
http://reference.sitepoint.com/css/page-break-inside
Other references:
http://www.webdevout.net
http://www.reddit.com/r/css/comments/jdeim/pagebreakinside_avoid_doesnt_work/
Stack Overflow threads:
Cross-browser support of `page-break-inside: avoid;`
"page-break-inside: avoid "- does not work
Google Chrome Printing Page Breaks
Which browsers support page break manipulation using CSS and the page-break-inside element?
Google Chrome Forum:
http://www.google.com/support/forum
I will not post the W3Schools link (due to general unreliability) but they also state it's only supported in Opera, for whatever it's worth.
I recently worked on the pdf download story which was having dynamic rows of data in table format which include various charts images(tech used=>Angular + Spring + Thymleaf + Puppeteer)
Some of the key points for handling page-breaks
Try to use <div></div>blocks instead of HTML tables
Do not use display: flex on the parent container on which you want page-break-inside: avoid(use float in child element)
.child1{
float: left;
}
3.If you are rendering div in loop and page-break-inside: avoid; not working
You should use this CSS hack to work on a particular div
<div class="parent-container">
<div class="child1"></div>
<div class="child2"></div>
</div>
.parent-container{
position: relative;
page-break-inside: avoid;
}
.parent-container::after {
content: "";
display: block;
height: 200px;
margin-bottom: -200px;
}
Check if the parent container display is not inline-block!!
If so, then it will never work! I waste few hours to figure it out.
Works in Chrome 87
For Bootstrappers, be aware that page-break-inside or others may not (highly) work under container or row or other classes of bootstrap even if you change manually the position property. When I exclude container and row, it worked like a charm!
I solved it: my problem was "a" parent div (not "the" parent div) set as display: flex.
I set it to display: block and it works.
I just tested this with a larger paragraph in IE9, Chrome 14 and Firefox 7, and it looks like only IE9 works as expected. You might have to resort to adding page breaks manually where you want them with
page-break-after:always
Of course that's only any good to you if you know the content length in advance.
What worked for me (in both FFox & Chrome, that is)
.container {
column-gap: .4em;
columns: 3;
padding: .4em;
}
.contained {
page-break-before: avoid;
page-break-inside: avoid;
page-break-after: always;
}
And that's it ; I didn't need position.
check if the parent(or top level container) display is flex ; remove it and try again;
it works for me in chrome71
Here is how I solved this while writing a css for printing.
For example, you put some pictures in an HTML file like this:
<div class="bottom">
<figure>
<img src="img01.jpg" alt="Front View">
<figcaption>Front View</figcaption>
</figure>
<figure>
<img src="img02.jpg" alt="Rear View">
<figcaption>Rear View</figcaption>
</figure>
</div>
And write the css like this:
.bottom figure{
page-break-inside: avoid;
}
Sometimes it won’t work as you expect, because the default value of display for most elements is block or inline, which is not ‘page-break friendly’. I usually change it like this:
.bottom{
display: contents;
}
This aims to disappear the container, making the child elements children of the element the next level up in the DOM.
As for your question, I suggest you to have a look at the display mode of the container of the paragraph to see whether it is set to block. If so, change it to contents and try again.
I hope this help.
After a huge digging, it seems to be a very silly, annoying and simple issue.
The key to fixing this issue is:
First, let's define what's parent and child.
Child: It's the element that we need to prevent/avoid cutting through in-between pdf pages
Parent: It's the direct parent/container of the child
Now we have the parent and the child very obvious, the next step is to give both parent and child some easy-to-implement rules. so let's do that
Parent rules
display: block;
Child rules
display: block; position: relative: page-break-inside: avoid;
That's it!
It Works for me, like this:
.print{position: absolute;}
.print p{page-break-inside: avoid}
Also page-break-inside: avoid may not work if one of parent elements has fixed height (say height: 1000px). I guess that's because browser is trying to fit content in specified height first and only then thinks about page breaking.
Changing to height: 100% fixed it for me.

Unexplainable UI Presentation Problem

Can anyone explain the weird presentation behavior in the UI screenshot above? As you can see, there's an undesirable separation between the insurance type and the top of the row. When looking at the code via Firebug, there's a clear break in the code. You can view this oddity in the code screenshot below.
The div.insurance-type parent container has no CSS styles. In other words, the vertical-align property, the margin-top property, the padding-top property, and the float property are set to default values and don't inherit a value that might cause this presentation. The children divs have this style:
div#worklist table tr td.col-InsuranceType div.insurance-type div {
display: block;
margin-bottom: 2px;
margin-left: 25px;
}
The span.insurance-company has this style:
div#worklist table tr td.col-InsuranceType div.insurance-type span.insurance-company {
font-weight: bold;
}
The components of this web app are:
ASP.NET MVC 3
Razor View Engine
jQuery 1.5.1
SQL Server 2008
IIS 7.5
This issue occurs in FF4, IE8 and IE7. Please let me know if you know the root cause of this unexplainable presentation behavior.
Thanks.
This is just a guess since I can't see the actual page, could there be some garbage character between the td and div that even firebug has trouble displaying? If the content is not client-side generated (ie: via Ajax), try viewing the source in Firefox (Ctrl-U or Cmd-U) and see if there is any weird character in there. I would even go as far as looking at the raw data in Fiddler.
On a different note, <div class="bold"> is bad practice (not semantic), use <strong> instead. :)
This might help:
Understanding vertical-align, or "How (Not) To Vertically Center Content"
Instead of
<div class="insurance-type">
<div class="bold">
<span class="insurance-company"
have you tried:
<div class="insurance-type"><div
class="bold"><span
class="insurance-company">