1

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.

Community
  • 1
  • 1
Lothar
  • 3,409
  • 8
  • 43
  • 58
  • Does the following question useful for you? http://stackoverflow.com/questions/13383144/reading-filesystem-and-returning-it – SaidbakR Dec 13 '12 at 23:23
  • 1
    if you are downloaing a file, there already is an indicator provided by browser. Why would you need another one? Some people have download managers or antiviruses taking care about it.. – MAXIM Dec 13 '12 at 23:25
  • 1
    @sємsєм No. I already have the data returning correctly. I just can't get the progress indicator to quit spinning because once the headers and data are output, the script cannot interact with the page any longer. – Lothar Dec 13 '12 at 23:26
  • @MAXIM The data takes a number of seconds to generate and the page just sits there, empty and static. I want some way to indicate that there is work going on. The browser indicator does do that but users have still complained about thinking it "didn't work". – Lothar Dec 13 '12 at 23:28
  • Then you should rework yuor progress, while generating data do not send headers yet. Show the progress bar and create a temp file. When things are done you show it done and output a JavaScript command to a page which reads the temp file and outputs headers. It will be a quick refresh for the user, but he will see the progress before it starts the download – MAXIM Dec 13 '12 at 23:31
  • Just to summarize that: 1. user requests the download. 2. you prepare the download writing it to a temporary file, while showing the progress bar to the user, since it takes a few seconds. 3. you output a redirect with JavaScript to a pag that reads recently created temporary file sending it as the download with headers – MAXIM Dec 13 '12 at 23:36
  • This sounds like a better approach than what I was trying. Make this an answer and I can accept it (and if you could throw in some code that'd be great... one area I am not sure about is reading the temp file and outputting it correctly for download and also how to know when the file is ready for use) – Lothar Dec 13 '12 at 23:49
  • @Lothar there we go. Hope this helps – MAXIM Dec 14 '12 at 00:46

1 Answers1

2

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:

<script language=”JavaScript”>
self.location=”download.php?file=whatever_you_called_it.xls”;
</script>

set the header for the Excel download with something like this:

header('Content-disposition: attachment; filename=your_excel_file.xls');
header('Content-type: application/xls');
readfile('tmp_dir/whatever_you_called_it.xls');

unlink ('tmp_dir/whatever_you_called_it.xls'); 

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...

MAXIM
  • 1,223
  • 1
  • 9
  • 16