Remove white stripe on last page of PDF created by wkhtmltopdf? - wkhtmltopdf

I'm capturing IBM 3270 terminal screens in HTML, preserving attributes such as color and underlining in <span> elements with class attributes. This works well.
Now I want to present multiple screen captures in a PDF file, one capture per page; a slideshow.
I'm using wkhtmltopdf to convert the HTML to PDF. This works well, too, except for one nit: an unwanted thin white stripe at the bottom of the last page in the PDF. Hence this question.
Here's an HTML test case, consisting of 3 screens (simplistic test cards, with no display attributes):
<!DOCTYPE html>
<html>
<head>
<title>3270 terminal screen captures</title>
<style>
body {
font-family: sans-serif;
margin: 0;
padding: 0;
background-color: #000000;
}
pre.terminal {
font-family: "IBM Plex Mono";
margin: 0;
padding: 0.5em;
color: #00FF00;
font-size: 9.5pt;
line-height: 1;
}
pre.terminal:not(:first-child) {
page-break-before: always;
}
</style>
</head>
<body>
<pre class="terminal">12345678901234567890123456789012345678901234567890123456789012345678901234567890
2--------+---------+---------+---------+---------+---------+---------+---------+
3
4 Screen 1
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
</pre>
<pre class="terminal">12345678901234567890123456789012345678901234567890123456789012345678901234567890
2--------+---------+---------+---------+---------+---------+---------+---------+
3
4 Screen 2
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
</pre>
<pre class="terminal">12345678901234567890123456789012345678901234567890123456789012345678901234567890
2--------+---------+---------+---------+---------+---------+---------+---------+
3
4 Screen 3
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
</pre>
</body>
</html>
Here's the wkhtmltopdf command line I'm using to create the PDF (shown here with line breaks for readability):
wkhtmltopdf
--enable-local-file-access
--disable-smart-shrinking
--print-media-type
--dpi 300
--page-width 6.527in
--page-height 3.327in
--margin-top 0
--margin-right 0
--margin-bottom 0
--margin-left 0
input.html
output.pdf
Why wkhtmltopdf? My primary platform, and the primary platform of users I'll be sharing this method with, is Windows 10. I've read the project status of wkhtmltopdf, and looked at weasyprint, but I'm baulking at the steps involved in installing weasyprint on Windows.
I've read and applied the advice in the existing question "wkhtmltopdf with full page background", but that's not fixed this issue.
Setting the height of the <pre> to match the wkhtmltopdf page height doesn't fix it, either:
box-sizing: border-box;
height: 3.327in;
Workaround
Workaround, not a solution: append extraneous content, and then delete the last page from the PDF. The remaining pages have edge-to-edge ("full-bleed") background color, as desired.
For example, add a bottom border to the <body> element:
border-bottom: 1px solid #000000;

Related

how includes only a few icons from bootstrap-icons?

how could I includes only a few icons from the bootstrap-icons project?
I have added the project to my dependencies (yarn add bootstrap-icons) and searching in it I can see that it has a sass file with a giant map variable "$bootstrap-icons-map" I won't include all icons, sooo, how could I includes only some icons its there any way defined?
You can do it manually. You can create a web icon font from yourself: I use often this tool: https://fontello.com/
You can take the bootstrap-icons you want from here : https://icons.getbootstrap.com/
and drag and drop into the previous tool fontello. You have to set your font-name and customize icon-names and code. Now you are ready to download your web icon font (top right download button). In that folder you will have the subfolder font with your custom web-icon-font. Inside subfolder css you will find the your-font-name.css file and inside it you will find the rules to include your web icon font (#font-face rule, bring this rule inside your css) and the rules to include the icons with the class bi-icon-name (you have to do this customization inside fontello, namely change the prefix (default prefix is icon- , change to bi-) and the icons-name).
Now you can put the bootstrap-icons rules too inside your css/sass :
.bi::before,
[class^="bi-"]::before,
[class*=" bi-"]::before {
display: inline-block;
font-family: bootstrap-icons !important;
font-style: normal;
font-weight: normal !important;
font-variant: normal;
text-transform: none;
line-height: 1;
vertical-align: -.125em;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
And now you can do:
<i class="bi bi-nome-mia-icona></i>
This approach can seems intimitadatory but is pretty simple.
Another possibility is to build an svg icon font, this has a series of advantages against web icon font, for example if you have few icons you can embedd your svg icon font inside your html page and save an http request and the download but if you have several icons your html page could become too big, in this case the svg icon font should be extern and in this case there are a lot of problems to handle it. If you want more insight about how to create an svg icon font tell me.
Last but not least, you could use svg inline.
For example put this directly into your html for yin-yang icon:
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-yin-yang" viewBox="0 0 16 16">
<path d="M9.167 4.5a1.167 1.167 0 1 1-2.334 0 1.167 1.167 0 0 1 2.334 0Z"/>
<path d="M8 0a8 8 0 1 0 0 16A8 8 0 0 0 8 0ZM1 8a7 7 0 0 1 7-7 3.5 3.5 0 1 1 0 7 3.5 3.5 0 1 0 0 7 7 7 0 0 1-7-7Zm7 4.667a1.167 1.167 0 1 1 0-2.334 1.167 1.167 0 0 1 0 2.334Z"/>
</svg>
In this case you haven't to include cdn, neither import anything. It's enough the svg inline that you can find for all the pther icons here (clicking on the icons) https://icons.getbootstrap.com/:
I hope this help you.

Is there a way to freeze a column in a vuetify data table?

I cannot find a good solution to this without using a vuetify fork, which isn't stable and appears to be the older version anyway. I will link to it in the comments.
The only way I can think to do this is to line up two data tables side by side, which creates problems in itself. I know there are other plugins/libraries that allow this, but I would really prefer to stick with vuetify. Has anyone had success with doing this?
My project is to create a grid that allows the user to set up a rotation. Each column (after the first one) is a dynamically created week (Friday's date is column header) that shows if there is an opening in a given organization. The struggle is to get enough weeks to show up on the screen at once. The first column is the organization. So, I want to know what organization my row is in for a given week as I scroll to the right. That's why I need to freeze the first column.
I'm open to other solutions - like a different way to show the header, perhaps, that would allow me to fit in 52 weeks worth of dates.
I am also searching for a solution to this. The nearest I have found is this complex bit of CSS Source
<style>
table > tbody > tr > td:nth-child(1),
table > thead > tr > th:nth-child(1) {
position: sticky !important;
position: -webkit-sticky !important;
left: 0;
z-index: 9998;
background: white;
}
table > thead > tr > th:nth-child(1) {
z-index: 9999;
}
</style>
However, it doesn't quite work for my case.
I have something like this
Account Jan Feb Mar
123456 50 51 52
123458 38 39 32
123600 20 21 22
So what I am looking for is the Excel equivalent of putting a freeze panes on the Jan,123456 intersection, so that the months stay in place when scrolling down, and the Account column stays in place when scrolling to the right.
I set the fixed-header and :height property on the v-data-table so that the header does not scroll vertically and so that it has a vertical scroll bar. The horizontal scroll bar seems to happen automatically and is specific to the table rather than the page.
Without the CSS the vertical scrolling works, though obviously not the horizontal scrolling as the Account column scrolls off screen to the left.
With the CSS the account numbers stay in position, but the headings still scroll to the left, so eg Jan replaces Account. Also when scrolling down, the Account Numbers scroll up to overwrite Account. It is closer to a solution than the basics provided by Vuetify.
I also saw the example from someone who had cloned vuetify and modified it to include fixed columns and grouping. However, I was not sure whether that was vuetify 1.5 or 2 and I have already had issues with seeing examples on 1.5 and then finding that they don't work on vue 2 which I am using as there were so many breaking changes. Like you I am also wary of adopting something that may not be supported.
I am surprised that Vuetify did not include this. It must be a pretty common requirement. I have seen an enhancement request for Vuetify 3, but it is too early to adopt that and presumably it would also mean adopting Vue 3.
Regards
Paul Simon
I finally found an approach to this that works. Another approach
However, I cannot really claim it as an answer to the original question as it only works by abandoning the use of a v-data-table altogether. I ended up just putting a standard table in between v-spacer in my vuetify card. Any attempt to use even a v-simple-table added a second unnecessary horizontal scroll bar which ruined the effect.
The bit of CSS linked above does at least give fixed header(s) and fixed column(s) with none of the issues around scrolling up over the top left corner cell of other approaches I have seen.
It is also very easy to mark which headers you want fixed (usually all) and, in particular, which columns you want fixed. Note that the fixed columns should use 'th' rather than 'td'. This is ideal for my purpose since my data source is multi-dimensional and returns row headers and then cells with numbers eg
Actual Actual Budget Budget
Country Product Jan Feb Jan Feb
UK Widget1 50 60 70 20
UK Widget2 60 80 90 100
USA Widget1 90 80 10 90
In the example above all the following are 'th'
Actual, Budget, Jan, Feb
Country, Product
Only the number cells are 'td'
As you can see, all you need to do is to mark the 'th' in the html with class="fixed" so unlike other approaches it works for an arbitrary number of columns rather than just the left most column.
I am an expert in multi-dimensional modelling, and certainly not an expert in CSS, but I modified the CSS in the linked example a little. My CSS is as follows:
<style scoped>
.table {
background-color: white;
margin: auto;
width:90%;
max-width:100%;
border-collapse: separate;
display: block;
overflow-x: scroll;
}
thead,
tbody {
display: inline-block;
}
thead {
position: sticky;
top: 1px;
z-index: 2;
}
tbody {
height: 200px;
}
th {
background-color: lightgrey;
border-left: 1px;
border-right: 1px;
border-color: black;
}
td,
th {
min-width: 100px;
max-width: 100px;
word-wrap: break-word;
}
.fixed {
position: sticky;
width: 5em;
left: 0;
top: auto;
z-index: 1;
}
td:not(.fixed) {
z-index: 0;
}
</style>
Instead of giving a fixed width for the table, I used %. I know that not all browsers support this but this is going to be an internal application. It is not a shopping site.
I also took the z-indexes down from 9999,999,0 to 2,1,0 as without this it tended to wind up on top of the Vuetify footer when scrolling down.
Regards
Paul Simon

wkhtml2pdf rendering size issue

Taking care of removing any paddings or margins, I have created a basic html page containing a single table whose height is supposed to be 297mm (A4 paper height):
<!DOCTYPE html>
<html>
<head>
<style>
body
{
padding: 0; /* Padding for content */
margin: 0 auto; /* Margin from container */
}
table
{
padding: 2.5mm 5mm; /* Padding for content */
margin:0; /* Margin from container */
width:100%;
border-spacing:0;
background-color:yellow;
height:297mm;
}
</style>
</head>
<body>
<table>
<tr style="height:3%"><td style="background-color:RGB(235, 105, 11)">1</td></tr>
<tr style="height:30%"><td style="background-color:RGB(47,52,57)">2</td></tr>
<tr style="height:17%"><td style="background-color:RGB(94,98,102)">3</td></tr>
<tr style="height:auto"><td style="background-color:RGB(255,255,255)">4</td></tr>
<tr style="height:13%"><td style="background-color:RGB(47,52,57)">5</td></tr>
</table>
</body>
</html>
And I'm trying to render this in A4 PDF format using wkhtml2pdf utility (again taking care of removing any margin and/or padding:
wkhtmltopdf.exe --page-size A4 -L 0 -R 0 -T 0 -B 0 .\testsize.html testsize.pdf
Anyway rendered table height does not seem to be 297mm in PDF document. It appears to be smaller:
It is only when modifying table height to height: 371mm that I can have it to fill full A4 paper height in the PDF document (NB: 371mm/291mm is almost a x1.25 ratio).
Do you have any idea for where this ratio in rendering height comes from and how i may fix it ?
NB1: As far as I know wkhtml2pdf uses webkit as rendering engine
NB2: When displaying html code in chrome with zoom=x1, displayed height already doesn't match with A4 PDF document placed side-by-side and zoom also set to x1.
I'm not sure wkhtmltopdf respects the mm CSS unit. That said, you could try to adjust some command line options that modify the ratio between the HTML document sizes and the rendered PDF:
--zoom <float>: I think this one is the most important in your case. Try to set to --zoom 1.25, the ratio you estimated.
--disable-smart-shrinking: In my experience, this command often prevents element sizes to have unexpected values.
--dpi <number>: I'm not sure if this will change something, but try 300 or 600.

Html anchor height issue with unitless line heights

Trying to conform to unitless line heights I have a problem with overflow: auto and anchor elements.
Consider the following simple page:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<head>
<title>test</title>
</head>
<body style="font-family: arial; font-size: 12px; line-height: 1;">
<div id="wrapper" style="overflow: auto; background-color: #FFCCCC;">
<p>Blah blah blah</p>
Test
</div>
</body>
</html>
The combination of font-size: 12px and line-height: 1 should make the height of the paragraph and anchor (without padding, margin and border) 12 pixels.
The total height of the page should therefore be: 4 * 12 = 48 pixels (2 elements plus 2 * 12 pixels margin for the paragraph). However, almost every browser 'reserves' two or three extra pixels for underlining the anchor (even though I used text-decoration: none). Firefox 7, Chrome 14 and Opera 11.51 all show this behaviour, surprisingly IE9 works fine :).
With their respective developer toolbars, you can see that all browsers agree that the div element has a height of 48 pixels, but only IE thinks the anchors height is 12 pixels. Other browsers say 14 or 15 pixels, causing the scrollbar to appear.
When removing the overflow: auto is not an option (in my case the div is generated by a framework and sometimes just contains floating elements, so the overflow is used to extend the div to encapsulate its children), is there any proper solution to this? i.e. better than giving the anchor font-size: 15px or line-height: 1.2 or something.
Cheers,
Moolie
The issue only seems to happen if the a is touching the bottom of #wrapper directly. This means you can solve the problem in 3 ways:
put the link into a paragraph
set display block on the link and give it a margin
set a padding bottom on the wrapper
You'll have to decide if you find these more "clean".

Firefox 4 Windows only "bug" with :after/:before CSS selectors?

I think this is a bug, and if so im going to report it, but even if it is a bug i need a way to fix this. I'd really like to not have to use an image but here's the problem:
JSBin Example: http://jsbin.com/alame5
Chrome 3 on Mac (and Windows)
Firefox 4 on Mac
Works the same on IE8 and IE9 as above
Now, Firefox 4 on Windows 7
the same affect can be made with one p:before:
.twitterfeed p:before {
content:"\00a0";
display:block; /* reduce the damage in FF3.0 */
position:absolute;
bottom:-20px; /* value = - border-top-width - border-bottom-width */
right:25px; /* controls horizontal position */
width:0;
height:0;
border-width:0 0 20px 20px; /* vary these values to change the angle of the vertex */
border-style:solid;
border-color:transparent transparent transparent #fff;
z-index: 0;
}
I only changed the border-width, according to this page.
But still, i'm pretty sure its a FF4 bug..

Resources