I'm using wkhtmltopdf to generate my pdf files. I've left the generation alone for some time and for whatever reason it's not generating the header and footer anymore.
Things I've tried so far (will update this when more answers come in):
Having the doctype, html, head and body tags ion the header and footer
Chaning the paths to the header and footer to absolute paths (Even using complete absolute paths from the drive forward C:/xampp... does not work.) It might be worth pointing out that changing the filename to something that doesn't exist does not throw an error. So I don't know if it finds the files. Maybe someone can tell me a good way to test this?
This is my header file:
<!DOCTYPE html>
<html>
<head>
<title>PDF header</title>
<style>
html {
display: block;
}
body {
font-family: Calibri, "Segoe Ui Regular", sans-serif;
letter-spacing: 0px;
}
</style>
</head>
<body style="padding-top: 30px">
<img src="../../images/logo_extra.jpg" style="width: 100%;"/>
</body>
</html>
This is my main file:
<?php
session_start();
require __DIR__ . '/../vendor/autoload.php';
use Knp\Snappy\Pdf;
$pdf = new Pdf('pdf\wkhtmltopdf\bin\wkhtmltopdf');
header('Content-Type: application/pdf');
// header('Content-Disposition: attachment; filename="offerte.pdf"');
$pdf->setOption('header-html', 'pdf/header.html');
$pdf->setOption('footer-html', 'pdf/footer.html');
$pdf->setOption('load-error-handling','ignore');
// I know there is a 'cover' function in WKHTMLTOPDF
$file = file_get_contents('pdf/cover.php');
echo $pdf->getOutputFromHtml($file);
?>
And as always, please:
Give me an explanation and maybe an example but not just a bunch of working code!
PS: If you see any other mistakes, please let me know.
wkhtmltopdf has an issue with header/cover/footer. I didn't dig into it very deep as adding margins did solve it for me:
<?php
session_start();
require __DIR__ . '/../vendor/autoload.php';
use Knp\Snappy\Pdf;
$pdf = new Pdf('pdf\wkhtmltopdf\bin\wkhtmltopdf');
header('Content-Type: application/pdf');
//just set margins
$pdf->setOption('margin-top', 20);
$pdf->setOption('margin-bottom', 15);
$pdf->setOption('margin-left', '0');
$pdf->setOption('margin-right', '0');
$pdf->setOption('header-html', 'pdf/header.html');
$pdf->setOption('footer-html', 'pdf/footer.html');
$pdf->setOption('load-error-handling','ignore');
$file = file_get_contents('pdf/cover.php');
echo $pdf->getOutputFromHtml($file);
?>
Description
Second problem is weird - nonexisting filename should throw an error. Comment out header and try then with false filename, snappys AbstractGenerator should say something...
Related
I am using Mpdf which is working fine locally, the trouble I am having is that the pdf wont output and just get a blank screen
Here is the error
Fatal error: Uncaught Mpdf\MpdfException: Data has already been sent to output (/customers/3/c/2/includes/header.php at line 14), unable to output PDF file in /customers/3/c/2/pdf/vendor/mpdf/mpdf/src/Mpdf.php:9510 Stack trace: #0 /customers/3/c/2: Mpdf\Mpdf->Output('sold.pdf', 'I') #1 /customers/3/c/2/include('/customers/3/c/...') #2 {main} thrown in /customers/3/c/2/pdf/vendor/mpdf/mpdf/src/Mpdf.php on line 9510
Couple of things I have tried, encoding is correct at UTF and NOT DOM, I have no white space, and everything seems to be ok
This is the header code
<?php
session_start();
if(empty($_SESSION['user_id']))
{
header("Location: https://www.home.co.uk");
}
require '../dbcon/database.php';
$db = DB();
require '../lib/library.php';
$app = new WIDGET();
require '../lib/carbon.php';
$user = $app->UserDetails($_SESSION['user_id']);
?>
I have also tried
<?php
session_start();
require '../dbcon/database.php';
$db = DB();
require '../lib/library.php';
$app = new WIDGET();
require '../lib/carbon.php';
$user = $app->UserDetails($_SESSION['user_id']);
?>
Which has made no difference.
And this is the code in line 9510 of Mdpf.php
case Destination::INLINE:
if (headers_sent($filename, $line)) {
throw new \Mpdf\MpdfException(
sprintf('Data has already been sent to output (%s at line %s), unable to output PDF file', $filename, $line)
);
}
Like mentioned all I am getting is a blank page, if I output to an iframe it works ok.
Works fine on 127.0.0.1
Any help much appreciated and thanks in advance for any help
Update:
Sorry forgot to mention or show the code calling the pdf.
I have already tried ob_clean() and still no go
require_once 'pdf/vendor/autoload.php';
if(ob_get_length() > 0) {
ob_clean();
}
$mpdf = new \Mpdf\Mpdf();
$html ='<html>
<body>
<h2 style="font-size: 120px; text-align:center;">SOLD</h2>
<h2 style="font-size: 50px; text-transform: uppercase; text-align:center;">'. $row->widget_model .'</h2>
<h2 style="font-size: 50px; text-transform: uppercase; text-align:center;">'. $row->widget_serial .'</h2><br>
<h2 style="font-size: 30px; text-transform: uppercase; text-align:center;">Delivery Date: '. (new DateTime($_POST['expdelivery']))->format('d-m-Y') .'</h2>
<br>
<h2 style="font-size: 20px; text-align:center;">Contact: '. $_POST['name'] .'</h2>
</body>
</html>';
$mpdf->WriteHTML($html);
$mpdf->Output('sold.pdf','I');
ob_end_flush();
}
EDIT 2:-
Looking at the network Tab it is just showing all the js calls and favicon.ico
It also shows this page updatewidget.php?id=2178
<?php
$page_title = "Widget Tracker - Amend Widget";
$page = '';
include "includes/header.php";
include "includes/sidebar.php";
$id = isset($_GET['id']) ? $_GET['id'] : NULL;
$sth = $db->prepare("SELECT * FROM `widgettracker` WHERE `id` = :id");
$sth->bindParam(':id', $id, PDO::PARAM_INT);
$sth->setFetchMode(PDO::FETCH_OBJ);
$sth->execute();
$row = $sth->fetch();
?>
<section class="content">
<div class="container-fluid">
<?php
if($row->widgetstatus == "Sold")
{include "sold.php";}
else
{include "widgetdetails.php";}
?>
</div>
</section>
<?php
include "includes/footer.php";
include "includes/customjs.php";
?>
And the page that has the Mpdf on is "widgetdetails.php" I need to insert a Sold date and update and generate the pdf. Then the error
You might have a blank line or newline after the closing ?> in your header file. Try removing the closing ?> from your php files that are not actually outputting anything.
You will want to check the network tab in your developer console. You should be able to see the raw data returned by the server, which should show you whatever data it is sending before it reaches the mpdf code.
My problem is that I cannot access a PHP variable from a CSS file loaded like this from index.php:
<link href="css/style.php" rel="stylesheet">
In the style.php file, I have this:
<?php header("Content-type: text/css; charset: UTF-8");
$myClassName = 'myClass'; ?>
.<?= $myClassName?> {
font-weight: bold;
}
in my index.php I have this:
<span class='<?= $myClassName?>'>this is a text</span>
But $myClassName return an empty string like it doesn exists...it does mean that I cannot access the PHP variable like this....is there someone have maybe a trick..?
I really need to set the css classnames with PHP variables from the css file and be able to get them back to my index.php
Under the header, do $css = $_GET['css']; or replace it with wherever you are initializing the variable from.For example:
<?php
header('Content-Type: text/css');
$css = $_GET['css'];
?>
body {
<?= $css ?>border-radius: 3px
}
I am using HTML2PDF library of PHP to create PDF from HTML. My page url is as below ::
http://domain.com/admin/invoice/invoicedownload
To create pdf using below code ::
ob_start();
$width_in_mm = 240;
$height_in_mm = 250;
$html2pdf = new HTML2PDF('P', array($width_in_mm,$height_in_mm), en, true, 'UTF-8', array(15, 10, 15, 10));
$html2pdf->setDefaultFont('Arial');
$html2pdf->pdf->SetTitle('Invoice Details');
$html2pdf->writeHTML($pdf_template);
$html2pdf->Output($file_name,'I');
die();
This code open pdf view in browser new tab.
Issue I am facing is that that new tab title is set as "Invoice Details - invoicedownload" but I want it as "Invoice Details". Always url's last part is append in title.
Please help me for this.
Thank you in advance.
In order to define your own tab title, you can use the 'embed' html tag.
File n°1 (main):
html, body, embed
{
width: 100%;
height: 100%;
}
body
{
margin: 0;
padding: 0;
}
<!DOCTYPE html>
<html>
<head>
<title>Your title</title>
</head>
<body>
<embed src=/path-to-your-pdf type='application/pdf'/>
</body>
</html>
File n°2 (/path-to-your-pdf):
<?php
$html2pdf = new Html2Pdf('P, 'A4', 'en');
$html2pdf->writeHTML($pdf_template);
$html2pdf->output();
Hope this helps ;)
I have strange problem, I make for example 3 files main.html style.css index.php,
then when I open index.php which read main.html and print to output I get different appearance than when I opening main.html, do you know what I making wrong ?
HTML:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>aa</title>
<link rel="stylesheet" type="text/css" href="style2.css"/>
</head>
<body>
<div id="container">
a
</div>
</body></html>
CSS:
body
{
width: 100%;
padding:0;
margin: 0;
background: #f6f6f6;
}
#container
{
margin: 0 ;
padding: 0;
background: #f6f6f6;
}
PHP:
<?php
$output = file_get_contents("main2.html");
echo $output;
?>
This main2.html
This is index.php
Where you have this:
<?php
$output = file_get_contents("main2.html");
echo $output;
?>
Just simply change to
<?php include ('main2.html');
Use the PHP Require Function.
//PHP
<?php
require 'main.html';
?>
Also you should set the width: 100% on the header not on the body.
http://php.net/manual/en/function.file-get-contents.php
file_get_contents — Reads entire file into a string
http://php.net/manual/en/function.include.php
The include (or require) statement takes all the text/code/markup that exists in the specified file and copies it into the file that uses the include statement.
So better use include or require. Note : I am writing from a mobile that's why it is not so formatted.
I agree with #jordan davis "Also you should set the width: 100% on the header not on the body."
I find solution, i must set php file encoding to ANSI or I set all files encoding UTF-8 without BOM + header('Content-Type: text/html; charset=utf-8'); to php file.
In my last template system I used this function:
private function read_file($filename){
$code = '';
if(file_exists($filename)){
$templatefile = fopen($filename, 'r');
while(!feof($templatefile)){
$code = $code.fgets($templatefile, 1024);
}
fclose($templatefile);
}
return $code;
}
That works perfectly for me. Insted of file_get_content im using fopen to open the File and then with fgets im reading the Content and finally it has to be closed with fclose. See the PHP.net for further Information about the function.
You can also add some Code for a 404 Message if your Template File doesn't exist.
I am using WP 3.5.1, twenty twelve child theme and PHP 5.2 on my server.
I am trying to use a php script(that works on my other websites) in order to get random background-image but it's not working:
CSS:
body {
background: url(<?php include ("bg.php"); echo $selectedBg; ?>) no-repeat fixed;
}
PHP:
<?php
$bg = array('1.jpg','2.jpg','3.jpg','4.jpg','5.jpg');
$i = rand(0, count($bg)-1);
$selectedBg = "$bg[$i]";
?>
my php file is in the same folder as the jpg's.
Any ideas?
No errors. If I use background: url(1.jpg); (instead of php) it works fine but obviously shows 1 image.
Small solution:
We know that he have 5 images on the server:
'1.jpg','2.jpg','3.jpg','4.jpg','5.jpg'
So quick tip:
<body style="background: url('pahttoimages/<?= rand(1, 5) ?>.jpg') no-repeat top center;">
i think the CSS file can't explain your PHP code
try body {
background: url(<?php echo '1.jpg'; ?>) no-repeat fixed;
}
As far as I can see, your code is valid.
Except, you should really write the last line like:
$selectedBg = $bg[$i];
No need for quotes here.
I suspect this is what is causing the error:
my php file is in the same folder as the jpg's. Any ideas?
The background-image needs to be relative to the template-file you are using, not the PHP-file. You script will only work if the images are located in the same folder as the template-slices.
In my WP-installation, I have a template located in /wp-content/themes/mytemplate/ and template-graphics located in /wp-content/themes/mytemplate/images/. If I were to use your script, I would need to preappend /images/ before all the backgrounds in your array.
By the way, you should consider installing Firebug on Firefox and inspect the source. Is the background-name parsed into the template? Does loading the image return a 404 not found-error? Is the location and path correct?
background-image: url(<?php include ("bg.php"); echo $selectedBg; ?>);
background-position: fixed;
background-repeat: no-repeat;
Do this:
// bg.php
<?php
return array(
'1.jpg',
'2.jpg',
'3.jpg'
);
// Wordpress CSS
<?php
$imageUrls = include('bg.php');
$imageUrl = $imageUrls[ array_rand($imageUrls) ];
?>
.someClass {
background-image: url(<?php echo $imageUrl ?>);
}
background: url('<?php $a = array('darkred.jpg','red.gif','pink.png'); echo $a[array_rand($a)];?>');