phpExcell generating extra worksheets - php

I'm trying to use phpExell in my Zend application to print out a Excel file with multiple work sheets.
In my controller class I have the following global variable...
public $objPHPExcel;
which is initialized in an action function like so...
$this->objPHPExcel = new PHPExcel();
The action then iterates through some database calls, building a report. On each iteration, it calls the following function, passing in the index of the worksheet as an integer, an array of data to be printed out, and a string containing the name of the worksheet.
protected function buildWorksheet($index, $report, $repName) {
//build new worksheet after default
if($index > 0) {
$objWorksheet = $this->objPHPExcel->createSheet();
$this->objPHPExcel->addSheet($objWorksheet);
} else {
$this->objPHPExcel->setActiveSheetIndex($index);
$objWorksheet = $this->objPHPExcel->getActiveSheet();
}
//write the worksheet
$col = 0;
$row = 1;
foreach($report as $entry) {
foreach($entry as $key => $value) {
$objWorksheet->setCellValueByColumnAndRow($col, $row, $value);
$col++;
}
$row++;
$col = 0;
}
$objWorksheet->setTitle($repName);
}
Then, back in the action I print out the excel file...
$objWriter = PHPExcel_IOFactory::createWriter($this->objPHPExcel, 'Excel5');
ob_start();
if ( headers_sent() ) die("**Error: headers sent");
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="simple.xls"');
header("Content-Transfer-Encoding: binary");
ob_clean();
$objWriter->save('php://output');
exit();
When I open the file in Excel, I get the following message...
Excel found unreadable content in 'simple.xls'. Do you want to recover the contents of this workbook?
I click yes. Then get two "Renamed invalid sheet name.' repair error messages. The file contains a worksheet for each iteration, but for everyone after the default sheet, it adds an extra sheet. Why is it creating the extra spreadsheet?

/**
* Create sheet __and add it to this workbook__
*
* #param int|null $iSheetIndex Index where sheet should go (0,1,..., or null for last)
* #return PHPExcel_Worksheet
* #throws Exception
*/
public function createSheet($iSheetIndex = null)

Turns out you don't need the call to addSheet. createSheet() automatically does this for you.
I removed
$this->objPHPExcel->addSheet($objWorksheet);
and it works fine now.

Related

PHPSpreadhseet: Not getting output while export data from my database even not a single error?

I changed my code from PHPexcel to PHPSpreadsheet, every data is dynamic and coming from Mysql but my few data is not exporting even i am not getting any error and Data is showing while i print_r($name1) the variable,
Any help or suggestions is appreciated -
Here is my Converted code -
$inn_table = "";
for($i=0;$i<count($labels);$i++) {
if($result['qualification']['dd1']!="") {
for($j=0;$j<count($dd1);$j++) {
$temp = explode(">",$dd1[$j]);
if($temp[0]==$labels[$i]) {
$name = explode(">",$dd1[$j]);
echo '<pre>';
print_r($name[1]);
$inn_table .= '<td>'.$name[1].'</td>';
}
}
}
echo $inn_table;
Print_r output -
Yes
Category A
Others
TAS
6
How can I export it in excel with help of PHPSpreadheet
simple example -
Check labels
It checks with labels as you can see in my code and put data in the same label column cell as you can see in picture like if it matched with media type the it's print in media type row as you can see in picture
That's a example you can edit (in this example i use composer for install PHPSpreadheet):
require 'DB.php';
require 'vendor/autoload.php';
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Writer\Xlsx as xlsx; // Instead PHPExcel_Writer_Excel2007
use PhpOffice\PhpSpreadsheet\Worksheet\Drawing as drawing; // Instead PHPExcel_Worksheet_Drawing
use PhpOffice\PhpSpreadsheet\IOFactory as io_factory; // Instead PHPExcel_IOFactory
$query = 'SELECT * FROM ? WHERE ?';
$result = $mysqli->query($query);
$objPHPExcel = new Spreadsheet();
$objPHPExcel->setActiveSheetIndex(0);
//NAME WORKSHEET
$objPHPExcel->getActiveSheet()->setTitle("Test");
$objPHPExcel->getActiveSheet()
->getPageSetup()
->setOrientation(PhpOffice\PhpSpreadsheet\Worksheet\PageSetup::ORIENTATION_LANDSCAPE);
$objPHPExcel->getActiveSheet()
->getPageSetup()
->setPaperSize(PhpOffice\PhpSpreadsheet\Worksheet\PageSetup::PAPERSIZE_A4);
$objPHPExcel->getActiveSheet()->SetCellValue('A12', 'ROW1');
$objPHPExcel->getActiveSheet()->SetCellValue('B12', 'ROW2');
$rowCount = 1;
}
while($row = $result->fetch_assoc()){
//BORDER
$objPHPExcel->getActiveSheet()->getStyle('A'.$rowCount)->applyFromArray($styleArray);
$objPHPExcel->getActiveSheet()->getStyle('B'.$rowCount)->applyFromArray($styleArray);
//VALUE
$objPHPExcel->getActiveSheet()->SetCellValue('A'.$rowCount, $row['row1']);
$objPHPExcel->getActiveSheet()->SetCellValue('B'.$rowCount, $row['row2']);
$rowCount++; //ADD COUNT
}
$objWriter = io_factory::createWriter($objPHPExcel, 'Xlsx');
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=EXAMPLE.xlsx");
header("Content-Transfer-Encoding: binary ");
ob_end_clean();
ob_start();
$objWriter->save('php://output');
exit;
Db information and relative query is only example, remember to prepare stmt

Convert csv to xls before streaming to xls

I'm outputting a custom WordPress posttype to CSV. Works fine... Now I have to output to xls... I want to use PHPExcel... I have no idea how to implement this because my code streams a (csv) file. How can I convert the csv and stream the resulting xls... My code so far:
// create a new array of values that reorganizes them in a new multidimensional array where each sub-array contains all of the values for one custom post instance
$ccsve_generate_value_arr_new = array();
foreach($ccsve_generate_value_arr as $value) {
$i = 0;
while ($i <= ($ccsve_count_posts-1)) {
$ccsve_generate_value_arr_new[$i][] = $value[$i];
$i++;
}
}
// build a filename
// $ccsve_generate_csv_filename = $ccsve_generate_post_type.'-'.date('Ymd_His').'-export.csv';
$ccsve_generate_csv_filename = 'WPhonden.csv';
//output the headers for the CSV file
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header('Content-Description: File Transfer');
header("Content-type: text/csv");
header("Content-Disposition: attachment; filename={$ccsve_generate_csv_filename}");
header("Expires: 0");
header("Pragma: public");
//open the file stream
$fh = #fopen( 'php://output', 'w' );
$headerDisplayed = false;
foreach ( $ccsve_generate_value_arr_new as $data ) {
// Add a header row if it hasn't been added yet -- using custom field keys from first array
if ( !$headerDisplayed ) {
fputcsv($fh, array_keys($ccsve_generate_value_arr));
$headerDisplayed = true;
}
// Put the data from the new multi-dimensional array into the stream
fputcsv($fh, $data);
}
// Close the file stream
fclose($fh);
// Make sure nothing else is sent, our file is done
exit;
}
Here is the PHPExcel code:
include 'PHPExcel/IOFactory.php';
$objReader = PHPExcel_IOFactory::createReader('CSV');
// If the files uses a delimiter other than a comma (e.g. a tab), then tell the reader
$objReader->setDelimiter("\t");
// If the files uses an encoding other than UTF-8 or ASCII, then tell the reader
$objReader->setInputEncoding('UTF-16LE');
$objPHPExcel = $objReader->load('MyCSVFile.csv');
$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5');
$objWriter->save('MyExcelFile.xls');

Why the extra information getting added to the Excel file which is to be downloaded using PHP headers?

I'm writing PHP array data to the excel file using some library. When I write the data to the excel file and echo some success message, it works fine. No other data than the intended array gets added to the file.
But when I use headers to make the download of same file functionality workable some additional information present on page (like header menu, some heading, copyright line at bottom of page, etc.)gets added to the file. How to avoid adding this extra information to the excel file? Following is my code:
<?php
require_once( CORE_PATH."/libs/excelwriter.inc.php" );
$objRebateReports = new RebateReports();
if($_POST['btnDownload']!='') {
$rebate_ret = $objRebateReports->GetRebateReport($_POST);
$rebate_data = $objRebateReports->GetResponse();
$t=time();
$fileName = ADMIN_ROOT."modules/rebates/rebate_report_".$t.".xls";
$excel = new ExcelWriter($fileName);
if($excel==false) {
echo $excel->error;
die;
}
$myArr = array('Sr. No.', 'Product','Manufacturer','User Name','Date','Status','Transaction Date');
$excel->writeLine($myArr, array('text-align'=>'center', 'color'=> 'red'));
$id=1;
foreach ($rebate_data as $value) {
$temp_rebate_data =array();
$temp_rebate_data['id'] = $id;
$temp_rebate_data['product'] = "";
$temp_rebate_data['manufacturer'] = "";
$temp_rebate_data['user_name'] = $value['customer_first_name']."".$value['customer_last_name'];
$temp_rebate_data['date'] = $value['created_at'];
$temp_rebate_data['status'] = $value['request_status'];
$temp_rebate_data['transaction_date'] = "";
$row = $temp_rebate_data;
$excel->writeLine($row, array());
$id++;
}
$excel->close();
//Following is the header information in order to download the excel file
header("Content-Type: application/vnd.ms-excel; charset=utf-8");
header("Content-Disposition: attachment; filename=".$fileName);
header("Expires: 0");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Cache-Control: private",false);
//Below is the success message after printing the data successfully to the file
//echo "Data written to file $fileName Successfully.";
}
?>
You should use output buffering for this.
//start of the page
ob_start();
//ur code
//headers
ob_clean();
flush();
readfile($file);
exit;
I think this will solve your problem

PHPExcel: Download the Excel file on the client side

The problem was solved: For other users that may have this problem - notice the encoding of the PHP file. If you use PHPExcel it must be ANSII encoding and not UTF8, otherwise the EXCEL will be downloaded corruptly. The Headers that were added (answer 1) solved the problem after i changed the encoding of the file itself.
I am using PHPExcel in order to create an EXCEL from a table in MYSQL DB, so the user can download it to his computer.
The code bellow creates a correct Excel file but the problem is that it is downloaded to my server. I read in PHPExcel manual that i need to add headers:
header('Content-Type: application/vnd.ms-excel');
header('Content-Disposition: attachment;filename="'.$name.'.xls"');
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, 'Excel5');
$objWriter->save('php://output');
But if i do that, the downloaded file is:
1. Has some jibrish inside
2. Says that Excel needs to fix it because the file is not good.
The problem is that this file is saved as UTF8 and if i encode it as ANSI then it is working properly but of course it is a manual change and i need a working properly excel to reach the users.
What is the bug?
My code that works (but download the file to the server):
<?php
include 'connection.php';
include 'checkUser.php';
//Getting all the needed information from the DB
$task_id=$_GET['id'];
$query2 = "SELECT * FROM projects WHERE ProjectID=$task_id";
$data2 = mysqli_query($con, $query2);
$row = mysqli_fetch_array($data2);
$project_type = $row['ProjectType'];
$project_name = $row['ProjectName'];
switch ($project_type){
case 2: $NumberOfRows=22; $project = "slivedetails"; break;
case 3: $NumberOfRows=30; $project = "plivedetails"; break;
default: $NumberOfRows=0; $project = "none";
}
//column names
if ($project="slivedetails"){
$ColumnNames = mysqli_query($con,"SHOW COLUMNS FROM slivedetails") or die("mysql error");
}
else if ($project="plivedetails"){
$ColumnNames = mysqli_query($con, "SHOW COLUMNS FROM plivedetails") or die("mysql error");
}
$query = "SELECT * FROM $project WHERE TaskID=$task_id";
$data = mysqli_query($con, $query);
$num_rows = mysqli_num_rows($data);
/** Include PHPExcel */
require_once 'PHPExcel_1.7.9_doc/Classes/PHPExcel.php';
require_once 'PHPExcel_1.7.9_doc/Classes/PHPExcel/IOFactory.php';
// create new PHPExcel object
$objPHPExcel = new PHPExcel();
$objPHPExcel = new PHPExcel();
// writer already created the first sheet for us, let's get it
$objSheet = $objPHPExcel->getActiveSheet();
// rename the sheet
$objSheet->setTitle('Task Results');
// let's bold and size the header font and write the header
// as you can see, we can specify a range of cells, like here: cells from A1 to A4
$objSheet->getStyle('A1:AD1')->getFont()->setBold(true)->setSize(12);
$char = 65;
// write header]
for ($i=1;$i<=$NumberOfRows;$i++){
$col_name = mysqli_fetch_array($ColumnNames);
$objSheet->getCell(chr($char).'1')->setValue($col_name['Field']);
$char++;
}
// Now we need to get the data from the DB. While we have a row in the result:
$rowIterator=2; //our row number. We begin from 2 because the first one is the title.
while ($RowInfo = mysqli_fetch_array($data)){
//We will fill the information based on the amount of columns:
$char = 65; //we set the first char as column A
for ($i=0;$i<$NumberOfRows;$i++){
$objSheet->getCell(chr($char).$rowIterator)->setValue($RowInfo[$i]);
$char++;
}
$rowIterator++;
}
// autosize the columns
$char = 65;
for ($i=1;$i<=$NumberOfRows;$i++){
$objSheet->getColumnDimension(chr($char))->setAutoSize(true);
$char++;
}
// create the writer
$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, "Excel2007");
$objWriter->save('results.xlsx');
?>
Remove the following inclusion:
require_once 'PHPExcel_1.7.9_doc/Classes/PHPExcel/IOFactory.php';
You declared the object twice. Remove one of them:
// create new PHPExcel object
$objPHPExcel = new PHPExcel();
Insert the following headers just before creating the Writer:
header("Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
header("Content-Disposition: attachment; filename=\"results.xlsx\"");
header("Cache-Control: max-age=0");
Instead of the following (which actually saves the file in the server):
$objWriter->save('results.xlsx');
Insert the following (which will create the downloadable file):
$objWriter->save("php://output");
This should solve the gibberish text. If you still get such text, insert the following code before the last line ($objWriter->save("php://output");):
ob_clean();
This worked for me. Hope it helps.
This should work, try to modify your code like this:
header("Content-Type: application/vnd.ms-excel");
header("Content-Disposition: attachment; filename=my_excel_filename.xls");
header("Pragma: no-cache");
header("Expires: 0");
flush();
require_once 'PHPExcel.php';
$objPHPExcel = new PHPExcel();
// here fill data to your Excel sheet
$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5');
$objWriter->save('php://output');
Alex, I had the same problem. I did all of them but again result was the same. I just changed
$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');
to
$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5');
and changed all .xlsx to .xls.
Hope It will help.
Download PHPExcel-1.8(from github) and replace it with the old PHPExcel.
Rename PHPExcel-1.8 to PHPExcel. In my code I have included require '../library/excel/PHPExcel.php';
I deleted all contents from this file (PHPExcel.php) and added only one line of code
require 'PHPExcel/Classes/PHPExcel.php';
(Note: I uploaded PHPExcel in the folder library/excel)
Works perfectly

File download for csv works in local host but not when live

I am creating a csv file from nested array and it works fine with a download link to the csv file in the localhost, but on live host it won't download. This is what is in my php file:
The headers declared:
/**
* Declare headers for CSV
*/
header("Content-type: text/csv");
header("Content-Disposition: attachment; filename=registration.csv");
header("Pragma: no-cache");
header("Expires: 0");
The Function that outputs the csv file:
/**
* Function will output the scsv file
* #param the csv $data in nested array form array(array("","",""),array("",""...)...)
*/
function outputCSV($data) {
$outstream = fopen("php://output", "w");
function __outputCSV(&$vals, $key, $filehandler) {
fputcsv($filehandler, $vals); // add parameters if you want
}
array_walk($data, "__outputCSV", $outstream);
fclose($outstream);
}
The link that I used in local:
Download CSV
Won't work on Live site. Instead of downloading it just takes me to the csv.php page and outputs the array in a string like this.
...ID,"Coach One","Coach Two",Work,Cell,Email,...
Try hardcoding the csv into the code. Replace these lines with the ones you have to see if your data being passed has bad characters. Maybe specifying the charset will help.
header('Content-Type: text/csv; charset=utf-8');
header('Content-Disposition: attachment; filename=data.csv');
$output = fopen('php://output', 'w');
fputcsv($output, array('Column 1', 'Column 2', 'Column 3'));
As described here:
http://code.stephenmorley.org/php/creating-downloadable-csv-files/
I'm not setup to really debug your code. You can try this though if you like. I know it works.
$out = fopen("php://temp", 'r+');
while (($row = $res->fetch(Zend_Db::FETCH_NUM)) != false) {
fputcsv($out, $row, ',', '"');
}
rewind($out);
$csv = stream_get_contents($out);
header("Content-Type: application/csv;");
header("Content-Disposition: attachment; filename=\"foo.csv\"");
header("Pragma: no-cache");
header("Expires: 0");
echo $csv;
exit(0);
Adjust the loop as needed to iterate on your results.

Categories