MPDF - Full page background based on page orientation - php

I am using MPDF to generate a PDF from some data.
The general flow is as follows: I collect data from a database, I start output buffering, include a template, and clear the buffer and append the HTML to the PDF (calling $mpdf->AddPage when necessary). So far so good.
In my css, I have defined the body to have background-image: url('portrait-bg.png');, which works great.
Now, I want to add some pages that are in landscape format ($mpdf->AddPage(..., 'L');). That works too - but I cannot figure out how to set a different background for those pages (so that the image isn't stretched).
What I've tried:
Setting an image directly on the pdf using $mpdf->Image (doesn't work, it counts as an actual image that content flows around, not as a background).
Putting a tag on the relevant page template, and then specifying a different background in my CSS (doesn't work, shows the original background - in fact, I don't seem to be able to select the body element at all in this manner!)

So after struggling with this for a long time, I was unable to find a good, clean way to do this - presumably due to shortcomings in MPDF.
In any case, the workaround I went with was using a style attribute on each body element that needed a special landscape background. It's not clean, it's not nice - but it seems to be the only way that works, unfortunately. Giving the body a class attribute and defining that in the linked CSS seems not to work (although I can't tell why - the MPDF docs claim to support this functionality, and it is how I set the standard background in the rest of the document).

Related

Make pdf data unselectable via php, converting everything to on image

So I am useing DomPDF to create my document. It draws everything on canvas. I need the resoult data on one page to become one image on this page. Make it unselectable, so it will look like it was scanned rather then created.
Depending on your solution you may want to look at this package spatie/browsershot. It is for Laravel, but you can see it making use of Puppeteer to take html and create either a PDF or an image.
From what I remember DomPDF is using an older rendering engine, where as puppeteer makes use of Google Chromes engine, so can render newer markup. So may even get a better looking result!

Will user custom styling work with document.ready + localStorage?

I run and actively develop a forum (which in itself runs on heavily modified SMF 1.1.16) - one feature I would like to add is the ability for the user to pick custom colours (say 2-4) from a widget in the corner of the page to customize the colours of the forum.
The HTML output of the forum is structured such that modifying the colours can be done with pure CSS, and I'm wondering what the right way to insert this CSS is.
The idea I had was that once the user saves their colour information, a piece of javascript would generate the necessary CSS and save it using HTML5 localStorage (probably using a polyfill library). Then, on $(document).ready(), we check for this CSS being present and if it is, we inject it into the page head.
Is this approach sensible? It's easy to develop, but will it result in a flicker of the usual styling (given that pages are rather heavyweight) before custom styling is applied?
If so, is there a better way to do this completely client-side? I would rather not involve the server if at all possible, but if I must I can just have the server generate CSS files for every user who saves custom styling.
What's the best approach?
I suggest you have a base style for the page first so that there won't be FOUC. Then, have your JS load the custom styles, parse it, and apply it to the page afterwards. You could do a "fade-in change" (like fade in the background etc) so the styles won't load like a snap.
You could also blank the page first, like set the body to display:none, before you load the styles, then after the styles are applied, remove the display:none
You also have to note that local storage has it's size limit. Don't load too much. Consider looking for the LZW compression in JS. It might help.

Export div content to image

Currently I'm working on a project in which user of website can design a giftwall by drag and drop of gifts. Drag, drop and sorting works perfect and I'm able to store generated giftwall into database. On recipient side system lists all the gift images in the same sequence sender sent so it visually looks like a giftwall. I want to allow users to store this giftwall into a single image so they can store their giftwalls into image album. In current system it lists all individual gifts into a individual div resided in main wrapper div. How can I export this wrapper div to image so it looks same as HTML. Any help will really be appreciated. Waiting for reply.
Thanks!
I don't know if there is a way by using pure javascript, but you can generate the image on your server and send it back.
I have never heard of saving browser's viewport to an image file via JS. I think it's only possible vie creating SVG or using HTML5 canvas.
I asked exactly the same thing a while back.
HTML div to screenshot?
The conclusion is... it is not possible with JS. Questionably possible from PHP also.
Use can use an online service for screen capture, like browsershots, but its not in real-time, and doesn't render everything well.
I used a workaround for my situation.
Recreated all the DOM/HTML elements which create the image (load parameters form database, and generate the DOM). Wrap everything in one container div, and zoom it out to the size you need.
I know, not the prettiest solution, but the only solution I could get to work.
Using <canvas> you can create image that will looks similar to how it looks on the page. Try it this way:
Get the size of wrapper <div> and create the same canvas element. Then get the position of each image in the div wrapper and draw that image on canvas at the same position with the same size.
Things may be harder if you need to draw additional controls, like button or textbox.
All modern desktop browsers suport <canvas> now.
You can either use html2canvas, which isn't perfect yet. Or store browser offsets of elements in div and then with GD or ImageMagick combine them into an image
Maybe this could be of use: http://html2canvas.hertzen.com/

dompdf positioning errors

This may have been asked multiple times, but is there a good HTML-to-PDF creator for PHP?
I'm currently using dompdf, and there is a whole list of unsupported things (such as postion:absolute inside a position:relative container, and float:right) which make my PDF render incorrectly.
dompdf forces me to make tables in order to align stuff the way I want. I made an HTML page using floats and relative+absolute positioning, but dompdf ignores this and overlaps all my text and positions them wrong.
It also randomly put a blank 2nd page even though I have both page-break-before and page-break-after set to avoid.
So, can anyone tell me a good PHP PDF creator, or tell me a workaround for dompdf's lack of floats or relative+absolute positioning (I hate tables)?
P.S. I am using dompdf 0.6.0beta1
I just decided to re-write my HTML using tables, so dompdf will render it the way I want. mPDF looked nice, I may switch to that in the future.

Pagination of text from xml file onto html page

O.K. so I'm developing a website to feature my fiction writings. I'm putting all of my documents into XML files, pulling and parsing them from the server with PHP and displaying them on the page. You can visit the page here for an example.
As implied from the background image, What I would like to do is take the text and split it into two columns, (with the text from the first spilling into the second), then allow for the overflow to be paginated so that there is no scrolling necessary. In other words, I'd like for the text to read like a book with the paging based on how long the body of the XML document is.
I would like for this to be done on the server side using PHP or something similar. Is there a way I can do this with an xsl stylesheet or a server-side script? I've been looking everywhere and can't seem to find anything.
Any help is appreciated.
Mr. Mutant
This is a surprisingly hard problem in general, and it's one you'll have no end of trouble with if you try to do it on the server. The problem with paginating HTML text is that where the page breaks go are entirely contingent on the client. The server doesn't know the client's screen resolution, font selection, or window size, and apart from the text itself those are the dependent variables for the problem.
I'd be surprised if at this point there weren't some jQuery library that just does this, but when I had to implement it myself about 7 years ago, here's the approach I took:
Create a div for each column. Each one contains the entirety of the document text. Style the divs with fixed line height. Put the column divs bottom in the document's z-order. Now you can lay out the rest of the page, leaving holes of known size in the layout that the divs can show through, and by manipulating the vertical position of each div you can control which line is the first to appear inside a given hole.
You can then let the client manipulate the font size, and as long as you recalculate the height of the holes and then reposition the divs properly, it will all magically work.
There may be ways of doing this in HTML5 that are easier; I would definitely look into that.

Categories