Easiest (unless generating the CSV would be way too slow, but perhaps not even then) would be to generate the data and output it on the fly.
The client doesn't know where the server is getting its response from, and wouldn't care anyway. So long as you send the right content-type headers to start with, you can generate and output the CSV directly to the client, which will receive it and treat it the way it would any other CSV file quite happily. No need to temporarily save it anywhere.
In short, the page the download link refers to is the script that generates the CSV. And instead of that script saving the CSV, it outputs it.