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.
Related
I have a problem with letter generating the letter 'N' become become 'ᴉ' (i upside down). I am working Laravel 9 using barryvdh/laravel-dompdf. In pc it is okay but when I open in my iphone (ios 16) I got this problem.
In My controller
public function recreate_card(Student $student){
$students[] = $student;
// return view('templates/student-card', compact('students'));
$pdf = Pdf::loadView('templates/student-card', compact('students'));
return $pdf->stream('student_card.pdf');
}
HTML Template
<!DOCTYPE html>
<html lang="en">
<head>
<title>{{ __('Student Card') }}</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<style type="text/css" media="screen">
html {
font-family: sans-serif;
line-height: 1;
margin: 15mm;
font-size: 1mm;
/* overflow: hidden; */
}
body {
font-family: "Arial (sans-serif)";
font-weight: 400;
line-height: 1.5;
color: #212529;
text-align: left;
background-color: #fff;
font-size: 3mm;
padding-top: 15mm;
}
...
<td class="fw-bold" colspan="2" style="text-align: center; font-size: 3.5mm; color: #014669;">{{ strtoupper($student->first_name).' '.strtoupper($student->last_name) }}</td>
...
Result that I got:
My Expectation: Supposed to be 'BO MATIN'
I found the solution. I change font-family in body from font-family: "Arial (sans-serif)"; to font-family: Arial, sans-serif;
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.
Chinese characters work fine in the HTML page, but when i try to covert HTML to PDF with below code, all Chinese characters got converted to question marks.
I tried to use all types of chinese font libraries but still no success. Please help me fix it.
$html = '<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="Content-Type: application/pdf; charset=utf-8"/>
<link rel="stylesheet" href="style.css">
<div style="width:800px; height:970px; padding:20px; border: 10px solid #787878">
<style>
body {
body {font-family: "simsun"}
}
</style>
<div style="width:750px; height:915px; padding:20px; border: 5px solid #787878">
</br>
<div><img class="imgA1" src="logo.png" ></div>
<!--<img class="imgB1" src="logo.png">-->
</br></br></br></br>
<h6 style="font-size:16px !important; text-align:center;"> <b>'.$goal.'</b></h6><br/><br/>
<b>立約人</b></br></br>
甲方 : <span style="font-size:18px;"><b>'.$user[0]['user_name'].'<b> </span>
<br><br>
乙方 : <span style="font-size:18px;"><b>'.$judge_name.'</b></span><br/><br/>
<b>四. 本合約壹式貳份,雙方各執壹份為憑。</b><br/><br/>
裁判簽名___________________<br/><br/>s中華民國 月 日
</div>
</div></html>';
$dompdf->loadHtml($html);
$dompdf->setPaper('A4', 'landscape');
/* Render the HTML as PDF */
$dompdf->render();
header('Content-Type: application/pdf; charset=utf-8');
header('Content-disposition: inline; filename="' . $no . '.pdf"', true);
/* Output the generated PDF to Browser */
$dompdf->stream();
#font-face {
font-family: 'Firefly Sung';
font-style: normal;
font-weight: 500;
src: url(http://eclecticgeek.com/dompdf/fonts/cjk/fireflysung.ttf)
format('truetype');
}
* {
font-family: Firefly Sung, DejaVu Sans, Verdana, Arial, sans-serif;
}
I am trying to include an external css into my PHP file:
<head>
<link rel="stylesheet" type="text/css" href="css/base.css">
</head>
my CSS File:
.carousel-inner > .item > img,
.carousel-inner > .item > a > img {
width: 100%;
margin: auto;
display: block;
margin-top:50px;
}
body {
font: 20px Montserrat, sans-serif;
line-height: 1.8;
overflow-y:hidden;
}
.container-fluid {
background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAWklEQVQoU2P8P5PhPwMDAwNjOgMjiMYFGIlWiM2E1oMvwbZU24vDbUFYN/P/f4Z0RjAfv0J8DgT5AUM3ksnIejEV4jAZa5B8mhkH9gxf+iIsnkEyiWiF2GwHAGuiJAtmjT1hAAAAAElFTkSuQmCC);
repeat;
position: relative;
padding-bottom: 70px;
}
p{
}
.btn-success {
background-color: #85C1E9;
border:0;
}
.bg-1 {
background-color: #1abc9c; /* Green */
color: #ffffff;
}
.bg-2 {
background-color: #474e5d; /* Dark Blue */
color: #ffffff;
}
.bg-3 {
background-color: #ffffff; /* White */
color: #555555;
}
.navbar {
padding-top: 0px;
padding-bottom: 0px;
border: 0;
border-radius: 0;
margin-bottom: 0;
font-size: 15px;
letter-spacing: 4px;
}
col-sm-4:hover {
color:#85C1E9;
}
.navbar-nav li a:hover {
color: #85C1E9 !important;
}
.helper {
margin:auto;
padding-top: 50px;
}
.col-sm-4:hover {
background:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAcAAAAHCAYAAADEUlfTAAAAJklEQVQYV2OMq7zlw4ADMIIkF7WrbUGX/3+G4f+ASS4MVtuMzcEAiGEnwSwsT0sAAAAASUVORK5CYII=")
repeat;
}
The stylesheet is obviously used, but the plaintext is also seen in the PHP file. If tried adding type or leave it away, href as /css/base.css and without leading /, but somehow I won't get rid of the plain text in my file. Any Idea whats causing it?
The PHP File:
<html>
<head>
<title>Awesome Title</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" type="text/css" href="css/base.css">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<script type="text/javascript" src="/js/my.js"></script>
<script>
...
</script>
<header id="myPage" data-spy="scroll" data-target=".navbar" data-offset="50">
...
</head>
</header>
<body>
..
</body>
EDIT:
Found the error, there was a sneaky include(css/base.css)
I tried to validate your css using the W3 Css validator and it told me there's a parse error in your css. Namely you're closing the background-image: with a semicolon while on the line below theres a repeat;. This is a syntax error, and I think because it can't parse the css, it's just displayed as plain text.
You should know if you want to give styles to php output commands, like echo or print you have to type all of your html codes .
And type your php codes middle of body tags in HTML format . Like this :
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="style.css" />
</head>
<body>
<?php
$text = "Hello World !";
echo "<p>" . $text . "</p>";
?>
</body>
</html>
But another problem that your code has is you typed a header tag inside head tags and close it after head closing tag and this will break the html programming grammar .
This is my php code : That retrieves a table from Mysql and prints it on the page.
Code:
<?php
// Inialize session
session_start();
// Check, if username session is NOT set then this page will jump to login page
if (!isset($_SESSION['username'])) {
header('Location: index.php');
}
?>
<!DOCTYPE HTML>
<html>
<head>
<title>Log in to Intelli-Track</title>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<meta name="description" content="" />
<meta name="keywords" content="" />
<link href="1.css" rel="stylesheet" />
<script src="js/jquery-1.8.3.min.js"></script>
<script src="css/5grid/init.js?use=mobile,desktop,1000px"></script>
<script src="js/init.js"></script>
<noscript>
<link rel="stylesheet" href="css/5grid/core.css" />
<link rel="stylesheet" href="css/style.css" />
<link rel="stylesheet" href="css/tablestyle.css" />
</noscript>
<style type="text/css">
#main {
padding-top: 100px;
padding-left: 55px; }
body
{
line-height: 1.6em;
}
#rounded-corner
{
font-family: "Lucida Sans Unicode", "Lucida Grande", Sans-Serif;
font-size: 12px;
margin: 45px;
width: 480px;
text-align: left;
border-collapse: collapse;
}
#rounded-corner thead th.rounded-company
{
background: #b9c9fe url('table-images/left.png') left -1px no-repeat;
}
#rounded-corner thead th.rounded-q4
{
background: #b9c9fe url('table-images/right.png') right -1px no-repeat;
}
#rounded-corner th
{
padding: 8px;
font-weight: normal;
font-size: 13px;
color: #039;
background: #b9c9fe;
}
#rounded-corner td
{
padding: 8px;
background: #e8edff;
border-top: 1px solid #fff;
color: #669;
}
#rounded-corner tfoot td.rounded-foot-left
{
background: #e8edff url('table-images/botleft.png') left bottom no-repeat;
}
#rounded-corner tfoot td.rounded-foot-right
{
background: #e8edff url('table-images/botright.png') right bottom no-repeat;
}
#rounded-corner tbody tr:hover td
{
background: #d0dafd;
}
</style>
</head>
<body>
<nav id="nav">
<ul>
<li>Home</li>
<li>Map-Mark</li>
<li>Log-Out</li>
<li>Credits</li>
</ul>
</nav>
<html>
<body>
<?php
$hostname = '127.0.0.1:3306';
$dbname = 'mapmark'; // Your database name.
$username = 'root'; // Your database username.
$password = ''; // Your database password. If your database has no password, leave it empty.
mysql_connect($hostname, $username, $password) or DIE('Connection to host is failed, perhaps the service is down!');
mysql_select_db($dbname) or DIE('Database name is not available!');
$query="SELECT * FROM markers";
$result=mysql_query($query);
$fields_num = mysql_num_fields($result);
echo "<div id=tab1 style= width:40%;margin-left:auto;margin-right:auto;position:relative;top:200px;>";
echo "<table id=rounded-corner>";//printing table headers
echo '
<thead>
<tr>
<th scope="col" class="rounded-company">Serial</th>
<th scope="col" class="rounded-q1">Description</th>
<th scope="col" class="rounded-q1">Latitude</th>
<th scope="col" class="rounded-q3">Longitude</th>
</tr>
</thead>';
// printing table rows
while($row = mysql_fetch_row($result))
{
echo "<tr>";
echo "<td>$row[0]</td>";
echo "<td>$row[1]</td>";
echo "<td>$row[2]</td>";
echo "<td>$row[3]</td>";
echo "</tr>\n";
}
echo "</table></div>";
?>
</body>
</html>
Essentially it looks somewhat like this :
What i need is a button on this page, on clicking which The same table would be downloaded as a PDF file.
Any help would be appreciated.
The only viable solution to easily convert html to pdf is by using the domPdf library https://code.google.com/p/dompdf/.
You could add a link to the same page with a ?pdf get parameter and let your php code output through dompdf when $_GET['pdf'] is present instead of echo'ing it out to the browser.
See the wiki for usage:
https://code.google.com/p/dompdf/wiki/Usage
I think in your case the easiest way would be to add:
if ( $_GET['pdf'] ) ob_start();
to the top of your page. (starting an output buffer: see http://php.net/manual/en/function.ob-start.php
and
if ( $_GET['pdf'] ) {
$html = ob_get_contents(); // this fills $html with all your output generated above.
//do the dompdf stuff here , using the $html variable.
}
to the bottom of your page..