PHP HTML to PDF mikehaertl/phpwkhtmltopdf Page Size Issue - php

I'm currently running mikehaertl/phpwkhtmltopdf package to convert HTML to PDF. Using the demo data I appear to be having issues with the PDF rendering the correct page dimensions. I need the page to be filled with an A4 layout, but I'm getting a much smaller resolution output for some reason. I believe there is either a setting I'm not aware of or I'm missing something in the HTML/CSS?
The PHP I am running is:
$pdf = new mikehaertl\wkhtmlto\Pdf(
array(
'binary' => '/usr/local/bin/wkhtmltopdf',
'no-outline', // Make Chrome not complain
'margin-top' => 0,
'margin-right' => 0,
'margin-bottom' => 0,
'margin-left' => 0,
// Default page options
'disable-smart-shrinking'
)
);
$pdf->addPage($this->getOrderPrint($objectId));
// Save the PDF
$pdf->saveAs(dirname(__FILE__).'/test.pdf');
The getOrderPrint method is correctly returnin the below HTML:
<!DOCTYPE html>
<head>
<style type="text/css">
body {
margin: 0;
padding: 0;
width: 21cm;
height: 29.7cm;
}
/* Printable area */
#print-area {
position: relative;
top: 1cm;
left: 1cm;
width: 19cm;
height: 27.6cm;
font-size: 10px;
font-family: Arial;
}
#header {
height: 3cm;
background: #ccc;
}
#footer {
position: absolute;
bottom: 0;
width: 100%;
height: 3cm;
background: #ccc;
}
</style>
</head>
<body>
<div id="print-area">
<div id="header">
This is an example headernbmv.
</div>
<div id="content">
<h1>Demo</h1>
<p>This is example content</p>
</div>
<div id="footer">
This is an example footer.
</div>
</div>
</body>
</html>

Try to add 'page-size' => 'A4' to your wkhtmltopdf options.

Related

Unable to add Header Footer on every page of pdf using DOMPDF

I am creating pdf by passing html to dompdf. I am trying to add header and footer on every page of the pdf. The issue is that the pdf has multiple pages. The header is created on the first page and footer on the last page. I need them both on every page.
#page {
margin: 0cm 0cm;
}
body {
margin-left: 1cm;
margin-right: 1cm;
margin-top: 1cm;
margin-bottom: 1cm;
}
header {
position: fixed;
top: 0cm;
left: 0cm;
right: 0cm;
height: 1cm;
padding: 10px;
background-color: #0011ff;
}
footer {
position: fixed;
bottom: 0cm;
left: 0cm;
right: 0cm;
height: 1cm;
padding: 10px;
background-color: #0011ff;
}
<header>
<p>Header</p>
</header>
<div>
<p>main content. This is just an example of how I am creating the document. This div's content spans on multiple pages.</p>
</div>
<footer>
<p>Footer</p>
</footer>
I got the solution from here and added bottom: 0px; to the footer style.
Here is the full code:
<!DOCTYPE html>
<html lang="en">
<head>
<style>
#page{
margin-top: 150px;
margin-bottom: 150px;
}
header{
position: fixed;
left: 0px;
right: 0px;
height: 150px;
margin-top: -150px;
}
footer{
position: fixed;
left: 0px;
right: 0px;
height: 150px;
bottom: 0px;
margin-bottom: -150px;
}
</style>
</head>
<body>
<header>
<img src="{{public_path("images/header.jpg")}}" style="width: 100%" >
</header>
<footer>
<img src="{{public_path("images/footer.jpg")}}" style="width: 100%">
</footer>
<main>
<!-- content here -->
</main>
</body>
</html>
The generated PDF had the header and footer images on all pages.
Please add proper html tags like; You need to wrap with html and body tag to make it work. This will print header and footer in each pdf pages.
<html>
<body>
<header>
<p>Header</p>
</header>
<footer>
<p>Footer</p>
</footer>
<div>
<p>main content. This is just an example of how I am creating the document. This div's content spans on multiple pages.</p>
</div>
</body>
</html>

How can I use html code in DOM PDF footer?

This is how I create the footer with DOMPdf:
$canvas = $dompdf->get_canvas();
$footer = $canvas->open_object();
$w = $canvas->get_width();
$h = $canvas->get_height();
$canvas->page_text($w-85,$h-28,"footer right",'helvetica',8);
$canvas->page_text($w-320,$h-28,"Page {PAGE_NUM} of {PAGE_COUNT}",'helvetica',8);
$canvas->page_text($w-550,$h-28,"footer left", 'helvetica',8);
This creates 3 sections in my footer, which works fine for me.
But I need the possibility in each line to integrate html text. I tried it like this:
$canvas->page_text($w-85,$h-28,"<b>My Company</b><br>My street<br>My city",'helvetica',8);
$canvas->page_text($w-320,$h-28,"Page {PAGE_NUM} of {PAGE_COUNT}",'helvetica',8);
$canvas->page_text($w-550,$h-28,"footer left", 'helvetica',8);
But the html code is not converted in the pdf.
I also tried:
$text = $dompdf->loadHtml("<b>My Company</b><br>My street<br>My city");
$canvas->page_text($w-85,$h-28,$test,'helvetica',8);
Like this nothing is loaded
You can't add html code in DomPdf
But you can work around using css
footer {
position: fixed;
bottom: 0;
left: 0px;
right: 0px;
height: 20px;
border-top: 1px solid #AAAAAA;
color: #777777;
width: 100%;
padding: 8px 0;
text-align: center;
}
And in html body place your content in <footer> </footer>
Working example:
<html>
<head>
<style>
#page { margin: 180px 50px; }
#header { position: fixed; left: 0px; top: -180px; right: 0px; height: 150px; background-color: orange; text-align: center; }
#footer { position: fixed; left: 0px; bottom: -180px; right: 0px; height: 150px; background-color: lightblue; }
#footer .page:after { content: counter(page, upper-roman); }
</style>
<body>
<div id="header">
<h1>Widgets Express</h1>
</div>
<div id="footer">
<p class="page">Page </p>
</div>
<div id="content">
<p>the first page</p>
<p style="page-break-before: always;">the second page</p>
</div>
</body>
</html>

Dompdf: how to get background image to show on first page only

I am using dompdf to generate letters which I want to brand with various different companies branded paper. To do this I'm getting a background image via css. See example image at bottom. I then set appropriate margins to fit the content I want to write out into the white space. However I just want this letterhead to display on the first page only. At present it is repeating onto each page. My css looks like:
<html>
<head>
<meta charset="utf-8">
<title>{$pdf.title}</title>
<style type="text/css">
#page {
size: A4;
margin:0;
padding: 0;
}
body {
padding: {$branding.page_margin_top}cm {$branding.page_margin_right}cm {$branding.page_margin_bottom}cm {$branding.page_margin_left}cm;
font-size: 7pt;
font-family: helvetica !important;
background-image: url('{$base_url}pd-direct.png');
background-position: center center;
background-repeat: no-repeat;
font-size: 10pt;
}
#postal-address {
margin: 0cm;
margin-left: {$branding.address_offset_left}cm;
margin-top: {$branding.address_offset_top}cm;
margin-bottom: {$branding.address_offset_bottom}cm;
font-size: 10pt;
}
#date {
font-weight: bold;
}
</style>
</head>
<body>
<div id="page-body">
<div id="content">
{if $pdf.postal_address}
<div id="postal-address">
{$pdf.postal_address|nl2br}
</div>
{/if}
{$pdf.main_body}
</div>
</div>
</body>
</html>
How can I change this so the background image is only displayed on the first page output by dompdf?
See current html being rendered at: http://eclecticgeek.com/dompdf/debug.php?identifier=ccfb2785f8a8ba3e1e459cbd283ad015
You can put the letterhead as the background image in an div that overlaps the main content div and use z-index to organise the stacking order of the divs, so that background image will appears at the back.
This way, the background image will only show on the first page when you convert it to PDF using DOMPDF.
The CSS below works for A4#150dpi.
CSS
#page {
size: A4;
margin-top:0.5cm;
margin-bottom:0;
margin-left:0;
margin-right:0;
padding: 0;
}
body {
font-family: helvetica !important;
font-size: 10pt;
position: relative;
}
#overlay {
position: absolute;
top: 0;
left: 0;
height: 100%;
width: 100%;
background-image: url('http://www.showhousesoftware.com/pd-direct.png');
background-position: center top;
background-repeat: no-repeat;
z-index: -1;
}
#content{
padding: 3.5cm 0.50cm 5.00cm 0.50cm;
}
#postal-address {
margin: 0cm;
margin-left: 1.50cm;
margin-top: 0.00cm;
margin-bottom: 1.00cm;
font-size: 10pt;
}
#date {
font-weight: bold;
}
HTML
<body>
<div id="page-body">
<div id="overlay">
</div>
<div id="content">
......
</div>
</div>
</body>

Issue With Header and Footer Include

I'm having an issue trying getting my fixed header and footer to show using a php include
Here is my HTML
<?php include '_includes/header.php' ?>
<div class="neo__wrapper">
<div class="neo__container">
</div>
</div>
<?php include '_includes/footer.php' ?>
My SASS (used for nesting)
*{
margin: 0;
padding: 0;
text-decoration: none;
border: 0;
border: none;
}
html,body{
width: 100%;
height: 100%;
}
.neo__wrapper{
width: 100%;
height: 100%;
margin: 0 auto;
.neo__container{
width: 960px;
height: 3000px;
margin: 0 auto;
}
}
header{
background:#ccc;
width: 100%;
position: fixed;
height: 100px;
top: 0;
}
footer{
background:#ccc;
position: fixed;
width: 100%;
height: 50px;
bottom: 0;
}
I'm just building a framework so my header.php is just
<header></header>
and my footer.php is
<footer></footer>
Basically, my page should just have a gray fixed header and footer
Your including an empty file.
<head><link rel="stylesheet" type="text/css" href="MyCSSFile.css"></head>
also, if you are doing a header and footer on every page, include this code into them as well. in header.php
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" type="text/css" href="MyCSSFile.css">
</head>
<body>
and in footer.php
<footer>
<script src="MyJavascriptFile.js"></script>
</footer>
</body>
</html>
Just figured out that it was an issue regarding WAMP, so PHP wasn't even running in the first place

Why does my <body> content get overlapped by the content "included" from an external file?

I was following this tutorial to learn about the include and include_once functions in PHP.
The following files work just fine:
index.php:-
<?php
include_once 'header.php';
echo 'variable';
header.php:-
<h1>My Page's Header</h1>
But when I try to include the following .php file into my index.php, it does not produce the desired result. The header rather overlaps and thus completely hides the 'variable'
What I want is that after I include the header from an external file, My page should start underneath the header. The header included from external file should not be considered included in my page, so none of the elements are overlapped or such. How can I achieve that?
<!DOCTYPE html>
<html>
<head>
<title>TODO supply a title</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<style>
.top-bar {
position: fixed;
width: 100%;
top: 0px;
left: 0px;
background: #000029;
padding: 5px;
}
.logo {
display: inline-block;
vertical-align: top;
color: white;
}
</style>
</head>
<body>
<div class="top-bar">
<img src="https://www.google.com.pk/images/srpr/logo11w.png" alt="Logo" class="logo" >
</div>
</body>
</html>
<?php
include_once 'header.php';
?>
<div id="parent_div" >
<script>
function getHeaderHeight() {
return document.getElementById("top-bar").height(); //top-bar is in header.php
}
document.getElementById("parent_div").style.padding-top="getHeaderHeight()";
</script>
<h1>Heading</h1>
</div>
That's because your header is set to position: fixed;. It is taken out of the document flow and will follow you as you scroll arround.
When you want it to not stick to the client top, change your css to this:
.top-bar {
position: relative;
background: #000029;
padding: 5px;
}
If you like your header to be fixed, you may also set a padding to the body of the document, that equals the height of your header.
Here you see your current problem: http://jsfiddle.net/Lc3W8/
Solution 1: http://jsfiddle.net/Lc3W8/1/
body
{
margin:0;
padding:0;
height: 3000px;
/*new:*/
padding-top: 30px;
}
.top-bar
{
position: fixed;
left:0;
right:0;
top:0;
height: 30px;
background-color: blue;
}
Solution two: http://jsfiddle.net/Lc3W8/2/
body
{
margin:0;
padding:0;
height: 3000px;
}
.top-bar
{
height: 30px;
background-color: blue;
}

Categories