I want to allow a user to enter a date range and then be able to download an Excel file with data retrieved based on that date range.
Initially I had this working by submitting the form as a GET request for the same page. If the GET params are present the page will retrieve the data and output the needed headers and then the data. I would then exit; from the process to prevent the page from loading (since I had to send the headers with the Excel data).
This works. However I want to include a progress indicator that will go away once the data has been sent. However I cannot find a way to do this.
I can start such an indicator when the form submit button is pressed, but I cannot find a way to turn it off once the document had been output for download.
Ajax does not work in this sort of situation, btw.
Can anyone suggest how to do this? I’ve seen suggestion here on SO about loading the output into a hidden iframe but I do not understand how to do this myself.
Because I have no code on which I could base I will write you the theory mostly.
user requests to download a file
you load a page where inside you are creating the file, the process takes some time, during which you show the user a progress bar.
instead of throwing this file to the user with header function (which you cannot use as you already are printing on the screen) you save the file into a temp directory. preferably call it with a random name, or a timestamp.
by the end of file creation print on the screen a JavaScript command like this:
set the header for the Excel download with something like this:
its always good to clean the things after yourself. be aware that it is possible that something does not get deleted. So preferably you would have a garbage collector anyways. And keep files out of public directories
Obviously, if the data is not sensitive, then you can simply set javascript directly to the file and the browser will download it directly. But then you would need some kind of garbage collector to clean all these files that are created… it would be messy…