I created a basic PHP webpage to generate a timesheet of the monthly working hours of employees of a company. The work hours and the other details in the table are to be feeded in JSON format through the an API into the PHP variables which are now set as a dummy associative arrays, containing some random data (I believe that is not relevant to the problem, so enough on this).
I designed the layout by using this helpful tool called Layoutit: https://www.layoutit.com/build
The PHP page I am currently working on would later be embeded within another HTML page and would have a button that will convert it to PDF with the command line utility called wkhtmltopdf. So far so good, I have a working PHP file with foreach cycles that generate the table. After successfully converting my empl_timesheet.php file to PDF with this command wkhtmltopdf http://192.168.64.2/empl_timesheet.php empl_timesheet.pdf
, the table is not resized automatically as I expect and also my paragraphs overflow from their div parent elements.
I am aware my code snippet will not correctly display here on the StackOverflow snippet viewer because it has some PHP in it, so if you want to reproduce the behaviour it is best to clone the repo or copy the contents of the files and run them on a XAMP or similar server. I was doing it with XAMP.
* {
font-family: 'Segoe UI', Tahoma, Verdana, sans-serif;
}
div {
line-height: 0px;
}
/* @page {
size: 21cm 29.7cm;
margin: 30mm 45mm 30mm 45mm;
}
@media print {
body{
line-height: 0px;
width: 21cm;
height: 29.7cm;
margin: 30mm 45mm 30mm 45mm;
background:#f1f2f2;
}
} */
.thetable, .company_header, .signaturearea {
border: 1px solid #323232;
border-radius: 1px 1px 1px 1px;
}
.companyname, .timesheet, .dnplaceholder {
padding-left: 3.5em;
padding-right: 3.5em;
padding-top: 20%;
float: left;
}
.l {
padding: 2em;
margin: 2em;
display: grid;
grid-template-columns: 1fr 1fr 1fr;
grid-template-rows: 1fr 1fr 1fr;
gap: 0px 0px;
grid-auto-flow: row;
grid-template-areas:
"company_header company_header company_header"
"thetable thetable thetable"
"signaturearea signaturearea signaturearea";
}
.company_header {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
grid-template-rows: 1fr 1fr 1fr;
gap: 0px 0px;
grid-auto-flow: row;
grid-template-areas:
". companyname ."
". timesheet ."
"dnplaceholder dnplaceholder .";
grid-area: company_header;
}
.companyname {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
grid-template-rows: 1fr 1fr 1fr;
gap: 0px 0px;
grid-auto-flow: row;
grid-template-areas:
". . ."
". . ."
"companyname companyname companyname";
grid-area: companyname;
}
.companyname {
grid-area: companyname;
}
.timesheet { grid-area: timesheet; }
.dnplaceholder {
display: grid;
grid-template-columns:1fr 1fr 1fr;
grid-template-rows:1fr 1fr 1fr;
gap: 0px 0px;
grid-auto-flow: row;
grid-template-areas:
". date ."
". name ."
". . .";
grid-area: dnplaceholder;
}
.name {
grid-area: name;
}
.date {
grid-area: date;
}
.thetable {
grid-area: thetable;
overflow: auto;
padding: 10%;
}
table {
width: inherit;
}
.signaturearea {
display: grid;
grid-template-columns:0.5fr 0.8fr 1fr;
grid-template-rows:0.2fr 0.2fr 0.2fr;
gap: 0px 0px;
grid-auto-flow: row;
grid-template-areas:
". . ."
". employeesignature ."
". . .";
grid-area: signaturearea;
}
.employeesignature {
grid-area: employeesignature;
display: inline-block;
}
/*
CUSTOM CSS TABLE
ref link: https://dev.to/dcodeyt/creating-beautiful-html-tables-with-css-428l
*/
.thetable {
border-collapse: collapse;
font-size: 100%;
font-family: sans-serif;
box-shadow: 0 0 20px rgba(0, 0, 0, 0.15);
text-align: center;
}
.thetable thead tr {
background-color: #b9b9b9;
color: #ffffff;
border-bottom: 1px solid #b1b1b1;
border-left: 1px solid #b1b1b1;
border-right: 1px solid #b1b1b1;
}
.thetable th,
.thetable td {
padding: 12px 15px;
border-bottom: 1px solid #b1b1b1;
border-left: 1px solid #b1b1b1;
border-right: 1px solid #b1b1b1;
}
.thetable tbody tr {
border-bottom: 1px solid #dddddd;
border-bottom: 1px solid #b1b1b1;
border-left: 1px solid #b1b1b1;
border-right: 1px solid #b1b1b1;
}
.thetable tbody tr:nth-of-type(even) {
background-color: #f3f3f3;
border-bottom: 1px solid #b1b1b1;
border-left: 1px solid #b1b1b1;
border-right: 1px solid #b1b1b1;
}
.thetable tbody tr:last-of-type {
border-bottom: 1px solid #b1b1b1;
border-left: 1px solid #b1b1b1;
border-right: 1px solid #b1b1b1;
}
/*.sum {
color: #009879;
}
*/
#jumbotron {
padding: 6em;
margin: 6em;
box-shadow: 1px #b1b1b1;
box-shadow: rgb(161, 161, 161) 5px 5px 15px 10px;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>timesheet</title>
<meta name="description" content="Source code by Svetlin I.">
<meta name="author" content="Svetlin!">
<!-- <link rel="stylesheet" href="stdz_style.css"> -->
<link rel="stylesheet" href="corner.css">
<link rel="stylesheet" href="timesheet_style.css?v=<?php echo time(); ?>">
</head>
<body>
<!-- JUMBO with shadows -->
<div id="jumbotron">
<!-- .l -->
<div class="l">
<div class="company_header">
<div class="companyname">
<h3>
<!-- Company Name Ltd. -->
</h3>
</div>
<div class="timesheet">
<h4>
Work Hours Timesheet
</h4>
</div>
<div class="dnplaceholder">
<div class="date">
Month: Feb 22
</div>
<div class="name">
Name: Mad Max
</div>
</div>
</div>
<!-- TABLE STYLED WITH CSS -->
<div class="thetable">
<?php
$data = array();
$companyLogo = "https//www.companylogo.xyz/logo";
$month = "February 23";
$name = "Mad Max";
$data[] = ["workStart" => "07:00", "workEnd" => "15:45", "breaks" => "0:45", "actualWorkHours" => "08,00", "placeholder" => "empty", "sick" => "empty", "vaccation" => "empty", "holiday" => "empty", "recordedOn" => "04.02.2022", "remark" => "empty"];
$data[] = ["workStart" => "06:30", "workEnd" => "15:15", "breaks" => "0:45", "actualWorkHours" => "08,00", "placeholder" => "empty", "sick" => "empty", "vaccation" => "empty", "holiday" => "empty", "recordedOn" => "05.02.2022", "remark" => "empty"];
$data[] = ["workStart" => "07:30", "workEnd" => "16:15", "breaks" => "0:45", "actualWorkHours" => "08,00", "placeholder" => "empty", "sick" => "empty", "vaccation" => "empty", "holiday" => "empty", "recordedOn" => "06.02.2022", "remark" => "empty"];
$data[] = ["workStart" => "07:00", "workEnd" => "15:45", "breaks" => "0:45", "actualWorkHours" => "08,00", "placeholder" => "empty", "sick" => "empty", "vaccation" => "empty", "holiday" => "empty", "recordedOn" => "04.02.2022", "remark" => "empty"];
$data[] = ["workStart" => "06:30", "workEnd" => "15:15", "breaks" => "0:45", "actualWorkHours" => "08,00", "placeholder" => "empty", "sick" => "empty", "vaccation" => "empty", "holiday" => "empty", "recordedOn" => "05.02.2022", "remark" => "empty"];
$data[] = ["workStart" => "07:30", "workEnd" => "16:15", "breaks" => "0:45", "actualWorkHours" => "08,00", "placeholder" => "empty", "sick" => "empty", "vaccation" => "empty", "holiday" => "empty", "recordedOn" => "06.02.2022", "remark" => "empty"];
$data[] = ["workStart" => "07:00", "workEnd" => "15:45", "breaks" => "0:45", "actualWorkHours" => "08,00", "placeholder" => "empty", "sick" => "empty", "vaccation" => "empty", "holiday" => "empty", "recordedOn" => "04.02.2022", "remark" => "empty"];
$data[] = ["workStart" => "06:30", "workEnd" => "15:15", "breaks" => "0:45", "actualWorkHours" => "08,00", "placeholder" => "empty", "sick" => "empty", "vaccation" => "empty", "holiday" => "empty", "recordedOn" => "05.02.2022", "remark" => "empty"];
$data[] = ["workStart" => "07:30", "workEnd" => "16:15", "breaks" => "0:45", "actualWorkHours" => "08,00", "placeholder" => "empty", "sick" => "empty", "vaccation" => "empty", "holiday" => "empty", "recordedOn" => "06.02.2022", "remark" => "empty"];
$data[] = ["workStart" => "07:00", "workEnd" => "15:45", "breaks" => "0:45", "actualWorkHours" => "08,00", "placeholder" => "empty", "sick" => "empty", "vaccation" => "empty", "holiday" => "empty", "recordedOn" => "04.02.2022", "remark" => "empty"];
$data[] = ["workStart" => "06:30", "workEnd" => "15:15", "breaks" => "0:45", "actualWorkHours" => "08,00", "placeholder" => "empty", "sick" => "empty", "vaccation" => "empty", "holiday" => "empty", "recordedOn" => "05.02.2022", "remark" => "empty"];
$data[] = ["workStart" => "07:30", "workEnd" => "16:15", "breaks" => "0:45", "actualWorkHours" => "08,00", "placeholder" => "empty", "sick" => "empty", "vaccation" => "empty", "holiday" => "empty", "recordedOn" => "06.02.2022", "remark" => "empty"];
$data[] = ["workStart" => "07:00", "workEnd" => "15:45", "breaks" => "0:45", "actualWorkHours" => "08,00", "placeholder" => "empty", "sick" => "empty", "vaccation" => "empty", "holiday" => "empty", "recordedOn" => "04.02.2022", "remark" => "empty"];
$data[] = ["workStart" => "06:30", "workEnd" => "15:15", "breaks" => "0:45", "actualWorkHours" => "08,00", "placeholder" => "empty", "sick" => "empty", "vaccation" => "empty", "holiday" => "empty", "recordedOn" => "05.02.2022", "remark" => "empty"];
$data[] = ["workStart" => "07:30", "workEnd" => "16:15", "breaks" => "0:45", "actualWorkHours" => "08,00", "placeholder" => "empty", "sick" => "empty", "vaccation" => "empty", "holiday" => "empty", "recordedOn" => "06.02.2022", "remark" => "empty"];
$data[] = ["workStart" => "07:00", "workEnd" => "15:45", "breaks" => "0:45", "actualWorkHours" => "08,00", "placeholder" => "empty", "sick" => "empty", "vaccation" => "empty", "holiday" => "empty", "recordedOn" => "04.02.2022", "remark" => "empty"];
$data[] = ["workStart" => "06:30", "workEnd" => "15:15", "breaks" => "0:45", "actualWorkHours" => "08,00", "placeholder" => "empty", "sick" => "empty", "vaccation" => "empty", "holiday" => "empty", "recordedOn" => "05.02.2022", "remark" => "empty"];
$data[] = ["workStart" => "07:30", "workEnd" => "16:15", "breaks" => "0:45", "actualWorkHours" => "08,00", "placeholder" => "empty", "sick" => "empty", "vaccation" => "empty", "holiday" => "empty", "recordedOn" => "06.02.2022", "remark" => "empty"];
$data[] = ["workStart" => "07:00", "workEnd" => "15:45", "breaks" => "0:45", "actualWorkHours" => "08,00", "placeholder" => "empty", "sick" => "empty", "vaccation" => "empty", "holiday" => "empty", "recordedOn" => "04.02.2022", "remark" => "empty"];
$data[] = ["workStart" => "06:30", "workEnd" => "15:15", "breaks" => "0:45", "actualWorkHours" => "08,00", "placeholder" => "empty", "sick" => "empty", "vaccation" => "empty", "holiday" => "empty", "recordedOn" => "05.02.2022", "remark" => "empty"];
$data[] = ["workStart" => "07:30", "workEnd" => "16:15", "breaks" => "0:45", "actualWorkHours" => "08,00", "placeholder" => "empty", "sick" => "empty", "vaccation" => "empty", "holiday" => "empty", "recordedOn" => "06.02.2022", "remark" => "empty"];
$data[] = ["workStart" => "07:00", "workEnd" => "15:45", "breaks" => "0:45", "actualWorkHours" => "08,00", "placeholder" => "empty", "sick" => "empty", "vaccation" => "empty", "holiday" => "empty", "recordedOn" => "04.02.2022", "remark" => "empty"];
$data[] = ["workStart" => "06:30", "workEnd" => "15:15", "breaks" => "0:45", "actualWorkHours" => "08,00", "placeholder" => "empty", "sick" => "empty", "vaccation" => "empty", "holiday" => "empty", "recordedOn" => "05.02.2022", "remark" => "empty"];
$data[] = ["workStart" => "07:30", "workEnd" => "16:15", "breaks" => "0:45", "actualWorkHours" => "08,00", "placeholder" => "empty", "sick" => "empty", "vaccation" => "empty", "holiday" => "empty", "recordedOn" => "06.02.2022", "remark" => "empty"];
$data[] = ["workStart" => "07:00", "workEnd" => "15:45", "breaks" => "0:45", "actualWorkHours" => "08,00", "placeholder" => "empty", "sick" => "empty", "vaccation" => "empty", "holiday" => "empty", "recordedOn" => "04.02.2022", "remark" => "empty"];
$data[] = ["workStart" => "06:30", "workEnd" => "15:15", "breaks" => "0:45", "actualWorkHours" => "08,00", "placeholder" => "empty", "sick" => "empty", "vaccation" => "empty", "holiday" => "empty", "recordedOn" => "05.02.2022", "remark" => "empty"];
$data[] = ["workStart" => "07:30", "workEnd" => "16:15", "breaks" => "0:45", "actualWorkHours" => "08,00", "placeholder" => "empty", "sick" => "empty", "vaccation" => "empty", "holiday" => "empty", "recordedOn" => "06.02.2022", "remark" => "empty"];
$data[] = ["workStart" => "07:00", "workEnd" => "15:45", "breaks" => "0:45", "actualWorkHours" => "08,00", "placeholder" => "empty", "sick" => "empty", "vaccation" => "empty", "holiday" => "empty", "recordedOn" => "04.02.2022", "remark" => "empty"];
$data[] = ["workStart" => "06:30", "workEnd" => "15:15", "breaks" => "0:45", "actualWorkHours" => "08,00", "placeholder" => "empty", "sick" => "empty", "vaccation" => "empty", "holiday" => "empty", "recordedOn" => "05.02.2022", "remark" => "empty"];
$data[] = ["workStart" => "07:30", "workEnd" => "16:15", "breaks" => "0:45", "actualWorkHours" => "08,00", "placeholder" => "empty", "sick" => "empty", "vaccation" => "empty", "holiday" => "empty", "recordedOn" => "06.02.2022", "remark" => "empty"];
$data[] = ["workStart" => "07:00", "workEnd" => "15:45", "breaks" => "0:45", "actualWorkHours" => "08,00", "placeholder" => "empty", "sick" => "empty", "vaccation" => "empty", "holiday" => "empty", "recordedOn" => "04.02.2022", "remark" => "empty"];
$dataHeader["day"] = "Day";
$dataHeader["workStart"] = "Work start";
$dataHeader["workEnd"] = "Work end";
$dataHeader["breaks"] = "Pause";
$dataHeader["actualWorkHours"] = "Actual Workhours";
$dataHeader["placeholder"] = "Placeholder";
$dataHeader["sick"] = "Sick Leave";
$dataHeader["vaccation"] = "Vaccation";
$dataHeader["holiday"] = "Holiday";
$dataHeader["recordedOn"] = "Recorded on:";
$dataHeader["remark"] = "Remark:";
$listKeys = ["day", "workStart", "workEnd", "breaks", "actualWorkHours", "placeholder", "sick", "vaccation", "holiday", "recordedOn", "remark"];
?>
<div>
<table>
<thead>
<tr>
<?php
foreach($dataHeader as $x => $x_value) {
echo "<th>" . $x_value . "</th>";
}
?>
</tr>
</thead>
<tbody>
<?php
$endday = 31;
$currentDay = 1;
foreach($data as $key=>$row) {
echo "<tr>";
echo "<td>" . $currentDay . "</td>";
foreach($row as $key2=>$row2){
echo "<td>" . $row2 . "</td>";
}
echo "</tr>";
$currentDay += 1;
}
?>
</tbody>
</table>
</div>
</div>
<!-- END TABLE STYLED WITH CSS -->
<!-- EMPLOYEE SIGNATURE -->
<div class="signaturearea">
<div class="employeesignature">
<p>Employee Signature:</p>
<p><br/><br/><br/></p>
<p><br/><br/><br/></p>
<p>__________________________</p>
</div>
</div>
<!-- END EMPLOYEE SIGNATURE -->
</div>
<!-- END .l -->
<!-- END JUMBOTRON with shadows -->
</div>
</body>
</html>
My question is, what is the right way to avoid this unintended behaviour (overflowing divs and paragraphs) while generating the PDFs with wkhtmltopdf? I am referring to the screenshot below which shows what wkhtmltopdf generates for me. As seen there, half of the table is getting cut off.
Using the utility itself to generate PDFs looks pretty straight forward and there are several topics raised here on StackOverflow with various use cases or issues other users before me had. Nevertheless, none of those I found, gave me a clue on how to solve my problem and this is why I decided to raise the topic here.
I have read through numerous articles on Stack, some of them I list here:
Here code snippets are not to be seen and there is no fix mentioned: wkhtmltopdf -> Issue to FIT Html table in A4 (C#)
I seem to have exactly the opposite problem of what Pankaj Pawar has described here as unnecessary blank spaces: wkhtmltopdf | Nested Table HTML to PDF | Blank Space issue
For me the issue is the lack of space to fit the table, so any advice on how to scale down my so-called jumbotron div to be sufficient for properly printing the table are welcome.
Mert has edited his question after a remark that he is missing explanation of the desired behaviour but there is also no answer yet: wkhtmltopdf html table side line
This one is not exactly my case as I already can convert it in A4, just my layout wont be as it is in HTML format: convert html to pdf in a4 size wkhtmltopdf
So to make the desired behaviour clear, there is the screenshot of the printed document which I am aiming my webpage to resemble as closely as possible, translated with Google Lens.
The other StackOverflow articles I have gone through are mostly about version-related issues, so still no luck in finding out a solution there for me.
Something else I have tried but did not work for me is setting the size of the page to be the size of the A4 format:
@page {
size: 21cm 29.7cm;
margin: 30mm 45mm 30mm 45mm;
}
@media print {
body{
line-height: 0px;
width: 21cm;
height: 29.7cm;
margin: 30mm 45mm 30mm 45mm;
background:#f1f2f2;
}
My code snippets you see here are also available on my GitHub profile.