You could also use the output buffering functions (starting, reasonably enough I suppose, with [man]ob_start[/man]). Run the same script to produce the invoice in both cases (put it in a separate function, say, and then you can use it for both on-screen and in-email invoice generation). Capture the output into a variable, empty the buffer, turn off buffering, and proceed as normal to produce a visible results.