Write a million records into an Excel - php

I tried to write data into excel with a million record using phpExcel. but it take too much time.
$header=array('test1','test1','test1','test1','test1','test1','test1','test1');
$objPHPExcel = new PHPExcel();
// Set document properties
$objPHPExcel->getProperties()->setCreator("Maarten Balliauw")
->setLastModifiedBy("Maarten Balliauw")
->setTitle("Office 2007 XLSX Test Document")
->setSubject("Office 2007 XLSX Test Document")
->setDescription("Test document for Office 2007 XLSX, generated using PHP classes.")
->setKeywords("office 2007 openxml php")
->setCategory("Test result file");
$objPHPExcel->getActiveSheet()->fromArray($header,NULL,'A1');
$sheet = $objPHPExcel->getActiveSheet();
// $final_xls_data1 is set of small records
// $rowcount this variable is set of old rowcounts and set $rowcount=$rowcount +1.
// create 8 small set of records. then add array in excel object
$sheet->fromArray($final_xls_data1,NULL,'A'.$rowcount);
$objPHPExcel->getActiveSheet()->setTitle('Simple');
$objPHPExcel->setActiveSheetIndex(0);
header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
header('Content-Disposition: attachment;filename="01simple.xlsx"');
header('Cache-Control: max-age=0');
header('Cache-Control: max-age=1');
header ('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); // Date in the past
header ('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT'); // always modified
header ('Cache-Control: cache, must-revalidate'); // HTTP/1.1
header ('Pragma: public'); // HTTP/1.0
$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');
$objWriter->save($xls_file_path);
How can I do this?

If you are using PHPExcel, look at this: https://stackoverflow.com/a/5984286/4499987. Mark talks about a bunch of ways to optimize PHPExcel. There are a lot of other posts that you can find help from.
If you really care about speed, I'd also recommend you to take a look at Spout: https://github.com/box/spout. It is super simple to use, does not require any optimizations and should help you create your Excel file in no time!

Related

PHPExcel corrupt file in MS Office Excel 2016

I know PHPExcel is deprecated and replaced with PHPSpreadsheet. I am planning to migrate in the near future but would like to address this problem anyway.
When using MS Office 2016 Office Excel on a Windows 10 Pro environment I get this message:
We found a problem with some content in 'Myfile.xlsx'. Do you want us to try to recover as much as we can?
Click Yes
Microsoft Excel was attempting to open and repair the file. To start this process again, choose Open and Repair from the Open file dialog.
Code works fine using LibreOffice. Also if I open the file in LibreOffice and save it with a different filename then it opens fine in MS Excel. Below is my code snippet, is there anything in this code that would cause this to happen.
Thank you
$filename = "Myfile.xlsx";
$objWriter = PHPExcel_IOFactory::createWriter($this->excel, "Excel2007");
header('Content-Type: application/vnd.ms-excel; charset=UTF-8');
header('Content-Disposition: attachment;filename="'.$filename.'"');
header('Cache-Control: max-age=0');
// If you're serving to IE 9, then the following may be needed
header('Cache-Control: max-age=1');
// If you're serving to IE over SSL, then the following may be needed
header ('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); // Date in the past
header ('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT'); // always modified
header ('Cache-Control: cache, must-revalidate'); // HTTP/1.1
header ('Pragma: public'); // HTTP/1.0
$objWriter->save('php://output');
Edit:
Snippet how rows and columns are built
if($data_type=="float" || $data_type=="decimal" || $data_type=="numeric"){
$this->excel->getActiveSheet()
->getStyle($cell)
->getAlignment()
->setHorizontal(PHPExcel_Style_Alignment::HORIZONTAL_RIGHT);
$this->excel->getActiveSheet()
->setCellValueExplicit($cell, $this_val, PHPExcel_Cell_DataType::TYPE_NUMERIC);
}
else{
$this->excel->getActiveSheet()
->setCellValueExplicit($cell, $this_val, PHPExcel_Cell_DataType::TYPE_STRING);
}
If I change from XLSX to XLS
From this
$filename = "Myfile.xlsx";
$objWriter = PHPExcel_IOFactory::createWriter($this->excel, "Excel2007");
To this
$filename = "Myfile.xls";
$objWriter = PHPExcel_IOFactory::createWriter($this->excel, "Excel5");
It works ok. It only fails if using Excel2007

phpexcel - download file gets corrupted

I am trying to download excel file generated by phpexcel. I am using example "Simple download xlsx" of phpexcel.
I am using same concept given in this SO question.
I am calling php file by POST request from client. Not passing any header. Using below code:
MessageService.invokePostRequest(
"/rest/testphpexcel1.php",
function(returnedResponse){
var data_type = 'application/vnd.ms-excel';
var excelDoc = new Blob([returnedResponse], {
type: data_type
});
var url = window.URL.createObjectURL(excelDoc);
var exportLink = new core.Element('a');
exportLink.setAttribute('href', url);
exportLink.setAttribute('download', this.filename + '.xlsx');
exportLink.trigger('click');
//adding some delay in removing the dynamically created link solved the problem in FireFox
setTimeout(function() {
window.URL.revokeObjectURL(url);
}, 0);
}.bind(this),{data: JSON.stringify(postData)}
Here MessageService.invokePostRequest is a wrapper around ajax.
On server side I've below php code:
// Create new PHPExcel object
$objPHPExcel = new PHPExcel();
// Set document properties
$objPHPExcel->getProperties()->setCreator("Maarten Balliauw")
->setLastModifiedBy("Maarten Balliauw")
->setTitle("Office 2007 XLSX Test Document")
->setSubject("Office 2007 XLSX Test Document")
->setDescription("Test document for Office 2007 XLSX, generated using PHP classes.")
->setKeywords("office 2007 openxml php")
->setCategory("Test result file");
// Add some data
$objPHPExcel->setActiveSheetIndex(0)
->setCellValue('A1', 'Hello')
->setCellValue('B2', 'world!')
->setCellValue('C1', 'Hello')
->setCellValue('D2', 'world!');
// Miscellaneous glyphs, UTF-8
$objPHPExcel->setActiveSheetIndex(0)
->setCellValue('A4', 'Miscellaneous glyphs');
// Rename worksheet
$objPHPExcel->getActiveSheet()->setTitle('Simple');
// Set active sheet index to the first sheet, so Excel opens this as the first sheet
$objPHPExcel->setActiveSheetIndex(0);
// Redirect output to a client’s web browser (Excel2007)
header('Content-Disposition: attachment;filename="01simple.xlsx"');
header('Content-Transfer-Encoding: binary');
header('Cache-Control: must-revalidate');
header('Pragma: public');
$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');
$objWriter->save('php://output');
exit;
Here I tried with Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet on client and server both side.
I am getting below response headers (from chrome's developer tools):
cache-control:must-revalidate
connection:Keep-Alive
content-disposition:attachment;filename="01simple.xlsx"
content-length:6309
content-transfer-encoding:binary
content-type:text/html; charset=UTF-8
date:Fri, 30 Jun 2017 13:51:40 GMT
keep-alive:timeout=5, max=100
pragma:public
server:Apache/2.4.6 (CentOS) PHP/5.4.16
x-powered-by:PHP/5.4.16
From content-length I assume there is some data and in response tab I can see some gibberish text. But that response is not properly converted to excel file, I think.
A file is always getting downloaded and when I open the file, it has text "Unexpected token P in JSON at position 0".
I don't know what am I doing wrong here.
How to download a proper excel file generated by phpexcel ?
Try to use additional headers, it works for me. And try to open by php without js. If php opens correct, try to find error in js script.
header('Content-Type: application/vnd.ms-excel');
header('Content-Disposition:attachment;filename="01simple.xls"');
header('Cache-Control: max-age=0');
header('Cache-Control: max-age=1');
header ('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header ('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT');
header ('Cache-Control: cache, must-revalidate');
header ('Pragma: public');

phpexcel not working in cakephp 1.3

I am trying to create and download excel file using PHPExcel in my CakePHP 1.3 application, But its not working.
My code:-
App::import('Vendor', 'PHPExcel', array('file' => 'Classes/PHPExcel.php'));
$objPHPExcel = new PHPExcel();
// Set document properties
$objPHPExcel->getProperties()->setCreator("Maarten Balliauw")
->setLastModifiedBy("Maarten Balliauw")
->setTitle("Office 2007 XLSX Test Document")
->setSubject("Office 2007 XLSX Test Document")
->setDescription("Test document for Office 2007 XLSX, generated using PHP classes.")
->setKeywords("office 2007 openxml php")
->setCategory("Test result file");
// Add some data
$objPHPExcel->setActiveSheetIndex(0)
->setCellValue('A1', 'Hello')
->setCellValue('B2', 'world!')
->setCellValue('C1', 'Hello')
->setCellValue('D2', 'world!');
// Miscellaneous glyphs, UTF-8
$objPHPExcel->setActiveSheetIndex(0)
->setCellValue('A4', 'Miscellaneous glyphs')
->setCellValue('A5', 'Miscellaneous glyphs');
// Rename worksheet
$objPHPExcel->getActiveSheet()->setTitle('Simple');
// Set active sheet index to the first sheet, so Excel opens this as the first sheet
$objPHPExcel->setActiveSheetIndex(0);
// Redirect output to a client’s web browser (Excel5)
header('Content-Type: application/vnd.ms-excel');
header('Content-Disposition: attachment;filename="01simple.xls"');
header('Cache-Control: max-age=0');
// If you're serving to IE 9, then the following may be needed
header('Cache-Control: max-age=1');
// If you're serving to IE over SSL, then the following may be needed
header ('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); // Date in the past
header ('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT'); // always modified
header ('Cache-Control: cache, must-revalidate'); // HTTP/1.1
header ('Pragma: public'); // HTTP/1.0
$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5');
$objWriter->save('php://output');
exit;
No error is coming while downloading. It just downloading a blank file.
It is working (creating and downloading properly) in core PHP but not working in CakePHP 1.3.
step1: Download from (http://www.codeplex.com/PHPExcel) and place it under app\vendors\Classes. Also make sure you place file containing class PHPExcel out side the directory. so your classes directory will have 1 folder and one file.
step2: create a CSV file in view page in the location views/view_name/csv.
step 3: Inside this folder create a file.
e.g.
<?php
echo "ID, Property ID, Date, Status \n";
foreach($x as $y) {
echo $y['Incident']['id'] . ',';
echo $y['Incident']['name'] . ',';
echo $y['Incident']['date'] .',';
echo $y['Incident']['status'];
echo "\n";
}
Step4: Provide proper link in any view where you are calling.
Use the link:
https://stackoverflow.com/a/37072809/2281448
NB: The above answer is for CakePHP 2.0. But the only difference is in the folder structure which is given below.
Place the folder 'Classes' into your Cakephp folder 'app/vendors/PHPExcel'.

PHPExcel Writes Junk characters when running the code on AWS.

I am facing problem with PHPExcel excel download code.A download code which is working on one server (netcore server) but same set of code not working on AWS server.can any one help me to figure out what could be the exact issue?? following is the phpexcel download code :
error_reporting(E_ALL);
ini_set('display_errors', TRUE);
ini_set('display_startup_errors', TRUE);
date_default_timezone_set('Europe/London');
if (PHP_SAPI == 'cli')
die('This example should only be run from a Web Browser');
/** Include PHPExcel */
require_once '../Classes/PHPExcel.php';
// Create new PHPExcel object
$objPHPExcel = new PHPExcel();
// Set document properties
$objPHPExcel->getProperties()->setCreator("Maarten Balliauw")
->setLastModifiedBy("Maarten Balliauw")
->setTitle("Office 2007 XLSX Test Document")
->setSubject("Office 2007 XLSX Test Document")
->setDescription("Test document for Office 2007 XLSX, generated using PHP classes.")
->setKeywords("office 2007 openxml php")
->setCategory("Test result file");
// Add some data
$objPHPExcel->setActiveSheetIndex(0)
->setCellValue('A1', 'Hello')
->setCellValue('B2', 'world!')
->setCellValue('C1', 'Hello')
->setCellValue('D2', 'world!');
// Miscellaneous glyphs, UTF-8
$objPHPExcel->setActiveSheetIndex(0)
->setCellValue('A4', 'Miscellaneous glyphs')
->setCellValue('A5', 'éàèùâêîôûëïüÿäöüç');
// Rename worksheet
$objPHPExcel->getActiveSheet()->setTitle('Simple');
// Set active sheet index to the first sheet, so Excel opens this as the first sheet
$objPHPExcel->setActiveSheetIndex(0);
// Redirect output to a client’s web browser (Excel5)
header('Content-Type: application/vnd.ms-excel');
header('Content-Disposition: attachment;filename="01simple.xls"');
header('Cache-Control: max-age=0');
// If you're serving to IE 9, then the following may be needed
header('Cache-Control: max-age=1');
// If you're serving to IE over SSL, then the following may be needed
header ('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); // Date in the past
header ('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT'); // always modified
header ('Cache-Control: cache, must-revalidate'); // HTTP/1.1
header ('Pragma: public'); // HTTP/1.0
$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5');
$objWriter->save('php://output');
Excel file is downloaded but with Junk/Un-supported characters
PKU~AG�D�X�[Content_Types].xml��MN�0��"�%nY ��vAa �(0��ؖg�w{&i�#�nbE�{��y��d۸l m�����X�(���)���F��;#1_�����c)j�x/%��E��y� �QĿi!��K�
I ran into this exact problem while doing an xlsx file and found that it was a buffer issue. To solve it I used the php output control function ob_end_clean(); right before save. So in your case it would look like:
$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5');
ob_end_clean();
$objWriter->save('php://output');
I had the same problem.
ob_end_clean(); $objWriter->save('php://output');
This will remove unwanted characters from excel.
I've faced the same problem
you can try this format
require_once './application/Classes/PHPExcel/IOFactory.php';
$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5'); //Excel2007
ob_clean();
header("Content-Type: application/vnd.ms-excel; charset=utf-8");
header("Content-type: application/x-msexcel; charset=utf-8");
header('Content-Disposition: attachment;filename="Filename.xls"');
header("Expires: 0");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Cache-Control: private",false);
$objWriter->save('php://output');

Using PHPExcel to export to xlsx

I am using PHPEXxcel to export an HTML Table generated using MYSQL and its like this.
<?php $query = "SELECT `Firstname`,`Lastname`,`Branch`,`Gender`,`Mobileno`, `Email`
FROM `student_details` WHERE Branch IN ('$branch') and `Year`='$year'
and Tenthresult > '$tenth' and
Twelthresult > '$twelth' and (CGPA > '$cgpa' || CGPA = '$cgpa')";
$result = mysql_query($query);
confirm_query($result);
$objPHPExcel = new PHPExcel();
$objPHPExcel->setActiveSheetIndex(0);
$rowCount = 1;
$objPHPExcel->getActiveSheet()->SetCellValue('A'.$rowCount,'Firstname');
$objPHPExcel->getActiveSheet()->SetCellValue('B'.$rowCount,'Lastname');
$objPHPExcel->getActiveSheet()->SetCellValue('C'.$rowCount,'Branch');
$objPHPExcel->getActiveSheet()->SetCellValue('D'.$rowCount,'Gender');
$objPHPExcel->getActiveSheet()->SetCellValue('E'.$rowCount,'Mobileno');
$objPHPExcel->getActiveSheet()->SetCellValue('F'.$rowCount,'Email');
while($row = mysql_fetch_array($result)){
$rowCount++;
$objPHPExcel->getActiveSheet()->SetCellValue('A'.$rowCount, $row['0']);
$objPHPExcel->getActiveSheet()->SetCellValue('B'.$rowCount, $row['1']);
$objPHPExcel->getActiveSheet()->SetCellValue('C'.$rowCount, $row['2']);
$objPHPExcel->getActiveSheet()->SetCellValue('D'.$rowCount, $row['3']);
$objPHPExcel->getActiveSheet()->SetCellValue('E'.$rowCount, $row['4']);
$objPHPExcel->getActiveSheet()->SetCellValue('F'.$rowCount, $row['5']);
}
$objWriter = new PHPExcel_Writer_Excel2007($objPHPExcel);
$objWriter->save('some_excel_file.xlsx');
?>
Its working but it saves the xlsx file in the root folder without showing to user any signs that its being downloaded.
This code rund when i click a button.now, can i make it to be downloaded like we download a mail attachment and showing the user in the front end that its being downloaded along with the location.
I tried using
header('Content-Type: application/vnd.ms-excel');
header('Content-Disposition: attachment;filename="01simple.xls"');
header('Cache-Control: max-age=0');
With this, i am getting what i wanted above but the xls file downloaded when opened shows
the message
'The File you are trying to open 'filename' is in a different format than the specified extension.....etc.Do you want to open now?
On opening it contains either the entire HTML Page or its simply blank...
Can anybody help me..?
Spreadsheets 101
There are many different spreadsheet file formats, each with their own different filename extensions, and that can be sent to a web browser using different mime types. These are described in the PHPExcel documentation, and each has its own different Writer in PHPExcel. You're mismatching two different formats
BIFF Format
Used by Microsoft Excel between versions 95 and 2003 File
extension: xls
PHPEXcel Writer: PHPExcel_Writer_Excel5
Mime Type: application/vnd.ms-excel
OfficeOpenXML Format
Used by Microsoft Excel since version 2007
File extension: xlsx
PHPEXcel Writer: PHPExcel_Writer_Excel2007
Mime Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
Don't mix and match: if you do, then Excel will (and justifiably) complain. If you want a BIFF file, use PHPExcel's BIFF Writer (Excel5), a file extension of .xls, and the mime type listed above for BIFF Format. If you want an OfficeOpenXML file, then use PHPExcel's Excel2007 Writer, a file extension of .xlsx, and the mime type listed above for OfficeOpenXML.
EDIT
Note that the examples provided with the PHPExcel distribution include 01simple-download-xls.php and 01simple-download-xlsx.php to demonstrate exactly what you want
Just adding those headers only sends those headers. The rest of your code is still the same, so you're saving your xls to your root folder like you used to.
Sending the headers only makes the page you would normally see be send with xls headers. Something which is not what you want, and you're getting your HTML page but with the wrong headers.
What you need to do is send those headers and then stream the xlsx.
Looking at a random thread (I know, bad idea, but this'll get you a headstart on what to do) here, you can find examples like this:
header("Pragma: public");
header("Expires: 0");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Content-Type: application/force-download");
header("Content-Type: application/octet-stream");
header("Content-Type: application/download");;
header("Content-Disposition: attachment;filename=$filename.xls");
header("Content-Transfer-Encoding: binary ");
$objWriter = new PHPExcel_Writer_Excel2007($objPHPExcel);
$objWriter->setOffice2003Compatibility(true);
$objWriter->save('php://output');
I do it with using below snippet.
// Redirect output to a client’s web browser (Excel2007)
header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
header('Content-Disposition: attachment;filename="test_file.xlsx"');
header('Cache-Control: max-age=0');
// If you're serving to IE 9, then the following may be needed
header('Cache-Control: max-age=1');
// If you're serving to IE over SSL, then the following may be needed
header ('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); // Date in the past
header ('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT'); // always modified
header ('Cache-Control: cache, must-revalidate'); // HTTP/1.1
header ('Pragma: public'); // HTTP/1.0
$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');
$objWriter->save('php://output');
try this ..
header('Content-Type: application/vnd.ms-excel');
$filename = "Reports".date("d-m-Y-His").".xls";
header('Content-Disposition: attachment;filename='.$filename .' ');
header('Cache-Control: max-age=0');
$objWriter = \PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5');
$objWriter->save('php://output');

Categories