PHP excel file without PHPExcel - php

I have to create a excel file having near about 350 columns and 1000 rows. I have developed code for this task using PHPExcel. But it takes 42secs to create file. So I have to create excel file without PHPExcel. So I have developed a script in which data is identified by "\t" for different tab data. It takes just 2secs to create file. But problem is that when I'm going to open that file (created by using "\t"), message of corrupted file is displayed. And on repairing that file, it works fine. But I can't understand that where I'm making mistake in script. If anyone can solve this problem either by using PHPExcel (less execution time) or by solving error of corrupt file, then answer will be appreciated. Here is my code (CakePHP 3).
Input Array like
// Do not confuse with { instead of [. It's okey.
// $export_data and $data both are same (Input array).
{
"0": {
"customer_id": 1,
"name": "John Stevens",
"Date of 1 Purchase": "2014-08-05T00:00:00+0000",
"Date of 2 Purchase": "2014-09-05T00:00:00+0000",
"Date of 3 Purchase": "2014-10-05T00:00:00+0000",
...
...
... 350 Cols ...
}
"1": {
...
}
...
...
"999 Rows"
}
Using PHPExcel
$r = 1;
$filename = FILE_PATH . 'galliyan.xlsx';
$header = array_keys($export_data[0]);
$objPHPExcel = new \PHPExcel();
$col = 0;
foreach ($header as $field) {
$objPHPExcel->getActiveSheet()->setCellValueByColumnAndRow($col, 1, $field);
$col++;
}
$objWriter = \PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');
$objWriter->save($filename);
chmod($filename, 0777);
$r++;
$objPHPExcel = \PHPExcel_IOFactory::load($filename);
foreach($export_data as $row) {
$col = 0;
foreach ($row as $ro) {
$objPHPExcel->getActiveSheet()->setCellvalueByColumnAndRow($col, $r, $ro);
$col++;
}
$r++;
}
$objWriter = \PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');
$objWriter->save($filename);
chmod($filename, 0777);
EDIT (UPDATED CODE)
$filename = FILE_PATH . 'galliyan.xlsx';
$header = array_keys($export_data[0]);
$objPHPExcel = new \PHPExcel();
$sheet = $objPHPExcel->getActiveSheet();
$col = 0;
foreach ($header as $field) {
$sheet->setCellValueByColumnAndRow($col, 1, $field);
$col++;
}
$objPHPExcel->getActiveSheet()->fromArray($export_data, null, 'A2');
$writer = \PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');
$writer->save($filename);
chmod($filename, 0777);
Using "\t"
foreach ($data as $row) {
if (!$flag) {
$header = array();
// display field/column names as first row
$header = array_keys($row);
$header = $this->setExcelHeaders($header);
$this->createExcelFile($dir_name, $filename, $header, $export_type);
$flag = TRUE;
}
array_walk($row, array($this, 'cleanData'));
array_push($values, $row);
}
$values = $this->setValues($values);
$this->writeExcelFile($dir_name, $filename, $values);
function setExcelHeaders($hdrs) {
$header = '';
foreach ($hdrs as $title_val) {
$header .= $title_val . "\t";
}
return $header;
}
function createExcelFile($dir_name, $filename, $header, $export_type = '') {
$fp = fopen($dir_name . "/" . $filename, 'w');
fwrite($fp, "$header\n");
fclose($fp);
$permission = Configure::read('Config.PERMISSION');
if ($export_type == "") {
chmod($dir_name, $permission);
}
chmod($dir_name . "/" . $filename, $permission);
}
public function cleanData(&$str) {
$str = preg_replace("/\t/", "\\t", $str);
$str = preg_replace("/\r?\n/", "\\n", $str);
if (strstr($str, '"'))
$str = '"' . str_replace('"', '""', $str) . '"';
}
private function setValues($all_vals) {
$data = '';
for ($i = 0; $i < count($all_vals); $i++) {
$line = '';
foreach ($all_vals[$i] as $value) {
if ((!isset($value)) || ( $value == "")) {
$value = "\t";
}
else {
$value = str_replace('"', '""', $value);
$value = '"' . $value . '"' . "\t";
}
$line .= $value;
}
$data .= trim($line) . "\n";
}
return $values = str_replace("\r", "", $data);
}
function writeExcelFile($dir_name, $filename, $data) {
$fp = fopen($dir_name . "/" . $filename, 'a');
fwrite($fp, "$data");
fclose($fp);
}

As you mentioned "without PHPExcel", have you tried looking at alternatives that can be faster than PHPExcel? For instance, you can generate a 350x1000 XLSX spreadsheet with Spout (https://github.com/box/spout) in just a few seconds.
Generating a CSV file is also a good alternative and I'd recommend you going this route if you can. The export process will be way faster! But don't try to reinvent the wheel, there a already a lot of CSV writer out there, ready to use (Spout and PHPExcel both have one for instance).

Related

Exported Excel store on local folder of project

I have code which download the excel file.
I want to save this file in folder.
if($array_count > 0)
{
$fileName = "export_data" . rand(1,100) . ".xls";
if ($error_array) {
function filterData(&$str) {
$str = preg_replace("/\t/", "\\t", $str);
$str = preg_replace("/\r?\n/", "\\n", $str);
if(strstr($str, '"')) $str = '"' . str_replace('"', '""', $str) . '"';
}
// headers for download
header("Content-Disposition: attachment; filename=\"$fileName\"");
header("Content-Type: application/vnd.ms-excel");
$flag = false;
foreach($error_array as $row) {
if(!$flag) {
// display column names as first row
// echo implode("\t", array_keys($row)). "\r\n";;
$flag = true;
}
// filter data
//header_remove('require_once($_SERVER["DOCUMENT_ROOT"]."/bitrix/header.php")');
array_walk($row, 'filterData');
echo implode("\t", array_values($row)). "\r\n"; ;
}
//exit;
}
}
Please some one help me to change my code to save file in folder.
Here I have made one sample for you with static array data. We can save the file in the folder.
You can make changes in this code as per your requirement.
<?php
$data_array = array (
array ('1','2'),
array ('2','2'),
array ('3','6'),
array ('4','2'),
array ('6','5')
);
$sep = "\t";
$xls = "col1".$sep."col2 \n";//Column headers
foreach ($data_array as $record){
$xls.= $record[0].$sep.$record[1]."\n"; //Append data to xls
}
$xls_handler = fopen ('xlsfile.xls','w');
fwrite ($xls_handler,$xls);
fclose ($xls_handler);
echo 'Data saved to xlsfile.xls';
?>

“How to export other next file‘ after 2000 rows data

I am using PHP for export CSV file this is working, but i export 2000 or greater rows how to create automatic next CSV file.
How to Move other file on after 2000 rows?
<?php
header('Content-type: application/csv');
header('Content-Disposition: attachment; filename = records.csv');
echo $header = "Name";
echo "\r\n";
$sql = mysql_query(“Select * from table”);
while ($getData = mysql_fetch_assoc($sql)) {
echo '"'.$name.'"';
echo "\r\n";
}
exit;
?>
You can use array_chunk function to keep the records of 2000 and export them in csv.
For example
$rowData = [
[1,2,3],
[11,21,31],
[21,22,32],
[31,42,73],
[111,222,333]
];
foreach(array_chunk($rowData, 2) as $key => $records){
$file_name = 'export_data_'.$key.'.csv';
writeToCsv($file_name,$records);
}
//funtion to export data to csv
function writeToCsv($fileName, $rowData){
$fp = fopen($fileName, 'w');
foreach ($rowData as $fields) {
fputcsv($fp, $fields);
}
fclose($fp);
}
In your case use array_chunk($rowData, 2000)
<?php
$rowLimit = 2000;
$fileIndex = 0;
$i = 1;
$handle = null;
$fileList = array();
$timestampFolder = strtotime("now").'/';
mkdir($timestampFolder);
$sql = mysql_query("Select * from table");
while ($getData = mysql_fetch_assoc($sql)) {
if( ($i%$rowLimit) == 1) {
$fileIndex+=1;
if(!is_null($handle)) {
fclose($handle);
}
$fileName = "records".$fileIndex.".csv";
$handle = fopen($timestampFolder.$fileName, "a");
$fileList[] = $fileName;
}
fputcsv($handle, $getData);
$i++;
}
foreach($fileList as $file) {
echo ''.$file.'<br>';
}

Multidimensional Array + CSV Export

I have an issue with an export script im trying to write...
I create a multidimensional array
while($row = $insert_row->fetch_assoc()) {
foreach ($selectArray as $value) {
$userData = $row[$value];
$userDataArray[] = $userData;
}
$userArray[] = $userDataArray;
unset($userDataArray);
}
Now I want to create the CSV File
$sendfilename = "export" . ".csv";
$filename = "file" . ".csv";
$delimiter = ';';
$enclosure = '"';
$encloseAll = true;
$nullToMysqlNull = false;
$delimiter_esc = preg_quote($delimiter, '/');
$enclosure_esc = preg_quote($enclosure, '/');
$fp = fopen($filename, 'wb');
if ($fp)
{
foreach ($userArray as $users) {
foreach ($users as $fields) {
fputcsv($fp, $fields,";",'"');
}
}
}
fclose($fp);
readfile($filename);
Im getting the error "fputcsv() expects parameter 2 to be array, string given"
Any solution?
Already fixed, I went one level to deep on fput...

How scan all the files in a directory and then load all the files

$dirs = array($homedir);
$files = array();
while(count($dirs)) {
$dir = array_shift($dirs);
foreach(glob("$dir/*") as $e)
if(is_dir($e))
$dirs[] = $e;
else
$files[] = $e;
$content .= "{$e}\n" . filegetcontents($e) . "\n";
}
if(!empty($content)) touch "allcode.txt";
how do i load all the files and then combine the code as
filename
code
-----
filename
code
-----
with line numbers as well.
The quickest method I've used is DirectoryIterator, but only available with PHP5.
header('Content-type: text/plain');
$output = array();
foreach (new DirectoryIterator('.') as $file) {
if ($file->isFile()) {
$output[] = $i++ . " " . $file->getFileName() . "\n";
$output[] = file($file->getPathName());
$output[] = "\n------------\n";
}
}
echo implode('', $output);

PHP - parsing a txt file

I have a .txt file that has the following details:
ID^NAME^DESCRIPTION^IMAGES
123^test^Some text goes here^image_1.jpg,image_2.jpg
133^hello^some other test^image_3456.jpg,image_89.jpg
What I'd like to do, is parse this ad get the values into a more readable format, possibly into an array if possible.
Thanks
You can do that easily this way
$txt_file = file_get_contents('path/to/file.txt');
$rows = explode("\n", $txt_file);
array_shift($rows);
foreach($rows as $row => $data)
{
//get row data
$row_data = explode('^', $data);
$info[$row]['id'] = $row_data[0];
$info[$row]['name'] = $row_data[1];
$info[$row]['description'] = $row_data[2];
$info[$row]['images'] = $row_data[3];
//display data
echo 'Row ' . $row . ' ID: ' . $info[$row]['id'] . '<br />';
echo 'Row ' . $row . ' NAME: ' . $info[$row]['name'] . '<br />';
echo 'Row ' . $row . ' DESCRIPTION: ' . $info[$row]['description'] . '<br />';
echo 'Row ' . $row . ' IMAGES:<br />';
//display images
$row_images = explode(',', $info[$row]['images']);
foreach($row_images as $row_image)
{
echo ' - ' . $row_image . '<br />';
}
echo '<br />';
}
First you open the text file using the function file_get_contents() and then you cut the string on the newline characters using the function explode(). This way you will obtain an array with all rows seperated. Then with the function array_shift() you can remove the first row, as it is the header.
After obtaining the rows, you can loop through the array and put all information in a new array called $info. You will then be able to obtain information per row, starting at row zero. So for example $info[0]['description'] would be Some text goes here.
If you want to put the images in an array too, you could use explode() too. Just use this for the first row: $first_row_images = explode(',', $info[0]['images']);
Use explode() or fgetcsv():
$values = explode('^', $string);
Or, if you want something nicer:
$data = array();
$firstLine = true;
foreach(explode("\n", $string) as $line) {
if($firstLine) { $firstLine = false; continue; } // skip first line
$row = explode('^', $line);
$data[] = array(
'id' => (int)$row[0],
'name' => $row[1],
'description' => $row[2],
'images' => explode(',', $row[3])
);
}
By far the best and simplest example of this I have come accross is quite simply the file() method.
$array = file("myfile");
foreach($array as $line)
{
echo $line;
}
This will display all the lines in the file, this is also applicable for a remote URL.
Simple and clear.
REF : IBM PHP Parse
I would like to contribute a file that provides atomic data structures.
$lines = file('some.txt');
$keys = explode('^', array_shift($lines));
$results = array_map(
function($x) use ($keys){
return array_combine($keys, explode('^', trim($x)));
},
$lines
);
Try fgetcsv() with ^ as the separator character:
$file = fopen($txt_file,"r");
print_r(fgetcsv($file, '^'));
fclose($file);
http://www.w3schools.com/php/func_filesystem_fgetcsv.asp
<?php
$row = 1;
if (($handle = fopen("test.txt", "r")) !== FALSE) {
while (($data = fgetcsv($handle, 1000, "^")) !== FALSE) {
$num = count($data);
echo "<p> $num fields in line $row: <br /></p>\n";
$row++;
for ($c=0; $c < $num; $c++) {
echo $data[$c] . "<br />\n";
}
}
fclose($handle);
}
?>
Ok, didn't see the edited version, so here's a redo. It's most likely a CSV file that uses carets as the separator, so...
$fh = fopen('yourfile.txt');
$headers = fgetcsv($fh, 0, '^');
$details = array();
while($line = fgetcsv($fh, 0, '^')) {
$details[] = $line;
}
fclose($fh);
youse a list, and split the "image_1.jpg,image_2.jpg" after you explode the string:
list($number, $status, $text, $images) = explode("^", $data);
$splited_images= preg_split(',', $images);
My solution
function parseTextFile($file){
if( !$file = file_get_contents($file))
throw new Exception('No file was found!!');
$data = [];
$firstLine = true;
foreach(explode("\n", $file) as $line) {
if($firstLine) {
$keys=explode('^', $line);
$firstLine = false;
continue;
} // skip first line
$texts = explode('^', $line);
$data[] = array_combine($keys,$texts);
}
return $data;
}

Categories