php + download to excel --> worksheet name - php

I am currently exporting data from php to excel using the code as below:
include("dbconnect.php");
$query = $_POST['query'];
$result = odbc_exec($conn,$query);
$count = odbc_num_fields($result);
//Define Variable For ODBC
$data = "";
//Field Name Data
for ($i = 1; $i <= $count; $i++)
{
$data .= odbc_field_name($result, $i)."t";
}
$data .= "n";
//Row Data
while(odbc_fetch_row($result))
{
for ($j = 1; $j <= $count; $j++)
{
$data .= odbc_result($result, $j)."t";
}
$data .= "n";
}
header("Content-type: application/octet-stream");
header("Content-Disposition: attachment; filename=ExcelFile.xls;");
header("Pragma: no-cache");
header("Expires: 0");
echo $data;
odbc_close($conn);
This all works fine, but the generated excel file has a sheetname of: ".xls]ExcelFile(1)" , and when you try to rename the sheet it causes an error in excel (unless you save the file first).
How can I define the sheetname in my php file?
Thanks in advance!
Have a nice weekend:-)

You're not actually creating an xls file, but a tab separated value file. Excel can read this, but it simply populates the data in the first worksheet. Because it's not a true xls file, you can't name the worksheet tabs in any way.
One option would be to change your code to use a library that writes true xls files, such as PHPExcel ( http://www.phpexcel.net )... you would then be able to define a name for the worksheet tab within your script.

By changing the
header("Content-type: application/octet-stream");
To
header("Content-type: application/vnd-ms-excel");
It is downloading without any errors and i am able to save that. the worksheet name is same as excel name.

Related

PHPExcel how to solve the encoding issue when reading a file

I was working on an Yii2 API where i need to upload a .csv or .xlsx file and read from it using PHPExcel(DEPRECATED now , but i am stuck with it as new one PhpSpreadsheet requires PHP version 5.6 or newer) and return the array of data .
This was the code used in the API function
public function actionUpload()
{
$params = $_FILES['uploadFile'];
if($params)
{
$data = array();
$model = new UploadForm();
$model->uploadFile = $_FILES['uploadFile'];
$file = UploadedFile::getInstanceByname('uploadFile');
$inputFileName = $model->getpath($file,$data);
// Read your Excel workbook
try
{
$inputFileType = \PHPExcel_IOFactory::identify($inputFileName['link']);
$objReader = \PHPExcel_IOFactory::createReader($inputFileType);
if($inputFileType == 'CSV')
{
if (mb_check_encoding(file_get_contents($inputFileName['link']), 'UTF-8'))
{
$objReader->setInputEncoding('UTF-8');
}
else
{
$objReader->setInputEncoding('Windows-1255');
//$objReader->setInputEncoding('ISO-8859-8');
}
}
$objPHPExcel = $objReader->load($inputFileName['link']);
}
catch(Exception $e)
{
die('Error loading file "'.pathinfo($inputFileName['link'],PATHINFO_BASENAME).'": '.$e->getMessage());
}
// Get worksheet dimensions
$sheet = $objPHPExcel->getSheet(0);
$highestRow = $sheet->getHighestRow();
$highestColumn = $sheet->getHighestColumn();
$fileData = array();
// Loop through each row of the worksheet in turn
for ($row = 1; $row <= $highestRow; $row++)
{
// Read a row of data into an array
$rowData = $sheet->rangeToArray('A' . $row . ':' . $highestColumn . $row,
NULL,
TRUE,
FALSE);
array_push($fileData,$rowData[0]);
// Insert row data array into your database of choice here
}
return $fileData;
}
}
But there are encoding issues when we upload a excel file containing hebrew data in it . As you can see the code below from the above code was used to address this issue
if (mb_check_encoding(file_get_contents($inputFileName['link']), 'UTF-8'))
{
$objReader->setInputEncoding('UTF-8');
}
else
{
$objReader->setInputEncoding('Windows-1255');
}
Later i found that UTF-8 and Windows-1255 are not the only possible encoding for the flies that may be uploaded but other encoding like UTF-16 or other ones depending upon the Operating System of user. Is there any better way to find the encoding other than using mb_check_encoding
The common error that occur during the process of reading the data in file is :
iconv(): Detected an illegal character in input string
As you can see the above error occurs due to the inability to detect the appropriate encoding of the file. Is there any workaround ?
You can attempt to use mb_detect_encoding to detect the file encoding but I find that results vary. You might have to manually specify a custom match order of encodings to get proper results. Here is an example substitute for the if statement in question:
if(inputFileType == 'CSV')
{
// Try to detect file encoding
$encoding = mb_detect_encoding(file_get_contents($inputFileName['link']),
// example of a manual detection order
'ASCII,UTF-8,ISO-8859-15');
$objReader->setInputEncoding($encoding);
}
Make sure the first clean the output buffer in your page:
ob_end_clean();
header( "Content-type: application/vnd.ms-excel" );
header('Content-Disposition: attachment; filename="uploadFile.xls"');
header("Pragma: no-cache");
header("Expires: 0");
ob_end_clean();

Delete row in excel while exporting using php

I have a php file where i export data from database to excel using
header("Content-type: application/vnd.ms-excel");
header("Content-Disposition: attachment;Filename=cel.xls");
Now, i want to delete the first row of the file before it is exported. Can anyone help me on this?
you can try this sample code
if(isset($_POST['Upload'])) {
if(move_uploaded_file($_FILES["file"]["tmp_name"], "files/" . $_FILES["file"]["name"])) {
$file_target="files/" . $_FILES["file"]["name"];
$data->read($file_target);
// $x = 2 indicates second row of the excel sheet //
for($x = 2;$x<=count($data->sheets[0]["cells"]); $x++) {
$first_cell = $data->sheets[0]["cells"][$x][1];
$second_cell = $data->sheets[0]["cells"][$x][2];
$third_cell = $data->sheets[0]["cells"][$x][3];
}
}
}

Selective download with PHPExcel

I'm using PHPExcel to download some data stored in MySQLi. I made an algorithm that is working for every data base (in theory). I have tested it with some of them and it was working fine.
I extracted names of the columns in an array: column_names and then, I'm adding titles and data to the excel report.
// Adding titles
$objPHPExcel->setActiveSheetIndex(0)
->setCellValue('A1',$bigTitle);
$counter = 0;
$let = 'a';
while ($counter <= count($column_names)){
$objPHPExcel->setActiveSheetIndex(0)
->setCellValue(strtoupper($let).'3', $column_names[$counter]);
$let++;
$counter++;
}
//Adding data
$i = 4;
while ($row = $result->fetch_array()) {
$counter = 0;
$let = 'a';
while ($counter <= count($column_names)){
$objPHPExcel->setActiveSheetIndex(0)
->setCellValue(strtoupper($let).$i, $row[$column_names[$counter]]);
$let++;
$counter++;
}
$i++;
}
I'm connecting to the database using
$conexion = new mysqli('localhost','user','pass','SAT_dbname',21);
I cloned "SAT_db1" database to "SAT_db2". They have exactly the same structure but different information. The download is working if I'm using
$conexion = new mysqli('localhost','user','pass','SAT_db1',21);
But it's not working if I'm using
$conexion = new mysqli('localhost','user','pass','SAT_db2',21);
I don't know what is wrong if they're the same with different names. Is not PHPExcel working with cloned databases? What else could it be?
The error shows up in the browser as "File not found".
EDIT
I was testing the download all day and I finally found something: I can download when I have few registers. When I have a few more, I can't.
I'm sending the file to the browser:
header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
header('Content-Disposition: attachment;filename="Report.xlsx"');
header('Cache-Control: max-age=0');
$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');
$objWriter->save('php://output');
Still haven't found a solution.
PHPExcel has limits with cache. I had to change these limits manually. I used this code before creating PHPExcel object:
set_time_limit(0) ;
$cacheMethod = PHPExcel_CachedObjectStorageFactory:: cache_to_phpTemp;
$cacheSettings = array( 'memoryCacheSize' => '500MB');
PHPExcel_Settings::setCacheStorageMethod($cacheMethod, $cacheSettings);
I assume if you have bigger files, you can expand "memoryCacheSize".

Export CSV file using PHP create corrupt file when try to open in MS Excel

I have the following script that will export data from my database using php to csv file. Everything works fine, except when I try to open the file in excel, I get "file is corrupt". When I run this code it shows the error - "The file is corrupted and can not be opened." Thanks in advance!
<?php
// Connection
include_once('conn.php');
$sql = "select * from info";
$qur = mysql_query($sql);
// Enable to download this file
$filename = "sampledata.csv";
header("Content-Disposition: attachment; filename=\"$filename\"");
header("Content-Type: text/csv");
$display = fopen("php://output", 'w');
$flag = false;
while($row = mysql_fetch_assoc($qur)) {
if(!$flag) {
// display field/column names as first row
fputcsv($display, array_keys($row), ",", '"');
$flag = true;
}
fputcsv($display, array_values($row), ",", '"');
}
fclose($display);
exit;
?>
I found the answer of my own question. Just need to add the ob_clean() line before we call the headers to download csv file to clear the output buffer. This will solve the error of not opening csv file in excel.

exporting database to xls with price formatted with dollar sign and commas

Im exporting my mysql database to excel, and everything is working, but I want the price field to display with a dollar sign and commas within the excel spreadsheet.
Here is my code:
$pubtable = $_GET["publication"];
$addate = $_GET["adDateHidden"];
$export = mysql_query("SELECT * FROM $pubtable WHERE addate = '$addate' ORDER BY price DESC") or die ("Sql error : " . mysql_error());
$fields = mysql_num_fields($export);
for($i = 0; $i < $fields; $i++){
$header .= mysql_field_name($export , $i). "\t";
}
while($row = mysql_fetch_row($export)){
$line = '';
foreach($row as $value) {
if(!isset($value) || trim($value) == "") {
$value = "\t";
} else {
$value = str_replace('"' , '""' , $value);
$value = '"' . $value . '"' . "\t";
}
$line .= $value;
}
$data .= trim($line). "\n";
}
$data = str_replace("\r" , "" , $data);
if(trim($data) == ""){
$data = "\n(0)Records Found!\n";
}
header("Content-type: application/vnd.ms-excel");
header("Content-Disposition: attachment; filename=".$pubtable."_".$addate.".xls");
header("Pragma: no-cache");
header("Expires: 0");
header ('Content-Transfer-Encoding: binary');
header ('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT');
header ('Cache-Control: cache, must-revalidate');
print "$header\n$data";
I tried doing this
$export = mysql_query("SELECT CONCAT('$', FORMAT(price, 2)) as fieldalias * FROM $pubtable WHERE addate = '$addate' ORDER BY fieldalias DESC") or die ("Sql error : " . mysql_error());
this formats it correctly but it only outputs the price field and nothing else.
Technically, you're not producing an Excel spreadsheet. You're producing a CSV file with a .xls extension. CSV has no mechanism for adding formatting, because it's just plain text. You can have MySQL and/or PHP format a number into what looks like a nice currency value, but then you're destroying its existence as a number. It'll be a string-that-used-to-be-a-number.
You should use PHPExcel to produce an ACTUAL Excel file, into which you can add all the usual goodies that Excel supports, including colors and formulae.
Your code is generating a text file (CSV formated) with a XLS extension. Then, under Windows with an Excel installed, it may be automatically opened by Excel despite the content is only text file.
This method cannot produce any data with style.
I suggest that you use OpenTBS to easily build your Excel file. OpenTBS is a PHP class which can build real XLSX, DOCX, ODT, ODS and more... using templates. You just design the template with Excel and then merge it with the data under PHP and you have a new XSLS directly for download, or as a files saved on the server.

Categories