PHPExcel generating totally jacked up output - php

Greetings,
I am having trouble figuring out how to properly use PHP in general and PHPExcel in particular. I have read multiple posts on this topic and yet I've been running around in circles. Here is the relevant portion of my jacked up code:
$viewinv = mysql_connect($sqlsrv,$username,$password);
if (!$viewinv) { die('Could not connect to SQL server. Contact administrator.'); }
mysql_select_db($database, $viewinv) or die('Could not connect to database. Contact administrator.');
$query = "select unit_id,config,location from inventory;";
$result = mysql_query($query);
if ($result = mysql_query($query) or die(mysql_error())) {
$objPHPExcel = new PHPExcel();
$objPHPExcel->getActiveSheet()->setTitle('blah');
$rowNumber = 1;
$headings = array('Unit ID','Config','Location');
$objPHPExcel->getActiveSheet()->fromArray(array($headings),NULL,'A'.$rowNumber);
$rowNumber++;
while ($row = mysql_fetch_row($result)) {
$col = 'A';
foreach($row as $cell) {
$objPHPExcel->getActiveSheet()->setCellValue($col.$rowNumber,$cell);
$col++;
}
$rowNumber++;
}
$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');
header('Content-Type: application/vnd.ms-excel');
header('Content-Disposition: attachment;filename="myFile.xls"');
header('Cache-Control: max-age=0');
$objWriter->save('php://output');
exit();
}
echo 'a problem has occurred... no data retrieved from the database';
PHPExcel is definitely outputting data from the query, I can see bits and pieces of plaintext, but it is surrounded by a ton of random characters as if though I am looking at the contents of a compressed or compiled piece of data.
For example:
PKâh¿>G’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¦
Any pointers would be extremely appreciated

Your problem is certainly in outputting more content than just Excel data (which is contained in output buffer).
To solve your problem, just call
ob_clean(); //this will clean the output buffer
before sending header.

The problem will likely be resolved by matching the correct writer types to the correct content-types and file extension.
XLSX (office 2007+):
Writer : Excel2007 (PHPExcel_Writer_Excel2007)
Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
XLS (before office 2007):
Writer : Excel5 (PHPExcel_Writer_Excel5)
Content-Type: application/vnd.ms-excel

Related

PHPExcel generatting some random characters?

I have the task of generating the excel sheet of each and every student separately so I used PHPExcel lib to perform the task
<?php
$host='localhost'; $user='root'; $pass=''; $DataBase='college';//define the correct values
// open the connexion to the databases server
$Link=#mysqli_connect($host,$user,$pass,$DataBase) or die('Can\'t connect !');
mysqli_set_charset($Link, 'utf8');//if not by default
//your request
if(isset($_GET['stud_id'])){
$id=$_GET['stud_id'];
$SQL='SELECT * from stud_master where stud_id=$id';
$rs=mysqli_query($Link, $SQL);//get the result (ressource)
/** Include PHPExcel */
require_once 'ec/Classes/PHPExcel.php';//change if necessary
// Create new PHPExcel object
$objPHPExcel = new PHPExcel();
$F=$objPHPExcel->getActiveSheet();
$Line=1;
while($Trs=mysqli_fetch_assoc($rs)){//extract each record
$F->
setCellValue('A'.$Line, $Trs['stud_id'])->
setCellValue('B'.$Line, $Trs['course_id'])->
setCellValue('C'.$Line, $Trs['fname'])->
setCellValue('D'.$Line, $Trs['mname'])->
setCellValue('E'.$Line, $Trs['lname']);//write in the sheet
++$Line;
}
}
// Redirect output to a client’s web browser (Excel5)
header('Content-Type: application/vnd.ms-excel');
header('Content-Disposition: attachment;filename="report.xls"');
header('Cache-Control: max-age=0');
$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5');
$objWriter->save('php://output');
exit;
Seems, the you have an error in your SQL syntax:
//use double quotes here, not single - otherwise $id won't be substituted
$SQL = "SELECT * from stud_master where stud_id=$id";
$rs=mysqli_query($Link, $SQL);//get the result (ressource)
But better use prepared statements to protect from SQL injection.

PHPExcel library hangs with relative "big" files

I'm trying to export some records to excel from my MySQL (webserver) and when the query returns >4k records the script hangs the web browser and temporaly the web hosting.
My PHP_version is 5.2.13-pl1-gentoo and the memory_limit configurated in php.ini is 128M
The result excel only have one column and N rows. With 100 or 200 rows the php script runs fine.
This is the php script
<? session_start();
ini_set('memory_limit', '1024M');
set_time_limit(0);
include("include/conexion.php");
require_once 'include/PHPExcel/Classes/PHPExcel.php';
require_once 'include/PHPExcel/Classes/PHPExcel/IOFactory.php';
$objPHPExcel = new PHPExcel();
$objPHPExcel->getProperties()->setCreator("Name")
->setLastModifiedBy("Name")
->setTitle("Listado")
->setSubject("Listado")
->setDescription("Listado.")
->setKeywords("Listado")
->setCategory("Listado");
$query = explode("|",stripcslashes($_POST['query']));
$objPHPExcel->getActiveSheet()->setTitle('List');
$resEmp = mysql_query ($query, $conexion ) or die(mysql_error());
$tot = mysql_num_rows($resEmp);
$num_fields = mysql_num_fields($resEmp);
$fistIndex = $objPHPExcel->getActiveSheet()->getCellByColumnAndRow(0, 1)->getColumn();
$lastIndex = $objPHPExcel->getActiveSheet()->getCellByColumnAndRow($num_campos - 1, 1)->getColumn();
//tittles
for ($e=0;$e < $num_fields;$e++){
$objPHPExcel->getActiveSheet()->setCellValueByColumnAndRow($e, 2, utf8_decode(ucwords(mysql_field_name($resEmp,$e))));
$objPHPExcel->getActiveSheet()->getColumnDimension($objPHPExcel->getActiveSheet()->getCellByColumnAndRow($e, 2)->getColumn())->setAutoSize(true);
}
//color tittles
$objPHPExcel->getActiveSheet()->getStyle( $fistIndex.'1:'.$lastIndex.'2' )->getFill()->setFillType(PHPExcel_Style_Fill::FILL_SOLID)->getStartColor()->setRGB('c5c5c7');
$objPHPExcel->getActiveSheet()->getStyle( $fistIndex.'1:'.$lastIndex.'2' )->getFont()->setBold(true);
if(isset ( $_POST ['mail'] )){
$objPHPExcel->getActiveSheet()->setCellValueByColumnAndRow(0, 2, "Email");
$emails = array();
for ($row = 0; $row < $totEmp; $row++) {
//more than one mail in field separated by ";"
$aux = explode(";", mysql_result($resEmp,$row,$col));
for($i=0; $i<count($aux); $i++){
$cleaned = utf8_encode(strtolower(trim($aux[$i])));
//filter repeated mails
if(!in_array($cleaned, $emails) && $aux[$i] != ""){
$num_rows = $objPHPExcel->getActiveSheet()->getHighestRow();
$objPHPExcel->getActiveSheet()->insertNewRowBefore($num_rows + 1, 1);
array_push($emails, $cleaned);
$objPHPExcel->getActiveSheet()->setCellValueByColumnAndRow(0, $num_rows + 1, $cleaned);
}
}
}
}
$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');
header('Content-type: application/vnd.ms-excel');
header("Content-Disposition: attachment; filename=".$nom_archivo.".xlsx");
// Write file to the browser
$objWriter->save('php://output');
exit();
?>
When enter to the script run a mysql query and then, iterate the result to get the mail field, if the obtained mail not exist in a array this mail is inserted in excel
I've tried to set
ini_set('memory_limit', '1024M');
set_time_limit(0);
But the problem persist.
Any idea to solve problem?
Thanks a lot
EDIT 1
I've updated the code with the recommendations and now works fine.
Anyway How can I get if occurs any error or the memory usage just before of hanging?
How can I get the max memory_limit available to set with ini_set('memory_limit', '2048M'); ?
<? session_start();
ini_set('memory_limit', '2048M');
set_time_limit(0);
include("include/conexion.php");
require_once 'include/PHPExcel/Classes/PHPExcel.php';
require_once 'include/PHPExcel/Classes/PHPExcel/IOFactory.php';
$objPHPExcel = new PHPExcel();
$objPHPExcel->getProperties()->setCreator("Name")
->setLastModifiedBy("Name")
->setTitle("Listado")
->setSubject("Listado")
->setDescription("Listado.")
->setKeywords("Listado")
->setCategory("Listado");
$activeSheet = $objPHPExcel->getActiveSheet();
$query = explode("|",stripcslashes($_POST['query']));
$activeSheet->setTitle('List');
$resEmp = mysql_query ($query, $conexion ) or die(mysql_error());
$tot = mysql_num_rows($resEmp);
$num_fields = mysql_num_fields($resEmp);
$fistIndex = $activeSheet->getCellByColumnAndRow(0, 1)->getColumn();
$lastIndex = $activeSheet->getCellByColumnAndRow($num_campos - 1, 1)->getColumn();
//tittles
for ($e=0;$e < $num_fields;$e++){
$activeSheet->setCellValueByColumnAndRow($e, 2, utf8_decode(ucwords(mysql_field_name($resEmp,$e))));
$activeSheet->getColumnDimension($activeSheet->getCellByColumnAndRow($e, 2)->getColumn())->setAutoSize(true);
}
//color tittles
$activeSheet->getStyle( $fistIndex.'1:'.$lastIndex.'2' )->getFill()->setFillType(PHPExcel_Style_Fill::FILL_SOLID)->getStartColor()->setRGB('c5c5c7');
$activeSheet->getStyle( $fistIndex.'1:'.$lastIndex.'2' )->getFont()->setBold(true);
if(isset ( $_POST ['mail'] )){
$activeSheet->setCellValueByColumnAndRow(0, 2, "Email");
$emails = array();
for ($row = 0; $row < $totEmp; $row++) {
//more than one mail in field separated by ";"
$aux = explode(";", mysql_result($resEmp,$row,$col));
for($i=0; $i<count($aux); $i++){
$cleaned = utf8_encode(strtolower(trim($aux[$i])));
//filter repeated mails
if(!in_array($cleaned, $emails) && $aux[$i] != ""){
array_push($emails, $cleaned);
}
}
}
for ($row = 0; $row < count($emails); $row++) {
$activeSheet->setCellValueByColumnAndRow(0, $row + 3, $emails[$row]);
}
}
$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');
header('Content-type: application/vnd.ms-excel');
header("Content-Disposition: attachment; filename=".$nom_archivo.".xlsx");
// Write file to the browser
$objWriter->save('php://output');
exit();
?>
Seems this library has serious problem in parsing large excel spreadsheets, I'd this issue already & I couldn't find a proper solution. I guess this is normal behaviour because this library is written fully in PHP that causes a lot of parsing overhead.
I strongly suggest you to use a excel parsing PHP-extension like this one.
As another thinkable solution [if its possible], you can break down your big file to several smaller files (e.g by sheets), otherwise I guess you should use a faster CPU or use another library or programming language to parse your exel files (e.g. apache-poi in java, maybe with a PHP/Java bridge).
Unfortunately, PHPExcel is not good for performing with large data because PHP is not really a good binary file processing language.
Some people export their data to XML format of excel (http://en.wikipedia.org/wiki/Microsoft_Office_XML_formats) and it can work well. However, the xml format does not have full features of excel binary file and of course it will have a bigger file size.
In order to work with the large data (import/export to binary excel file), our system now using libxl which will cost you 199$ for a license, and php_excel which is a wrapper for libxl. In effect, our system now export a excel file with more than 5k of rows in about just only some seconds using libxl and I think it's an only solution for you until now to use binary excel.
P/s: The $objPHPExcel->getActiveSheet() also have a cost, so you could store it value to a variable for reusing later which will help you to speed up your code a little bit.
I had this problem but after changed some options in php.ini and scripts, I could reduce file from 28 MB to 4 MB.
increase memory_limit=2048M in php.ini.
change max_execution_time to more seconds.
in the script yo should use Excel2007 like below:
ob_end_clean();
header('Content-Type: application/vnd.ms-excel');
header("Content-Disposition: attachment;filename=$date.xls");
header('Cache-Control: max-age=0');
ob_end_clean();
$objWriter =PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');
$objWriter->save('php://output');

PHPExcel output to browser not working

I am not really a PHP expert as my past experience is mostly geared towards the system engineering side.
I am facing a problem with PHPExcel which gives me this error "Cannot modify header information - headers already sent by in line 1" when I want to output my XLSX file to the browser.
Here is the sample of my code
$host="localhost";
$uname="lol";
$pass="lol123";
$database = "lol12345";
$table="MemReport";
$table1="CPUReport";
$table2="TrafficReport";
$table3="HDDReport";
// create a file pointer connected to the output stream
$output = fopen('Memory.csv', 'w+');
$output1 = fopen('CPU.csv', 'w+');
$output2 = fopen('Traffic.csv', 'w+');
$output3 = fopen('HDD.csv', 'w+');
// output the column headings
fputcsv($output, array('HostName','Date','Time','Percent','TholdDescription'));
fputcsv($output1, array('HostName','Date','Time','Percent','TholdDescription'));
fputcsv($output2, array('HostName','Date','Time','Percent','TholdDescription'));
fputcsv($output3, array('HostName','Date','Time','Percent','TholdDescription'));
// fetch the data
mysql_connect($host, $uname, $pass);
mysql_select_db($database);
echo mysql_error();
$rows = mysql_query("SELECT * FROM $table order by date ASC, Time ASC");
echo mysql_error();
$rows1 = mysql_query("SELECT * FROM $table1 order by date ASC, Time ASC");
echo mysql_error();
$rows2 = mysql_query("SELECT * FROM $table2 order by date ASC, Time ASC");
echo mysql_error();
$rows3 = mysql_query("SELECT * FROM $table3 order by date ASC, Time ASC");
echo mysql_error();
// loop over the rows, outputting them
while ($row = mysql_fetch_assoc($rows))
fputcsv($output, $row);
while ($row1 = mysql_fetch_assoc($rows1))
fputcsv($output1, $row1);
while ($row2 = mysql_fetch_assoc($rows2))
fputcsv($output2, $row2);
while ($row3 = mysql_fetch_assoc($rows3))
fputcsv($output3, $row3);
include '/tmp/Classes/PHPExcel/IOFactory.php';
$inputFileType = 'CSV';
$inputFileNames = array('HDD.csv','Traffic.csv','CPU.csv','Memory.csv');
$objReader = PHPExcel_IOFactory::createReader($inputFileType);
$inputFileName = array_shift($inputFileNames);
$objPHPExcel = $objReader->load($inputFileName);
$objPHPExcel->getActiveSheet()->setTitle(pathinfo($inputFileName,PATHINFO_BASENAME));
foreach($inputFileNames as $sheet => $inputFileName) {
$objReader->setSheetIndex($sheet+1);
$objReader->loadIntoExisting($inputFileName,$objPHPExcel);
$objReader->loadIntoExisting($inputFileName,$objPHPExcel);
$objPHPExcel->getActiveSheet()->setTitle(pathinfo($inputFileName,PATHINFO_BASENAME));
}
$loadedSheetNames = $objPHPExcel->getSheetNames();
foreach($loadedSheetNames as $sheetIndex => $loadedSheetName) {
$objPHPExcel->setActiveSheetIndexByName($loadedSheetName);
$sheetData = $objPHPExcel->getActiveSheet()->toArray(null,true,true,true);
//var_dump($sheetData);
//var_dump($sheetData);
$myfile = "Report.xlsx";
header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
header("Content-Disposition: attachment;filename=$myfile");
header('Cache-Control: max-age=0');
$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');
$objWriter->save('php://output');
}
any help is appreciated, most of my code has been copy and pasted and then edited to my knowledge, also i was able to get to email the xlsx file but just have problem sending it for download.
I don't mind reading the file from the directory for download.
regards,
Lin
No spaces or tabs, no error messages, no newline characters, no BOM markers, no other output whatsoever.
Note that the error message you're seeing tells you which file/line was responsible for the output headers already sent by xxx in line 1.... so that's where to look.
At line 1 of a file, it's most likely to be something before your opening <?php tag, or a file saved with a BOM header

Exporting data to excel (multiple sheets) using php

I am trying to export data to Excel using this PHP Class, so far things are working fine and the export is being generated. But now I have a new requirement of generating multiple sheets inside a single excel file.
For example if i have two arrays, i want both to be on separate sheets.
$myarray1 = array (
1 => array ("Oliver", "Peter", "Paul"),
array ("Marlene", "Mica", "Lina")
);
$myarray2 = array (
1 => array ("Oliver", "Peter", "Paul"),
array ("Marlene", "Mica", "Lina")
);
At present both arrays are being exported on a single sheet
$xls = new Excel_XML;
$xls->addArray ( $myarray );
$xls->addArray ( $myarray2 );
$xls->generateXML ( "testfile" );
I am wondering if someone tried this before and was able to achieve it and I will appreciate any help I can get on this.
i would suggest you to use PHPExcel library.supports variety of formats, can do visual formatting and is easy to use.
You can find more about it at their webpage: http://phpexcel.codeplex.com/
You can do a lot more of course, reading excel files, setting visual styles, creating plots, expressions and lot more.
you can even use fgetcsv http://php.net/manual/en/function.fgetcsv.php
this example using PHPExcel
function exportToExcelsheets($data, $fileName){
/* Create new PHPExcel object*/
$objPHPExcel = new PHPExcel();
$sheet_index = 0;
foreach ($data as $s=>$sheet){
/* Create a first sheet, representing sales data*/
$alpha = ['A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','V','W','X','Y','Z'];
$objPHPExcel->setActiveSheetIndex($sheet_index);
$head_keys = array_keys($sheet[0]);
foreach ($head_keys as $a=>$headval){
$objPHPExcel->getActiveSheet()->setCellValue($alpha[$a].'1', $headval);
}
$i=2;
foreach($sheet as $row) {
$index = 0;
foreach ($row as $v=>$value){
$value = isset($value)?$value:'';
$objPHPExcel->getActiveSheet()->setCellValue($alpha[$index].$i,$value);
$index++;
}
$i++;
}
/*Rename sheet*/
$objPHPExcel->getActiveSheet()->setTitle('sheet_'.$s);
/* Create a new worksheet, after the default sheet*/
$objPHPExcel->createSheet();
$sheet_index++;
}
/* Redirect output to a client’s web browser (Excel5)*/
header('Content-Type: application/vnd.ms-excel');
header("Content-Disposition: attachment; filename=\"$fileName\"");
header('Cache-Control: max-age=0');
//$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5');
//$objWriter->save('php://output');
$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');
$objWriter->save('php://output');
}

PHPExcel can't generate data from database

When i open the Excel file message appear:
the file you are trying to open, 'filename".xls', is in a different format than specified by the file extension. verify that the fileis not corrupted and is from a trusted source before opening the file."
The output is like this:
ÐÏࡱá;þÿ þÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ
>¶#d‹‹dggÿÿÿÿÿ .....
Here is my code..
<?php
require_once 'database.php';
include 'PHPExcel.php';
$phpExcel = new PHPExcel();
$phpExcel->getActiveSheet()->setTitle("My Sheet");
$phpExcel->setActiveSheetIndex(0)
->setCellValue('A1', 'Name.')
->setCellValue('B1', 'Age');
$qry_table = ("SELECT * FROM MEMBERS");
$inc=2;
while($data_array = mysql_fetch_array($qry_table))
{
$name = $data_array['Name'];
$age = $data_array['Age'];
$$phpExcel->setActiveSheetIndex(0)
->setCellValue('A'.$inc, $name)
->setCellValue('B'.$inc, $age);
$inc++;
}
$phpExcel->setActiveSheetIndex(0);
header("Content-Type: application/vnd.ms-excel");
header("Content-Disposition: attachment; filename=\"filename.xls\"");
header("Cache-Control: max-age=0");
$objWriter = PHPExcel_IOFactory::createWriter($phpExcel, "Excel5");
$objWriter->save("php://output");
exit;
Where's your "mysql_query()" to query the database?
Change
$qry_table = ("SELECT * FROM MEMBERS");
to
$qry_table = mysql_query("SELECT * FROM MEMBERS");
//Edit:
And you've got a pointer ref. to an a variable which does not exsits
Change:
$$phpExcel->setActiveSheetIndex(0)
->setCellValue('A'.$inc, $name)
->setCellValue('B'.$inc, $age);
to:
$phpExcel->setActiveSheetIndex(0)
->setCellValue('A'.$inc, $name);
$phpExcel->setActiveSheetIndex(0)
->setCellValue('B'.$inc, $age);
When you get this error, we always recommend opening the file in a text editor and checking for leading or trailing white spaces (spaces, tabs, newlines), or a BOM marker, or any obvious PHP error messages in plain text in the file.
Try saving the file to your webserver, then opening it and see if the same error occurs

Categories