I am using PhpExcel to create files containing a variable amount of data. Here's how it works :
- The user selects a start date and an end date
- A list of profils is generated
- The user clicks on a button called "To Excel" and a file containing a list of events between the two selected dates for each profil is generated
- When every xlsx file have been created, a zip archive is generated and the usal download window appears
I tested it on FF, Chrome, Opera and IE9 and everything seems to be good. The zip archive is valid and I can extract all the xlsx files which are rightly generated.
Unfortunatly, on IE10, something strange happens: it only works half the time (I tried once, it didn't work. I refreshed. It worked. I refreshed. It didn't work and so on). What happens is that one or more xlsx file is missing. For exemple, I expected to have 16 files and I only received 15.
So I did things like this : when the user hits the "To Excel" button, for each element of the list, an AJAX request is done and calls the "Excel Script"
$.ajax({
type: "GET",
url: "rap_spec_excel_alt.php",
data: "displayFacturation="+displayFacturation+"&startDateRapSpec="+startDate+"&endDateRapSpec="+endDate+"&codeEntSpec="+thisVal+"&delete=0&download=0&nbfiles="+nbFilesExpected,
success: function(data) {
},
error: function() {
}
});
I also test if it the current element is the first or the last element of the list. If it is the first element, in my "Excel Script", I empty the temporary folder containing the old xlsx files. If it is the last element, on success, I call the "Zip Script" like this :
window.open("download_xls_zip.php?nbfiles="+nbFilesExpected);
So, in that way, I have the "confirm download box". My "Excel Script" is huge so I will not post it entirely, but here's a glimpse :
//Delete old files
if ($_GET["delete"] == 1) {
$files = glob('tempxls/*');
foreach($files as $file){
if(is_file($file)) {
unlink($file);
}
}
}
//PHPExcel
include '../libs/pclzip/pclzip.lib.php';
error_reporting(E_ALL);
include '../libs/phpexcel/Classes/PHPExcel.php';
include '../libs/phpexcel/Classes/PHPExcel/Writer/Excel2007.php';
$objPHPExcel = new PHPExcel();
$cacheMethod = PHPExcel_CachedObjectStorageFactory::cache_to_discISAM;
PHPExcel_Settings::setCacheStorageMethod($cacheMethod);
$objPHPExcel->getProperties()->setCreator("John Doe");
$objPHPExcel->getProperties()->setLastModifiedBy("John Doe");
$objPHPExcel->getProperties()->setTitle($year.$month."_".$_GET["codeEntSpec"]);
$objPHPExcel->getProperties()->setSubject("File for ".$_GET["codeEntSpec"]);
$objPHPExcel->getProperties()->setDescription("File for ".$_GET["codeEntSpec"]);
$objPHPExcel->getDefaultStyle()->getFont()->setName('Arial');
$objPHPExcel->getDefaultStyle()->getFont()->setSize(8);
$objPHPExcel->getActiveSheet()->getColumnDimension('A')->setWidth(7.33);
$objPHPExcel->getActiveSheet()->getColumnDimension('B')->setWidth(12);
$objPHPExcel->getActiveSheet()->getColumnDimension('C')->setWidth(8);
$objPHPExcel->getActiveSheet()->getColumnDimension('D')->setWidth(9.33);
$objPHPExcel->getActiveSheet()->getColumnDimension('E')->setWidth(22.67);
$objPHPExcel->getActiveSheet()->getColumnDimension('F')->setWidth(15.67);
$objPHPExcel->getActiveSheet()->getColumnDimension('G')->setWidth(14.67);
$objPHPExcel->getActiveSheet()->getColumnDimension('H')->setWidth(10.83);
$objPHPExcel->getActiveSheet()->getColumnDimension('I')->setWidth(9);
$objPHPExcel->setActiveSheetIndex(0);
//... AND SO ON ...
$objPHPExcel->getActiveSheet()->setTitle("File for ".$_GET["codeEntSpec"]);
$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');
$objWriter->save('tempxls/'.$year.$month.'_'.$_GET["codeEntSpec"].'.xlsx');
When the "Zip Script" is called, it knows how many files should be in the temporary folder. So it waits until every file has arrived and then, the zip archive is created.
//PCLZip
include '../libs/pclzip/pclzip.lib.php';
//Number of files expected
$nbFilesExpected = $_GET["nbfiles"];
$filecount = 0;
//Count the files in the folder
while ($filecount != $nbFilesExpected) {
$dir = 'tempxls';
$i = 0;
if ($handle = opendir($dir)) {
while (($file = readdir($handle)) !== false){
if (!in_array($file, array('.', '..')) && !is_dir($dir.$file))
$i++;
}
}
$filecount = $i;
}
//Zip archive
if ($filecount == $nbFilesExpected) {
$archive = new PclZip('tempzip/archive.zip');
$archive->add('tempxls/');
header("content-type: application/octet-stream");
header("Content-Disposition: attachment; filename=archive.zip");
readfile("tempzip/archive.zip");
flush();
unlink("tempzip/archive.zip");
}
Like I said, everything is good with FF, Chrome, Opera and IE9. The files are there, the zip archive also and the xlsx files are well formated with the right data. But not in IE10...
What I've noticed, it is if I choose a large interval between each date, I have many more data (of course). So, some files are not created because they are to large (I have some limitations on my server) and a fatal error appears. Therefore, the zip archive can't be created because some files are missing.
I thought it could be the answer and I tried to solve the problem with "$cacheMethod" but it didn't work. When the problem appears, I look in the IE10's console but there is nothing (I even installed Firebug on IE...).
Can someone can give me a hand or just explain to me what I do wrong? It would be much apprecietaded! Thank you very much!
EDIT
Here is what I get when I use Firebug on IE10
Headers
ResponseHeaders
> Date Tue, 20 Aug 2013 09:06:37 GMT
> Server Apache
> Expires Thu, 19 Nov 1981 08:52:00 GMT
> Cache-Control no-store, no-cache, must-revalidate, post-check=0, pre-check=0
> Pragma no-cache
> Connection close
> Content-Type text/html
RequestHeaders
> Accept */*
> X-Requested-With XMLHttpRequest
Response
Empty
EDIT 2
It seems to work if I set :
async: false
So, the files are created one after the other. Then, I've got the right number of xlsx files in my zip archive.