Generating a PDF with non-printable background - php

In Adobe Acrobat there is an option to add a "background" to a PDF file and set the default settings that this image should be visible when opening the document but should not be printed out. I want to automate the process by a PHP script.
I checked all the popular PHP PDF libs (TCPDF, FPDF, mPDF, ...) but none of them seems to provide such an option. All I found is adding images by the ->Image method and place it behind the text. This does work when viewing the document, but of course it is also printed out.
A second approach is to render plain HTML and include custom stylesheets. I created the simple HTML
<h1>Simple text.</h1>
<div>
<p>Should be printed.
<img src="..."></p>
</div>
<div class="no-print">
<p>Should NOT be printed.
<img src="..."></p>
</div>
and saved the CSS in print.css
.no-print {
display: none;
}
and included it by:
<link rel="stylesheet" media=“print” type="text/css" href="print.css">
The result does not show the second div. I guess the PDF libs do not evaluate the media in the link tag. To be honest this approach does not feel right, especially because PDF !== HTML.
Nevertheless I cannot imagine that this is so difficult. How do all the big companies manage this? I'm grateful for every hint!

Related

How to embed a pdf in HTML and print that with cmd+p / ctrl+p

I am trying to include a pdf file in my HTML page and allow users to print that by using cmd+p or ctrl+p.
Here is my code -
<html>
<body>
<p> I want to print this page with pdf </p>
<iframe src="/my.pdf" width="800px" height="2100px" />
</body>
<html>
When I visit my page I am able to see the pdf file but when I try to print it shows me a blank page for pdf.
I am building this application with PHP. I have tried the embed and object tag also but had no luck with this.
Please help me to fix this.
Such functionality is not possible as explained here: Print Pdf from javascript embed tag
The only real thing you can do is try to convert the PDF to images and use the "#media print" tag to style the printing page appropiately.
It's a different matter
Record it for others.
If there are a lot of blank pages, the class you want to print out:
#media print{
.paper {
display:inline-block
}
}
Apply above CSS. My problem solve by this trick.

SVG icon in twig template

I'm struggling with svg icons. I'm creating menu and to do this I have to use several of svg icons. I already know, that if I want to manipulate colour with help CSS (for example when icon is active/hover) I have to use in HTML <svg> tag not <img src="path-to-icon.svg"/>.
How can I solve this problem in a nice way?
I don't want use full path of svg in my HTML file, because sometimes it is has a hundred of lines d="..." attribute. I try to avoid use <use xlink:href="path-to-icon.svg" /> as well, because is not supported by IE or Edge browsers.
I can add that I use .twig template, so maybe there is a 'PHP' way to add icon.
HTML:
<label id="menuIcon" for="menu" onclick="openNav()">
{# svg icon #}
</label>
CSS
.icon:hover path {
fill: green;
}
I would generate my own font file with all the icons used in the application... just like fontawesome or ionicons.
Please see this Craft Function within Twig it may be useful:
https://craftcms.com/docs/3.x/dev/functions.html#svg
You can also put your code into a .twig template and include that like you would any other twig file.

PHP - Dynamically creating a svg with embedded fonts

I want to dynamically create an svg that I can use in an <img/> tag. This in itself is easy; create an svg, set the header and echo the generated parts in their correct place.
The problem is, I want to be able to embed fonts in the svg.
I've tried using the #font-face rule in the css of the svg, but that didn't work (MDN says that it only works on Android and Safari).
Is there any cross-browser way to do this?
Solutions I've Considered:
Possible Solution #01:
The solution:
In my main file, create an svg file which uses the #font-face css rule, and then use exec() to use inkscape to convert that svg into another svg, which converts all letters into paths. I then could use echo file_get_contents($inkscape_file) with the correct headers to output it as a svg which can be used with an <img/> tag.
The problem with this:
This creates 2 additional files, so seems very inefficient. Furthermore, since each user will end up generating several images, the space it takes up would grow phenomenally.
Possible Solution #02:
The solution:
Make a template in illustrator, then save it as svg, and tick the embed all glyphs option. Then replace the text & the styles with the options from the PHP script. Use the correct header and output this.
The problem with this:
This severely limits the amount of fonts that can be used, as it is limited to only those which I create a template for. My desired behaviour was to add the option for users to upload their own fonts and use them. This solution does not allow for that.
Additional information that may be of some relevance:
My development server runs fedora, and the production server uses redhat.
The #font-face rule I am currently using is as follows:
#font-face {
font-family: Potato;
src: url("/fonts/potato.otf");
}
You can't load any external resources declared in the svg from the <img> tag.
The only solutions would be some crappy ways to append the glyphs or the fonts into the svg file itself.
Actually there is a not so crappy way to do it as you found in this answer by lèse-majesté.
The best way is then still IMO to not use an <img> tag to display the svg documents, but rather use an <iframe> or an <object> tag, with the #font-face declared inside the svg file, or even directly include an inline version into the document. These methods do allow the loading of external resources such as fonts.
Then you just have to save the fonts on your server or just an url to the font in the #font-face declaration.

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

Generate PDF of page using alternate/print stylesheet

I want to generate a PDF of a webpage but apply an alternate, print-type stylesheet to it instead of the styles it uses now. Say, for example, I have a button on http://eorailway.co.uk to generate a PDF of the same page (which is run and administered by me, so therefore I can include any PHP/JS necessary to each page) but I want to apply alternate styling to it before generating the PDF.
At the moment I am using the dompdf PHP library to generate the PDF using the normal/default stylesheet, but cannot for the life of me think how to apply the alternate stylesheet to the page when clicking the "Generate PDF" button.
Any advice is most appreciated.
Since the site is under control, you could dynamically decide which stylesheets to include based on a query string parameter. i.e. http://example.com/page.php?stylesheet=print would have your template output only the alternate stylesheet, and your PDF library would fetch that page to generate.
I would recommend making an alternate page with the "print" stylesheet applied and point to it using the print meta tag. (e.g. <link rel="alternate" media="print" href="<? ECHO $_SERVER['PHP_SELF'].'?print'; ?>""> )
Then have PHP determine the stylesheet to use based on the presence of that GET variable.
You can use the DOMXML stuff in php to apply a specific XSLT file to some XML:
$stylsheet = "Example.xsl";
$xsldoc = domxml_xslt_stylesheet_file($stylsheet);
$htmldoc = $xsldoc->process($xmldoc);
$results_page = $xsldoc->result_dump_mem($htmldoc);
That's something I did in php4, might be an easier way in 5.
In the 0.6.0 release of DOMPDF you can specify the stylesheet to use by modifying the DOMPDF_DEFAULT_MEDIA_TYPE configuration constant.
http://code.google.com/p/dompdf/source/browse/trunk/dompdf/dompdf_config.inc.php?r=336#234

Categories