I am trying to display client details as a pdf using dompdf from HTML. Also added a header and footer in the pdf. Some contents in the pdf are displayed under the footer section.
This is the Image of pdf generated, here the data under Other Details are displayed under the footer section. How can change the alignment of content into the next page with a header and footer?
This is the code have written, give a solution
<html>
<head>
<title>Prescription</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<style>
body {
padding: 0;
margin: 0;
font-family: "Times New Roman", Times, serif;
}
header {
position: fixed;
top: 0;
left: 0;
right: 0;
height: 200px;
padding: 10px 50px;
background-color: #ccc;
border-bottom: 1px solid #1f1f1f;
z-index: 1000;
}
.text-center {
text-align: center;
}
.phone {
float: right;
margin-bottom: 10px;
margin-right: 150px;
}
.phone h4 {
text-align: center;
right: 50px;
}
main {
margin-top: 200px;
padding: 10px 50px;
}
.after-header {
height: 30px;
padding: 10px 0;
}
.patient-id {
float: left;
}
.date-day {
float: right;
}
.page-header {
margin-top: 5px;
padding: 5px;
background-color: aqua;
}
.page-header h2 {
font-family: monospace;
font-size: 20px;
text-align: center;
}
footer {
position: fixed;
bottom: 0;
left: 0;
right: 0;
height: 50px;
border-bottom: 1px solid #1f1f1f;
border-top: 1px solid #1f1f1f;
z-index: 1000;
}
footer h3 {
padding-left: 50px;
}
.details {
margin-top: 0;
padding: 2px 0;
}
table {
margin: 5px 0;
width: 100%;
border-top: 1px dotted #1f1f1f;
border-right: 1px dotted #1f1f1f;
}
td {
text-align: justify;
padding: 10px;
border-bottom: 1px dotted #1f1f1f;
border-left: 1px dotted #1f1f1f;
}
table tr>td:first-child {
border-left: none;
}
label {
font-weight: bold;
font-size: 15px;
}
</style>
</head>
<body>
<header>
<div class="text-center">
<h1>SPECIALITY CLINIC</h1>
<h2>xxxxxxxx</sub>
</h2>
<h3>Pediatrition</h3>
</div>
<div class="phone">
<h4>Phone: xxxxx</h4>
</div>
</header>
<footer>
<h3>xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.</h3>
</footer>
<main>
<div class="after-header">
<div class="patient-id">
<h3>Patient Id: 1001</h3>
</div>
<div class="date-day">
<h3>Date: 17/05/2019</h3>
</div>
</div>
<div class="page-header">
<h2>Patient Details</h2>
<hr>
</div>
<div class="details">
<div>
<div style="background-color: #f2f2f2; padding: 5px;">
<h3>General Details</h3>
</div>
</div>
<table>
<col width="10%">
<col width="20%">
<col width="10%">
<col width="10%">
<col width="30%">
<tr>
<td><label>Name:</label></td>
<td colspan="3"><label>Agreesh V S</label></td>
<td rowspan="4"><img src="img.jpg"></td>
</tr>
<tr>
<td><label>Age:</label></td>
<td><label>24</label></td>
<td><label>Gender: </label></td>
<td><label>Male</label></td>
</tr>
<tr>
<td><label>Phone: </label></td>
<td colspan="3"><label>9876543210</label></td>
</tr>
<tr>
<td><label>Email: </label></td>
<td colspan="3"><label>9876543210</label></td>
</tr>
</table>
<div>
<div style="background-color: #f2f2f2; padding: 5px;">
<h3>Personal Details</h3>
</div>
</div>
<table>
<col width="50%">
<col width="50%">
<tr>
<td><label>Date Of Birth:</label></td>
<td colspan="3"><label>18/04/1995</label></td>
</tr>
<tr>
<td><label>Weight</label></td>
<td><label>65 KG</label></td>
</tr>
<tr>
<td><label>Weight at Birth </label></td>
<td colspan="3"><label>2.5 KG</label></td>
</tr>
<tr>
<td><label>Blood Group </label></td>
<td colspan="3"><label>B+ve</label></td>
</tr>
</table>
<div>
<div style="background-color: #f2f2f2; padding: 5px;">
<h3>Other Details</h3>
</div>
</div>
<table>
<col width="50%">
<col width="50%">
<tr>
<td><label>Date Of Birth:</label></td>
<td colspan="3"><label>18/04/1995</label></td>
</tr>
<tr>
<td><label>Weight</label></td>
<td><label>65 KG</label></td>
</tr>
<tr>
<td><label>Weight at Birth </label></td>
<td colspan="3"><label>2.5 KG</label></td>
</tr>
<tr>
<td><label>Blood Group </label></td>
<td colspan="3"><label>B+ve</label></td>
</tr>
</table>
</div>
</main>
</body>
</html>
Keep in mind that when Dompdf positions content it is based on the bounds of the body. If you have a header/footer on the page you need to push it outside the bounds of the body or it will overlap the document content.
A small tweak to your CSS should fix things. First, add a page margin to accommodate your header. Something along the lines of:
#page {
margin: 220px 1in 1in 1in;
}
Then modify the top positioning of your header to push it into that space:
header {
position: fixed;
top: -200px;
left: 0;
right: 0;
height: 200px;
padding: 10px 50px;
background-color: #ccc;
border-bottom: 1px solid #1f1f1f;
z-index: 1000;
}
I am having a php table which contains information about billing of certain numbers. After generating this table I export it in pdf using mpdf.
If the table has a certain number of rows it breaks the page in a weird way, leading the headers repeat on the next page with no rows.
Here is the format of the table:
The table contains up to 3 headers inside <thead> tags, like this:
<table class="items" width="100%" style="font-size: 9pt; border-collapse: collapse;" cellpadding="8">
<thead>
<tr>
<td width="30.3%">Forbrug</td>
<td width="23.1%">Periode</td>
<td width="10.76%">Tid/MB</td>
<td width="9.28%">Enheder</td>
<td width="12.9%" align="right">I alt</td>
<td width="13.3%" align="right">I alt+<b>moms</b></td>
</tr>
</thead>
rows are added in a while from the database in this way.. nothing special
<tr>
<td>'.$produktNameFromDatabase.'</td>
<td>'.$periodeFromDatabase.'</td>
<td>'.$tidMbFromDatabase.'</td>
<td>'.$enhederFromDatabase.'</td>
<td align="right">'.number_format((float)$produktpris, 2, ',', '.').' kr.</td>
<td align="right"><b>'.number_format((float)$produktpris*(1 + (0.25 * $moms)) - $momsDiscount, 2, ',', '.').' kr.</b></td>
</tr>
with the total lines at the end
<tr>
<td class="blanktotal" colspan="1" rowspan="6"></td>
<td class="blanktotal" colspan="1" rowspan="6"></td>
<td class="totals" colspan="2">Subtotal:</td>
<td class="totals" colspan="2">'.number_format((float)$pris1, 2, ',', '.').' kr.</td>
</tr>
<tr>
<td class="totals1" colspan="2">Moms:</td>
<td class="totals1" colspan="2">'.number_format((float)$pris1*(0.25 * $moms) - $momsTotal, 2, ',', '.').' kr.</td>
</tr>
<tr>
<td class="totals1" colspan="2"><b>TOTAL:</b></td>
<td class="totals1" colspan="2"><b>'.number_format((float)$pris1*(1 + (0.25 * $moms)) - $momsTotal, 2, ',', '.').' kr.</b></td>
</tr>
</tbody>
</table>
!!! EVERYTHING that you have seen by now, including the totals are a part of the table!
Here is the mpdf settings that I have:
In PhP:
$mpdf=new mPDF('win-1252','A4','','',20,15,48,25,10,10);
$mpdf->useOnlyCoreFonts = true; // false is default
$mpdf->SetProtection(array('print'));
$mpdf->SetTitle("Suggestive Title");
$mpdf->SetAuthor("Author");
$mpdf->SetWatermarkText("Faktura");
$mpdf->showWatermarkText = true;
$mpdf->watermark_font = 'DejaVuSansCondensed';
$mpdf->watermarkTextAlpha = 0.1;
$mpdf->SetDisplayMode('fullpage');
In HTML:
$html .= '<!--mpdf
<htmlpageheader name="myheader">
<table width="100%"><tr>
<td width="50%" style="color:#000000;">
<span style="font-weight: bold; font-size: 14pt;">
Company Name
</span>
Company Information
</td>
<td width="50%" style="text-align: right;">
<img src="image.jpg" />
Invoice Information <br />Side: {PAGENO} af {nb}
</td>
</tr></table>
</htmlpageheader>
<htmlpagefooter name="myfooter">
<div style="border-top: 1px solid #000000; font-size: 9pt; text-align: center; padding-top: 3mm; ">
Footer Stuff
</div>
<div style="font-size: 9pt; text-align: center;">
Other Footer Stuff
</div>
</htmlpagefooter>
<sethtmlpageheader name="myheader" value="on" show-this-page="1" />
<sethtmlpagefooter name="myfooter" value="on" />
mpdf-->';
Some styling that I use
body {font-family: sans-serif;
font-size: 10pt;
}
p { margin: 0pt;
}
td { vertical-align: top; }
.items td {
border-left: 0.1mm solid #000000;
border-right: 0.1mm solid #000000;
}
table thead td { background-color: #d4ffaa;
border: 0.1mm solid #000000;
}
.items td.blanktotal {
background-color: #FFFFFF;
border: 0mm none #000000;
border-top: 0.1mm solid #000000;
border-right: 0.0mm solid #000000;
}
.items td.totals {
text-align: right;
border-top: 0.1mm solid #000000;
border-right: 0.0mm solid #000000;
border-left: 0.0mm solid #000000;
}
.items td.totals1 {
text-align: right;
border-top: 0.0mm solid #000000;
border-right: 0.0mm solid #000000;
border-left: 0.0mm solid #000000;
}
The result looks something like this:
This issue occurs only when the number of rows fills the page. If it overflows it is no major issue, because the table headers are still there on the next page (all of them unfortunately, not only the last one) and the rest of the rows are added further.
How can I get rid of those empty rows, in this special case?
Thank you!
!!EDIT: Added more information, code and a better image of the case. Sorry for not doing it at the first time!
!!EDIT #2: I just observed on other examples that had more than 1 page of rows that the <thead>s keep their position on next pages. It happens all the time. Is there a way to disable that so that other <thead>s will just continue on the next page from the top of the page without remembering the position from the previous page?
You need to set headers (and footers) in individual strings, like this:
require_once __DIR__ . '/../vendor/autoload.php';
$stylesheet = '
.table-header{
border: none;
background-color: yellow;
width: 100%;
}
.table-header td{
border-right: 1px solid;
}
.table-body{
border: none;
background-color: transparent;
width: 100%;
}
.table-body td{
border-right: 1px solid;
border-bottom: 1px solid;
}
.table-footer{
border: none;
background-color: transparent;
width: 100%;
}
.table-footer .td-number{
text-align: right;
}
';
/* Sample data */
$html = '<table class="table-body">';
for ($i = 1; $i <= 100; $i++) {
$html.='<tr>
<td width="30.3%">Forbrug '.$i.'</td>
<td width="23.1%">Periode '.$i.'</td>
<td width="10.76%">'.$i.' MB</td>
<td width="9.28%">Val '.$i.'</td>
<td width="12.9%" align="right">I alt '.$i.'</td>
<td width="13.3%" align="right"><b>moms</b> '.$i.'</td>
</tr>';
}
$html.= '</table>';
$header = '<table class="table-header"><tr>
<td width="30.3%">Forbrug</td>
<td width="23.1%">Periode</td>
<td width="10.76%">Tid/MB</td>
<td width="9.28%">Enheder</td>
<td width="12.9%" align="right">I alt</td>
<td width="13.3%" align="right">I alt+<b>moms</b></td>
</tr></table>';
$footer = '<table class="table-footer"><tr>
<td>Footer here</td>
<td class="td-number"><b>Page N. {PAGENO}</b></td>
</tr></table>';
$mpdf = new mPDF('c','A4','','',15,15,18,15,10,5);
$mpdf->mirrorMargins = 1;
/* Declare headers */
$mpdf->SetHTMLHeader($header);
$mpdf->SetHTMLHeader($header,'E');
/* Declare footers */
$mpdf->SetHTMLFooter($footer);
$mpdf->SetHTMLFooter($footer,'E');
$mpdf->WriteHTML($stylesheet,1);
$mpdf->WriteHTML($html);
$mpdf->Output();
I eventually found a solution. Best way to get rid of these things is to replace <thead> tags with <th>. <thead> has a predefined style which makes the table header repeat itself on every page. <th> will make the header stop repeating itself on the next pages (fortunate or unfortunate), but it will eliminate the space caused by the <thead>'s style
I'm making a Wordpress module to reserve a room.
Now I use mPDF to create the contracts of the reservations automatically.
mPDF has problems with creating tables with on every row a border line.
When I create the table and view it in html everything looks fine. But when I create a PDF with mPDF the does not show me the row bottom border.
This is the html code that I use to generate the pdf:
.logo
{
display: inline-block;
width: 130;
height: 146;
align: left;
hspace: 12;
}
.headerText
{
display:inline-block;
text-align: right;
float:right;
}
.header{
padding-bottom: 20px;
}
.table{
border-left: thin solid;
border-right: thin solid;
border-bottom: thin solid #000000;
border-top: thin solid;
}
.table{
margin-top: 10px;
margin-bottom: 10px;
border-collapse: collapse;
}
table tr {
border-bottom: 1px solid black;
}
table tr:last-child {
border-bottom: none;
}
.Cell
{
width: 300px;
}
.firstCell
{
border-left: thin;
border-right: thin solid;
border-bottom: thin;
border-top: thin;
}
.smallCell
{
width:150px;
}
.largeCell
{
width: 450px;
}
.row
{
display: block;
}
.koninklijkeLogo
{
width: 30px;
}
.maxSize
{
width: 600px;
}
<table class="table">
<tr class="row">
<td class="smallCell firstCell">Naam:</td>
<td class="largeCell">{%name%}</td>
</tr>
<tr class="row">
<td class="smallCell firstCell">Adres:</td>
<td class="largeCell">{%adres%}</td>
</tr>
<tr class="row">
<td class="smallCell firstCell">Telefoonnummer:</td>
<td class="largeCell">{%phone%}</td>
</tr>
<tr class="row">
<td class="smallCell firstCell">E-mailadres:</td>
<td class="largeCell">{%mail%}</td>
</tr>
</table>
Can I resolve the problem by changing some of my code or is this a bug in mPDF?
From this document, it appears that borders for tr elements are supported by the latest version of mPDF (version 6).
Are you using the latest version?
Maybe you can try to apply a bottom border to the cells only, and not the rows? (Just make sure there are no table cellspacing or td cell margins, or you will see gaps in the borders).
Ok I can display data on to the page from the database but I am having a problem displaying it nicely in a table format so its under headers and gos down the page. This is what has happened at the moment:
Here is my page code:
<link rel="stylesheet" href="css/productiontable.css">
<?php
error_reporting(0);
require './db/connect.php';
include './includes/header.php';
?>
<h2>Productions</h2>
<div class="productiontable">
<table>
<tr>
<th>Production Name</th>
<th>Production Description</th>
<th>Production Type</th>
</tr>
<tr>
<td class="productname">
<?php
if($result = $connection->query("SELECT * FROM Production")){
if($count = $result->num_rows){
while($row = $result->fetch_object()){
echo $row->ProductionName;
?>
</td>
<td class="productinfo">
<?php
echo $row->ProductionInformation;
?>
</td>
<td class="producttype">
<?php
echo $row->ProductionType;
}
?>
</td><bR>
</tr>
</table>
<?php
$result->free();
}
}
mysqli_close($connection);
include './includes/footer.php';
Here is the css for the table:
#import url(http://fonts.googleapis.com/css?family=Dosis);
h2{
text-align: left;
color: white;
font-family: 'Dosis';
margin: 10px;
font-size: 32px;
}
h3{
font-size: 18px;
color: white;
margin: 20px;
}
.productiontable{
width: 900px;
border: 1px black solid;
margin: 10px;
}
.productname{
width: 200px;
float: left;
font-weight: bold;
margin-left: 10px;
}
.productinfo{
width: 500px;
float: left;
margin-left: 10px;
}
.producttype{
width: 200px;
float: left;
font-style: oblique;
margin-left: 10px;
}
Please help as much as possible many thanks :)
There are a couple of things wrong:
1. The br tag is not needed.
2. The loop should be outside of the tr. This way a new row will be made for every row.
I want to show certain <div> on a certain <td> of a table. Here is what I'm trying in HTML:
<table width="100%" cellspacing="0" cellpadding="0" border="0">
<tr>
<td width="10%" valign="middle">{$avatar}{$change_avatar}</td>
<td class="trow1" width="90%" valign="top">
{$online_status}<span class="largetext"><strong>{$formattedname}</strong></span>
<div class="smalltext">{$groupimage}</div>
</td>
</tr>
</table>
On this code, I've this:
$change_avatar = '<div class="change_avatar">Change Avatar</div>';
I want to show {$change_avatar} on mouse hover when mouse comes over to the first <td> of the table, code I showed above.
Here is CSS I used;
.change_avatar{
display: none;
font-size: 11px;
background: #363737;
color: #FFF;
opacity: 0.8;
border-radius: 2px;
padding: 3px 5px;
}
.change_avatar a:link, .change_avatar a:visited, .change_avatar a:active{
color: #FFF !important;
text-decoration: none;
}
td:hover .change_avatar{
display: inline;
margin-top: 50px;
margin-left: -70px;
position: absolute;
}
Please help.
Try this:
CSS:
.change_avatar{
display: none;
font-size: 11px;
background: #363737;
color: #FFF;
opacity: 0.8;
border-radius: 2px;
padding: 3px 5px;
}
.change_avatar a:link, .change_avatar a:visited, .change_avatar a:active{
color: #FFF !important;
text-decoration: none;
}
td #change_avatar:hover .change_avatar{
display: inline;
margin-top: 50px;
margin-left: -70px;
position: absolute;
}
HTML:
<table width="100%" cellspacing="0" cellpadding="0" border="0">
<tr>
<td width="10%" valign="middle" id="change_avatar">{$avatar}{$change_avatar}</td>
<td class="trow1" width="90%" valign="top">
{$online_status}<span class="largetext"><strong>{$formattedname}</strong></span>
<div class="smalltext">{$groupimage}</div>
</td>
</tr>
</table>
you can use JQuery to achieve this. e.g. you td have id="avatarTD"
$("#avatarTD").mouseover(function(){
$(".change_avatar").show();
});
$("#avatarTD").mouseout(function(){
$(".change_avatar").hide();
});