I am generating PDF using ejs file in nodejs. Is it possible to add Footer on every page of the generated PDF?
Here is my ejs file:
<!DOCTYPE html>
<html>
...
<head>
<style>
footer{
background-color: red;
width: 100%;
position: absolute;
bottom: 0;
left: 0;
right: 0;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
</style>
</head>
<body> ... </body>
<footer>
<p>this is footer</p>
</footer>
</html>
here is my nodejs code snippet:
ejs.renderFile(path.join(__dirname, './views', "report-template.ejs"), { invoicedata: JSON.parse(results[0].jsondata), moment:moment }, (fileerr, data) => {
if (fileerr) {
console.log("Error!", fileerr);
} else {
let options = {
"height": "11.7in",
"width": "8.3in",
}
pdf.create(data, options).toFile("report.pdf", function (err, data) {
if (err) {
console.log("error!!");
} else {
console.log("file created successfully");
}
})
}
})
The output pdf getting is:
screenshot of pdf
Whilst it is fairly easy to emulate page breaks headers and footers in HTML they are not natural for a format that is designed for unfettered page widths or lengths.
It is common to describe HTML objects as % of a variable canvas the conversion to the fixed Cartesian pages needed by PDF is prone to rounding errors.
Here as an example, the primary aim was to emulate a PDF layout in Microsoft Edge (Chrome based) but the fiddle factors that work fairly well for view and print in one browser will need adjustments in another.
SEE the inset where the page for exactly the same code and target printer which is perfect in edge print preview, is subject to creep-age in Internet Explore, on the same printer defaults !! That crap-page thus often requires minor tweaking to keep it in sync, leading to two different copies of source !
<!DOCTYPE html>
<html><head>
<meta content="text/html; charset=utf-8" http-equiv="Content-Type">
<title>Dynamic Styles: NewPage Breaking Headline News</title>
<!--
Generic break values
NewPage break values
Column break values
Region break values
Global values
-->
<style type="text/css" media="all">
.body {
position: absolute;
}
#page {
break-before: auto;
margin: 0px;
width: 736px;
height: 1103px;
position: relative;
}
h1 {
text-align: center;
}
#page-break {
position: absolute;
bottom: 0;
width: 100%;
height: 20px;
padding: 20px;
background-color: red;
text-align: center;
}
</style>
</head>
<body>
<div id="page">
<div>
<br><h1>Headline on Page 1</h1>
...
more content on Page 1
...
</div>
<div id="page-break"> Footline on Page 1 </div>
</div>
<div id="page">
<br><h1>Headline on Page 2</h1>
...
more content on Page 2
...
<div id="page-break"> Footline on Page 2 </div>
</div>
<div id="page">
<br><br><h1>Headline on Page 3</h1>
...
more content on Page 3
...
<div id="page-break"> Footline on Page 3 </div>
</div>
</body></html>
Maybe this CSS can help? I.e. change "absolute" position to fixed?
#media print {
footer {
position: fixed;
bottom: 0;
}
}
There were some comments in this question that might be helpful:
How to use HTML to print header and footer on every printed page of a document?
Related
I want to add footer in the end of the page after every page-break in the html.
here is the html code(here when the content of the container is overflow i want to add footer at that page as well as on the second page it creates after the page-break):
<html>
<head>
...
<style>
.container {
width: 695px;
height: 1022px;
display: flex;
flex-direction: column;
margin: 10px;
padding: 40px;
color: #495057;
letter-spacing: 1px;
}
.footer{
position: absolute;
bottom: 0;
width: 100%;
background-color: red;
text-align: center;
page-break-after: always;
}
</style>
</head>
<body>
<div class="container">
...
</div>
<div class="footer">
...
</div>
<body>
</html>
Output ( as we can see in the output it only gives the footer in the first page but i want it in the second page as well):
You can use csi.js .
u will need to add the csi.min.js file in your <head>.
Make a footer.html
and add this to every page where u want that file to be included, in this case at last where u want your footer to be.
<body>
//Your page
<div data-include="footer.html"></div>
</body>
Edit:
I found this in their readme. try adding
"footer": {
"height": "28mm",
"contents": {
first: 'Cover page',
2: 'Second page', // Any page number is working. 1-based index
default: '<span style="color: #444;">{{page}}</span>/<span>{{pages}}</span>', // fallback value
last: 'Last Page'
}
},
to config
I am buliding a custom email template and i am trying to put text in a specific position on an image. This template is built dynamically via mustache on a camunda workflow model.
The codes below can be tested/viewed at w3schools
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
.container {
position: relative;
text-align: left;
color: white;
}
.top-left {
position: absolute;
top: 170px;
left: 250px;
}
</style>
</head>
<body>
<div class="container">
<img data-imagetype="External" src='img_snow_wide.jpg' width="1000" height="600">
<div class="top-left">{{happyBirthday}}</div>
</div>
</body>
</html>
As you may see {{happyBirthday}}, which will display values dynamically, is showing on the desired place on the image when using CODE A.
However the template received via email shows the value for {{happyBirthday}} below the image. I was able to get the snippet of code, CODE B, from the elements tab on chrome console via inspect,
CODE B
<div>
<style>
<!-- .rps_9d84 .x_container {
text-align: left;
color: white
}
.rps_9d84 .x_top-left {
top: 170px;
left: 250px;
color: #000080
}
-->
</style>
<div class="rps_9d84">
<div>
<div class="x_container">
<img data-imagetype="External" src="img_snow_wide.jpg" width="1000" height="600">
<div class="x_top-left">{{happyBirthday}}</div>
</div>
</div>
</div>
</div>
As you may see the two codes are similar in the key aspects of the css code i.e. top-left, which determines the position of the dynamic text on the image.
I am not an html expert and i do not see the difference between the two sets of code. Could someone point out what i am missing here ?
You are missing the position: absolute; property on .x_top-left
Since your top-left class element doesn't seem to apply the absolute position style (in CODE B), which will by default always be placed under or next to the previous element.
Try to set the position element with the !important flag.
.top-left {
position: absolute !important;
top: 170px;
left: 250px;
}
This website doesn't seem to be using any javascript (besides something for webfont). Yet clicking a link applies a set of css rules. How does it work and what feature(s) of html/css is being used here?
As far as I can tell, data-step attribute seems to be playing some part in this. But I'm not familiar with how this works to produce the desired affects.
HTML
<!DOCTYPE html>
<html>
<head>
<title>Web Design in 4 minutes</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
...
<link rel="stylesheet" type="text/css" href="website.css">
</head>
<body>
<header id="header">
<img id="logo" src="jt.png" alt="JT logo">
<h1>Web Design in 4 minutes</h1>
<p>
by Jeremy Thomas
</p>
</header>
<main>
<section id="start">
<p>Let's say you have a product, a portfolio, or just an idea you want to share with everyone on your <em>own</em> website. Before you publish it on the internet, you want to make it look attractive, professional, or at least <em>decent</em> to look at.</p>
<p>What is the <a class="step" data-step="0" href="#content">first thing</a> you need to work on?</p>
</section>
<section id="content">
<h2>Content</h2>
<p>The purpose of <strong>design</strong> is to enhance the presentation of the content it's applied to. It might sound obvious, but content being the <strong>primary</strong> element of a website, it should not be established as an afterthought.</p>
<p>Written content, like the paragraph you're currently reading, makes up for more than 90% of the Web. Styling this textual content will go a long way.</p>
<p>Let's assume you've already finalised the content you want to publish and just created an empty <code>style.css</code> file, what is the <a class="step" data-step="1" href="#centering">first rule</a> you can write?</p>
</section>
<section id="centering">
<h2>Centering</h2>
<p>Long lines of text can be hard to parse, and thus hard to <strong>read</strong>. Setting a limit of characters per line greatly enhances the readability and appeal of a wall of text.</p>
<pre><span class="selector">body</span> {
<span class="attribute">margin</span>: <span class="number">0</span> auto;
<span class="attribute">max-width</span>: <span class="number">50</span><span class="unit">em</span>;
}</pre>
<p>After styling the text <em>blocks</em>, what about styling the <a class="step" data-step="2" href="#font-family">text itself</a>?</p>
</section>
<section id="font-family">
<h2>Font family</h2>
<p>The browser's font defaults to <code>"Times"</code>, which can look unappealing (mostly because it is the "unstyled" font). Switching to a <strong>sans-serif</strong> font like <code>"Helvetica"</code> or <code>"Arial"</code> can vastly improve the look of your page.</p>
<pre><span class="selector">body</span> {
<span class="attribute">font-family</span>: <span class="string">"Helvetica"</span>, <span class="string">"Arial"</span>, sans-serif;
}</pre>
<p><em>If you want to stick with a serif font, try <code>"Georgia"</code>.</em></p>
<p>While this makes the text more <em>appealing</em>, let's also make it <a class="step" data-step="3" href="#spacing">more readable</a>.</p>
</section>
...
CSS
/* Base styles */
a strong {
color: inherit;
}
hr {
background: none;
border: none;
border-bottom: 1px solid #d8dee9;
}
img {
height: auto;
max-width: 100%;
}
pre {
overflow: auto;
white-space: pre-wrap;
}
footer {
align-items: center;
display: flex;
justify-content: center;
margin-top: 4em;
text-align: center;
}
/* Initial state */
#visited {
background-color: white;
bottom: 0;
color: white;
display: block;
left: 0;
padding: 1em;
position: fixed;
right: 0;
text-align: center;
}
#visited:visited {
background-color: #e81c4f;
}
#logo,
section,
footer {
display: none;
}
#start {
display: block;
}
/* 00 Content */
html.step0 #content {
display: block;
}
/* 01 Centering */
html.step1 #centering {
display: block;
}
html.step1 header,
html.step1 main {
margin: 0 auto;
max-width: 50em;
}
...
The website is working on href and id concept. (same page navigation)
http://jgthms.com/web-design-in-4-minutes/
Example:
go to id
<div style="margin-top:2000px;"></div>
<a id="id">id</a>
This refers to same page navigation. By default the content is display:none and on click of it, it is visible.
Hope it helps you.
Cheers!
I have a situation where I am trying to display log data in XML format.
A template for the main page 'mainpage.html' defines the DIV and iframes.
A CSS file 'style2.css' defines the attributes of the page and data.
A file 'header.html' is sourced into one of the iframes. I'm only doing the last one because I don't want to have to build static headers every time the log file is parsed into table format.
And a fourth file, a sample log file, 'import.xml', is sourced into the other iframes. This file reads a log file in XML format and wraps data with <tr> and <td> tags.
Several problems are giving me grief.
My selectors for <TH> and <TD> tags are not taking effect
<TR> tags are not working in iframe
Vertical scrollbar is not hiding
Text is not centering
I don't have this problem if I put everything into one html file. It's only when I'm sourcing in external files.
I hope I'm being clear enough. The files that I'm providing are not meant to be production quality. Instead they are only proving out functionality. They are pretty basic and ugly.
Here are the file contents:
mainpage.html
<!DOCTYPE html>
<head><link rel="stylesheet" href="style2.css"></link></head>
<body>
<div id="container">
<div id="header">
<iframe id="hdr-frame" src="header.html"></iframe>
</div>
<div id="main">
<iframe id="main-frame" src="import.xml"></iframe>
</div>
</div>
</body>
</html>
header.html
<DOCTYPE! html>
<head>
<body>
<table id="header-table">
<th>Header 1</th><th>Header 2</th><th>Header 3</th><th>Header 4</th><th>Header 5</th><th>Header 6</th>
</body>
</html>
style2.css
#container {
width:800px;
height:auto;
margin-left:auto;
margin-right: auto;
margin-top: 11px;
margin-bottom: 21px;
background-color: yellow;
}
#header {
height: 33px;
width:790px;
margin-left: auto;
margin-right: auto;
border: 1px solid black;
background-color: Red;
overflow: hidden;
}
#main {
width:99%;
height: auto;
margin-left: auto;
margin-right: auto;
background-color:Green;
color: white;
}
#import-table > tr > td {
width:30px;
color:red;
vertical-align: middle;
}
td {
width: 30px;
color: red;
text-align: center;
}
#hdr-frame {
width:790px;
height: 30px;
text-align: center;
}
#main-frame {
width:790px;
height: auto;
overflow: hidden;
}
import.xml
<!DOCTYPE HTML>
<head><link rel="stylesheet" href="style2.css"></link>
<body>
<table id="import-table">
<tr><td>Element 1</td><td>Element 2</td><td>Element3</td><td>Element 4</td><td>Element 5</td><td>Element6</td></tr>
<tr><td>Element 7</td><td>Element 8</td><td>Element9</td><td>Element 10</td><td>Element 11</td><td>Element12</td></tr>
</table>
</body>
</html>
I ended up figuring out most of my own problems. I named the file being sourced is as '.xml', since that was what it started out to be. But when I added HTML tagging, it didn't matter to the browser that it was now an html file, it still interpreted it as an XML file.
For some reason the page i've made has stopped showing the image, it's just showing a small broken page icon, even though it showed it before. I haven't changed the name of the image or its location.
I'm also trying to create a button, but it's not showing up
Here's the html code:
<!DOCTYPE html>
<html>
<head>
<title>Title</title>
<link href="design.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div id="pic">
<img src="C:\Users\A\Desktop\Untitled.jpg" id="pic">
</div>
<div class='banner'>
</div>
<div class="button">
</div>
</body>
</html>
and here's the css code:
#pic {
position: absolute;
margin-left: 40px;
margin-top: 4px;
z-index: 1;
}
.banner {
height: 100px;
width: 100%;
background-color: #FFFFFF;
position: absolute;
top: 0;
left: 0;
z-index: 0;
}
.button {
height: 50px;
width: 120px;
background-color: #BCD2EE;
border-color: #6495ED;
z-index: 3;
}
Body {
background-color: #E8E8E8;
}
The page just shows the white banner at the top of the page and the grey background, but the image just shows a small broken page icon, and the button isn't being created.
You are referencing a file from your local file system. For security reasons this is not possible, and should never be possible. Upload the image to your server, or move it to the correct folder if you use localhost, and reference the image via an url relative to the domainname.
You're using a absolute address to the image, my bet is that you either moved the file or renamed it, or even deleted it. Just make sure the path is correct and it should work.
By the way, the <title> tag should go inside the <head>.