I'm using wkhtmltopdf to generate my pdf files.
I have main page and footer page that I am rendering. They are in separate view.
Problem with printing it is that just font is loaded and other is not.
I did the main page the same way and all of the css is loaded correctly.
My view of footer.html.twig
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Statement Footer</title>
<link href="https://fonts.googleapis.com/css?family=Courier+Prime&display=swap" rel="stylesheet">
</head>
<style type="text/css">
html {
height: 0;
background-color: white;
white-space: nowrap;
font-family: 'Courier Prime', monospace;
}
hr {
display: block;
height: 1px;
border: 0;
border-top: 1px solid #ccc;
margin: 1em 0;
padding: 0;
}
#footer{
display:table-cell;
width:33.33vw;
text-align: center;
}
</style>
<body>
<hr/>
<div id="footer">
Hello!
</div>
</div>
</body>
</html>
And in my controller:
$options = [
'encoding' => 'UTF-8',
'footer-html' => $footerHtml = $this->renderView('#WebsiteTemplates/invoice/footer.html.twig')
];
$html = $this->renderView('#WebsiteTemplates/invoice/invoice.html.twig');
$filename = sprintf('test-%s.pdf', date('Y-m-d'));
return new Response(
$this->get('knp_snappy.pdf')->getOutputFromHtml($html, $options),
200,
[
'Content-Type' => 'application/pdf',
'Content-Disposition' => sprintf('attachment; filename="%s"', $filename),
]
);
Style tags are good, and I have no css files as assets that I have to include. All of them are directly in a twig.
Related
I'm using Dompdf v2.0.1 to make a report. I'm using a custom font from Google Fonts (Josefin Sans) but the spaces are rendered incorrectly.
But when rendering the page as HTML, spaces are displayed correctly.
Below I'll paste the HTML and PHP code I'm using to generate the PDF.
<!DOCTYPE html>
<html lang="pt-BR">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Josefin+Sans:wght#300;400;700&display=swap" rel="stylesheet">
<title>Relatório de atendimentos</title>
<style>
#page {
margin: 16px;
padding: 0;
}
body {
font-family: 'Josefin Sans', sans-serif;
font-size: .8em;
}
table {
width: 100%;
border-collapse: collapse;
border: none;
}
td, th {
padding: .3em;
}
td {
border: solid 1px #000;
font-weight: 300;
}
.title {
font-size: 1.2em;
color: #FFF;
text-align: center;
background-color: #363435;
border-color: #363435;
}
</style>
</head>
<body>
<table>
<thead>
<tr>
<th class="title">Relatório detalhado de tickets</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<b>GERADO POR: </b> sadsadsad
</td>
</tr>
</tbody>
</table>
</body>
</html>
<?php
declare(strict_types=1);
namespace App\Actions\Report;
use Dompdf\Dompdf;
class GenerateReport
{
public static function run(array $data): string
{
return GenerateReportString::get($data);
$pdf = new Dompdf([
'isRemoteEnabled' => true,
'isJavascriptEnabled' => false,
'dpi' => 200,
]);
$pdf->setPaper('A4', 'landscape');
$pdf->loadHtml(
GenerateReportString::get($data)
);
$pdf->render();
return $pdf->output();
}
}
I tried setting the charset to UTF-8 in the HTTP header (Content-Type: application/pdf; charset=UTF-8), but the result is the same.
This is due to a font subsetting bug in the underlying php-font-lib library, see issue 2445. Not all fonts are impacted, but for those that are you can temporarily work around the issue by disabling subsetting.
$dompdf = new Dompdf(["IsFontSubsettingEnabled" => false]);
Note: This isn't a great solution if the font is large since it will impact the overall PDF size.
ViewBlade
<!doctype html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<style type="text/css" media="all">
.HVMC{font-family: "Herr Von Muellerhoff", cursive !important}
.MDHC{font-family: "Mr De Haviland", cursive !important;}
.ABC{font-family: "Alex Brush", cursive !important;}
.CCC{font-family: "Cedarville Cursive", cursive !important;}
.LBAC{font-family: "La Belle Aurore", cursive !important;}
.img-list {
background-size: contain;
background-position: center;
background-repeat: no-repeat;
position: relative;
width: 100%;
height: 1310px;
}
html,body
{
height: 100%;
margin: 0;
background-color:lightgray;
}
</style>
</head>
<div id="maindiv">
#foreach ($proposalfromTemplate as $proposal)
{!! $proposal->html !!}
#endforeach
<div>
</html>
Controller
PDF::setOptions(['isRemoteEnabled' => TRUE, 'enable_javascript' => TRUE]);
$pdf = PDF::loadView('pdfview');
return $pdf->download($pid . '.pdf');
When I return View It works fine, but when I return $pdf->download() it not including CSS, in Blade file
the given data is a text file which I get from storage so I am not able to add CSS on it
Thanks
You have to render your HTML first before load into DOMPDF
public function generateXYZ()
{
PDF::setOptions(['isRemoteEnabled' => TRUE, 'enable_javascript' => TRUE]);
$dompdf = new Dompdf();
$html = view('your.view.path')->render();
$dompdf->loadHtml($html);
$dompdf->render();
return $pdf->download('card.pdf');
}
I create a pdf in Symfony via snappy from a twig template:
So this is my Controller, where I am creating the pdf:
/**
* #Route("/pdf", name="pdf")
*/
public function pdf(Request $request, Pdf $snappy)
{
$snappy->setOption("encoding","UTF-8");
$html = $this->renderView("default/pdf.html.twig",array(
"title" => "pdf"
));
$filename = "mypdf";
return new Response(
$snappy->getOutputFromHtml($html),
200,
array(
'Content-Type' => 'application/pdf',
'Content-Disposition' => 'inline; filename="'.$filename.'.pdf"'
)
);
}
And here is the html template, where I create the header
pdf.html.twig:
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
* {box-sizing: border-box;}
body {
margin: 0;
font-family: Arial, Helvetica, sans-serif;
}
.header {
overflow: hidden;
background-color: #000;
padding: 20px 10px;
}
.header-right {
float: right;
}
}
</style>
</head>
<body>
<div class="header">
Logo
</div>
<div style="padding-left:20px">
<h1>headline</h1>
<p>Some text</p>
<p>Some content..</p>
</div>
</body>
</html>
I try that the black header fits into the page without border. But there is still a white border. It does not go to the edge.
Change this line
$snappy->setOption("encoding","UTF-8");
into
$snappy->setOption("encoding","UTF-8");
$snappy->setOption('margin-left', '0mm');
$snappy->setOption('margin-right', '0mm');
$snappy->setOption('margin-top', '0mm');
The issue is that wkhtmltopdf defaults to non-zero left & right margins. If you modify your executable to wkhtmltopdf -R 0 -L 0 ... the black will extend to the width of the page. See this.
Btw, you may want to remove the extra brace } at the line immediately above </style>
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.
I'm trying to set up a universal navigation bar. I'm using include to import menu.php into index.php. When I do, it works fine; however, when I add something after the menu.php include, the menu's CSS rules carries on.
index.php
<!DOCTYPE HTML>
<html>
<head>
<link rel=stylesheet href="css/style.css" />
<title>Home | Website</title>
</head>
<body>
<?php include 'menu.php'; ?>
<p>Test</p>
</body>
</html>
menu.php
<head>
<title>Menu | Website</title>
<style>
// menu-only styles...
</style>
</head>
<body>
Home
</body>
<?php return; ?>
You're essentially including an HTML page within an HTML page doing it your way.
To get your CSS to target only your menu, keep it in your style.css file, but make your div have a "menu" class.
Something like this should do what you're looking for, I believe.
index.html
<!DOCTYPE HTML>
<html>
<head>
<link rel=stylesheet href="css/style.css" />
<title>Dare Network | Home</title>
</head>
<body>
<?php include 'menu.php'; ?>
<p>Test</p>
</body>
</html>
style.css
html,body {
padding: 0;
margin: 0;
background-color: #777777;
}
.menu {
/* padding: top&&bottom left&&right; */
padding:10px 0;
background-color: #7786ff;
text-align: center;
}
.menu a {
/* merge transitions into one line to make both functional */
transition: background-color .25s ease-in-out, padding-bottom .25s ease-in-out;
background-color: #b20000;
color: #ffffff;
text-decoration: none;
/* padding:top right bottom left */
padding:10px 10px 5px 10px;
}
.menu a:hover {
background-color: #cc0000;
padding-bottom: 10px;
}
menu.php
<div class="menu">
Home
</div>
This is not a PHP issue
Your CSS in menu.php comes later in the DOM than your actual stylesheet and therefore is being overwritten. Either scope your menu.php styles with some containing element or put your menu CSS code earlier in the DOM (like before style.css)
You are almost a bit closer to what you code. A HTML page can have only one html,head,title,body tag.
Just remove these html,head,title,body tags from menu.php
index.html
<!DOCTYPE HTML>
<html>
<head>
<link rel=stylesheet href="css/style.css" />
<title>Dare Network | Home</title>
</head>
<body>
<?php include 'menu.php'; ?>
<p>Test
</body>
</html>
style.css
html,body {
padding: 0;
margin: 0;
background-color: #777777;
}
menu.php
<style>
body {
padding-top: 10px;
padding-bottom: 10px;
background-color: #7786ff;
text-align: center;
}
a {
transition: background-color .25s ease-in-out;
transition: padding-bottom .25s ease-in-out;
background-color: #b20000;
color: #ffffff;
text-decoration: none;
padding-top: 10px;
padding-right: 10px;
padding-bottom: 5px;
padding-left: 10px;
}
a:hover {
background-color: #cc0000;
padding-bottom: 10px;
}
</style>
Home
<?php return; ?>