PHP: Adobe Reader can't open PDF files created with mpdf - php

I'm using mpdf to create PDF files on the fly, and the files open fine in a browser but Adobe gives me an error:
Adobe Acrobat Reader DC could not open 'example-filename.pdf'
because it is either not a supported file type or because the file
has been damaged (for example, it was sent as an email attachment
and wasn't correctly decoded).
I looked at other questions about this (another mpdf + adobe error), and checked out the pdf in a text editor. I found that the first part of the file looked like this:
<!DOCTYPE html>
<head>
<title>
CapstoneDB
</title>
%PDF-1.4
%âãÏÓ
After I removed everything up to %PDF-1.4 (including the tab), the file opened fine in Adobe, which is great, except that I need to be able to get the generated pdfs to open in Adobe without manually fiddling with the code every time.
Here's my wrapper function that calls mpdf with the html and css:
include('../mpdf/mpdf.php');
function user_download_pdf($html, $css_file, $filename) {
$mpdf = new mPDF();
$stylesheet = file_get_contents($css_file);
$mpdf->WriteHTML($stylesheet,1);
$mpdf->WriteHTML($html,2);
$mpdf->Output($filename, "D");
}
I never feed mpdf a full html page, usually just an h3 and one or more tables. Maybe I need to be giving mpdf an entire html page, including <head>, <body>, etc? Is there any way to change mpdf configuration or the way I call mpdf in php that would get rid of the html junk at the beginning of the pdf file that's gunking everything up?

Place
ob_clean();
immediately before
$mpdf->Output();
Without this mpdf sometimes includes the website page HTML and not just the HTML that you want in the PDF, probably because headers have already been sent elsewhere in the code. That can mess up your PDF so Adobe won't open it.

Related

mPDF generating blank pdf when importing css

When using PHP 8.1 and mpdf 8.1.2, when generating a PDF, the body of the resulting pdf is empty. While when I just output the HTML used in writehtml, I do get the full content including the css interpreted correctly.
However, when I comment out the <style>{% include '#App/inlineStyles/pdf.css' %}</style> part, it does render the PDF correctly, however (obviously) without the required styling.
I also tried seperately including both using 2 different writeHTML calls (with different modes for css). This resulted in the css not being applied (but the content being written).
The pdf.css file doesn't contain anything weird/invalid. It's partially based on tailwind and generated from .scss files.
I tried new Mpdf(['debug'=>true]) and also tried to catch any mpdfexceptions, but there were none.
Can somebody help me out?
EDIT:
The reason for this happening is within CssManager.php that the entire css gets removed:
// Remove CSS (tags and content), if any
$regexp = '/<style.*?>(.*?)<\/style>/si'; // it can be <style> or <style type="txt/css">
$html = preg_replace($regexp, '', $html);
EDIT2:
How am I supposed to include a file? I think I know the problem; I require the tailwind css component in my .css file which I'm including. The length of my .css file is 38601 lines (1000kb). The problem is in Mpdf/CssManager.php, line 481 (the code above). The return of the preg_replace is null because the file is too long.
In the past (with PHP 7.3 & an older version of mpdf) I did manage to include the tailwind css also into the mpdf writehtml. But in this version it does not work any longer.
My main question is, what is the best way to include the tailwind component? As I'm guessing that the length is what is causing $html to be null and therefore resulting in a blank page
(I'm not sure whether it would still be required to include a file (?))

DOMPDF change the html elements places

I am working with laravael,I have an HTML view that has CSS integrated. I want to convert into a PDF. If I open the view (it doesn't mather if I open it via my Documents or by a link in my app) it works fine, everything looks ok. But if I get that file and generate a PDF with dompdf, when I open it the css for the background and the images are in their places but the texts change places and have another size.
Here is how I convert it to a PDF
$file = file_get_contents("../resources/views/panel/historial/pdfs/otros.html");
$dompdf = new DOMPDF();
$dompdf->loadHtml($file);
//$dompdf->load_html_file($html);
$dompdf->render();
$dompdf->stream("otros.pdf", array("Attachment" => 0));
return $dompdf;
enter image description here
I think that is not working in that way to except then the DOMPDF-Renderer has not the full CSS functionality.
https://github.com/dompdf/dompdf/wiki/CSSCompatibility
Here is a list of elements that are supported. So in your case i would suggest that you render a new template and make it with a different style for your PDF.
Another good solution is wkhtmltopdf which has a better support but is a command line tool which you have to call over php or if you don't need PHP then run it directly from your command line.
https://wkhtmltopdf.org/

Embed the PDF in a webpage without using the built-in PDF viewer

Currently I am using the standard way to embed an pdf to the browser, however, the built-in pdf viewer for my target browser is not working as expected. I would like to force (Chrome, Firefox and IE8 (if possible, but IE9+ is also ok)) to use the adobe reader. The problem is , I can only change this option manually. Is there any way to change the option in HTML/ JS/ PHP ? Thanks.
<OBJECT data="YourFile.pdf" TYPE="application/x-pdf" TITLE="SamplePdf"
WIDTH=200 HEIGHT=100>
shree
</object>
I try to find the solution and someone suggested header, not working unfortunately e.g.
Content-Type: application/pdf
Content-Disposition: inline; filename.pdf
You can use Google PDF viewer to embed pdf files on to your website. Use this link https://docs.google.com/viewer
Example:
<iframe src="https://docs.google.com/viewer?url={HTTP PATH OF THE PDF FILE}&embedded=true" width="600" height="780" style="border: none;"></iframe>
https://docs.google.com/viewer?url=http://research.google.com/archive/bigtable-osdi06.pdf
Check out PDFObject which is a Javascript library to embed PDFs in HTML files. It handles browser compatibility pretty well and will most likely work on IE8.
In your HTML, you could set up a div to display the PDFs:
<div id="pdfRenderer"></div>
Then, you can have Javascript code to embed a PDF in that div:
var pdf = new PDFObject({
url: "https://sample.pdf",
id: "pdfRendered",
pdfOpenParams: {
view: "FitH"
}
}).embed("pdfRenderer");
Cheers
Trick Chrome and Firefox (and maybe other browsers) into displaying the PDFs using the Adobe Reader plugin (for full PDF Open Parameters support among other benefits) by using one of the following 'Adobe PDF in XML Format' types in your embed code:
application/vnd.adobe.pdfxml
application/vnd.adobe.x-mars
This works fine as of my answer today and I'm hopeful it will continue to work fine. I'm using it currently with standard PDF files as a workaround for embedding PDF files in the browser that need to use the Adobe PDF plugin rather than the browser's built-in PDF rendering. Even though my PDF files are standard (non-XML) files, they appear to load just fine with this new application type parameter.
<OBJECT data="YourFile.pdf" TYPE="application/vnd.adobe.pdfxml" TITLE="SamplePdf"
WIDTH=200 HEIGHT=100>
shree
</object>

HTML2PDF generates corrupted file

I'm using HTML2PDF (http://html2pdf.fr/) to generate PDF files from a webpage. However, I'm having a kind of weird error: the generated file can be perfectly shown with the "Preview" Mac tool (or simply touching the space bar when the downloaded PDF file is selected), but when I try to open the file with the Adobe Acrobat Pro, the following error message appears:
Adobe reader could not open "file.pdf" because it is either not a support file type or because the file has been damaged (for example, it was sent as email attachment and was'nt correctly decoded).
Here is how I'm generating the PDF content and the PDF file itself:
$content = '<page backtop="12mm" backbottom="12mm" backleft="8mm" backright="8mm" style="font-size: 10pt;">
<h1>MyTitle</h1>
<br>
<table style="width: 100%;">
<tr>
<td style="width: 25%;"></td>
....
</tr>
</table>
</page>';
$html2pdf = Yii::app()->ePdf->HTML2PDF('P','A4','en',true,'utf-8');
$html2pdf->pdf->SetDisplayMode('fullpage');
$html2pdf->WriteHTML($content);
$html2pdf->Output($outputname , EYiiPdf::OUTPUT_TO_DOWNLOAD );
Any idea on what can be happening? Maybe I'm missing something about the format or the file encoding? I've tried different encodings but nothing seems to solve the problem...
Thanks in advance for your time and effort! :)
Solved! After dealing with this a little bit more, I've decided to open the PDF file with a plain text editor, and I've found that the PHP page used to generate the file included by default a header and a footer (I'm using the Yii Framework), which resulted in "printing" the HTML header and footer code in the PDF file... Is anyone ever has the same problem I had, the way to solve it is to open the page's controller file (in 'protected/controllers/myPageController.php') and change the following line:
$this->render('index');
By this one:
$this->renderPartial('index');
Everything works as expected now! ^_^

How to print the content of an OBJECT element when using the FILE->PRINT menu?

I have a PHP script which displays a PDF inside an object element. Adobe Reader plugins handle this fine and using the Adobe toolbar users can print the embedded PDF. However, some users insist on using the File menu (98% of users on Internet explorer 8) to print the HTML document. Utilizing this File->Print menu in IE, the HTML document is printed out without the contents (PDF) of the OBJECT element. (Print Preview) Using this method to print the document in Chrome or FF results in only the data currently shown in the Object viewport, to be printed. That is, a partial object and not the actual PDF.
I have searched and read a few related questions on StackOverflow, but nothing specific to this situation or case. Some of these 'solutions' use a Javascript method or function to print the content via a button or link. If I can't get my users to use the Adobe toolbar in the browser to print a PDF, I doubt they'll change their minds to use a button that says 'PRINT'.
Why does the File->Print method in IE result in a blank page? Is there a way to make the browser print the contents of an Object element when using the File->Print menu. No JS hacks, buttons, links to 'click here', iframes, or suggestion to 'display it inline' etc.
For reference, the code for this 'View PDF' is below (which, again, works fine to display the PDF content in the object element; no issues).
echo "
<html>
<head>
<title>View PDF</title>
</head>
<body scroll='no'>
<object data='getFile.php?f={$file_hash}' type='application/pdf' width='100%' height='100%' >
<h2>Error: No PDF plugin</h2>
<p>The browser does not have a PDF viewer installed. In order to view the PDF in the browser, please <a href='http://get.adobe.com/reader'>download Adobe Reader</a>. </p>
</object>
</body>
</html>";
As far as I know there is no solution for this issue. I have seen some developers "solving" the problem by generating a PDF file that automatically shows the print dialog when opened
Another option could be to show the PDF file in a new window that removes the toolbar and menus in order to avoid the visual ambiguity.
Window.open(url, "_blank", "location=0,menubar=0,toolbar=0");
I do not know if this one works, but you could try detecting the browser print event, then calling pdfDoc.printAll(); on your Acrobat Reader object.
Open just the PDF - without the HTML & object. Then File->Print will always work.
Of course it depends much more on the browser/reader configuration if the PDF is displayed in the browser or opened in a new Reader window

Categories