I just want to import data from excel (xls, xlsx) to mySql db in Yii2 using PHPExcel.
This is my code in Controller:
$modelFile ->file = $firstName. '_' .$middleName. '_' .date('Y-m-d'). '_' .$file ->getBaseName(). "." .$file ->getExtension();
$objPHPExcel = new \PHPExcel();
$inputFiles = fopen("../file/".$modelFile ->file, "r");
try {
$inputFileType = \PHPExcel_IOFactory::identify($inputFiles);
$objReader = \PHPExcel_IOFactory::createReader($inputFileType);
$objPHPExcel = $objReader ->load($inputFiles);
} catch (Exception $ex) {
die('Error');
}
$sheet = $objPHPExcel ->getSheet(0);
$highestRow = $sheet ->getHighestRow();
$highestColumn = $sheet ->getHighestColumn();
//$row is start 2 because first row assigned for heading.
for ($row = 2; $row <= $highestRow; ++$row) {
$rowData = $sheet ->rangeToArray('A'.$row. ':' .$highestColumn.$row, NULL, TRUE, FALSE);
//save to branch table.
$modelHeader = new FakturOut();
$modelDetail = new FakturOutDetail();
$modelHeader ->name = $rowData[0][0];
$modelHeader ->age = $rowData[0][1];
$modelHeader ->address = $rowData[0][2];
$modelHeader ->academic_id = $rowData[0][3];
$modelHeader ->mother_name = $rowData[0][4];
$modelHeader ->father_Name = $rowData[0][5];
$modelHeader ->gender = $rowData[0][6];
$modelHeader ->height = $rowData[0][7];
$modelHeader ->weight= $rowData[0][8];
$modelHeader ->save();
}
And then the browser return an error notification like pathinfo() expects parameter 1 to be string, resource given. Please help to solve this error.
in your code you have used
$inputFileType =\PHPExcel_IOFactory::identify($inputFiles);
which is used to identify the valid excel file and it expects the parameter as filename.
I can see in your code, you have passed $inputFiles as a parameter to identify method, which is not a file name but resource handler. and identify method expects it to be string (file name).
This is the reason you are getting error.
Note : fopen() returns a file pointer resource on success, or FALSE on error.
$inputFiles = fopen("../file/" . $modelFile->file, "r");
Related
Im working with someone else's code.
lets say I have an id have something like this in a csv text file(no header this is just an example and is imported into a database)
|id|partNumber|vendorNumber|dateModified|
123|18-302|fe32l|8/27/2020
123|18-302|fe32l|8/22/2020
123|18-302|fe32l|8/27/2021
321|18-3032|fe32l|8/27/2020
321|18-3032|fe32l|5/24/2022
My conclusion is because it gabs everything, rather than the newest, as a result it doesn't import the newest information.
Question
How do I modify the text file it creates to only write then newest dates for each id.(which is the first and last field in the text file). It can even delete the fields after it writes it.
I think the file is created within lines 253-297
protected function writeImportFile($tmpFile)
{
$data = file_get_contents($tmpFile);
$data = str_replace('\\', '', $data);
$data = str_replace("\t", '', $data);
file_put_contents($tmpFile, $data);
unset($data);
$stopwatch = new Stopwatch();
$stopwatch->start('write');
$tmpDir = $this->tmpDir;
$fileImport = $tmpDir . $this->tableName . '.txt';
$fileRead = new \SplFileObject($tmpFile);
$reader = new CsvReader($fileRead, '|');
$reader->setHeaderRowNumber(0);
$writer = new CsvWriter('|');
$writer->setStream(fopen($fileImport, 'w'));
$numLines = $reader->count();
$i=0;
$this->modColumns();
foreach ($reader as $row) {
$newRowArray = $this->modRow($row);
if (!empty($newRowArray)) {
$writer->writeItem($newRowArray);
}
$i++;
if($i%1000 == 0){
$this->writeLog(' import file has wrote '.$i.' of '.$numLines);
}
}
unlink($tmpFile);
$exTime = $stopwatch->stop('write');
$timeMil = $exTime->getDuration();
$this->writeLog(' Time to write import file for ' . $this->tableNameSw . ' ' . gmdate("H:i:s", $timeMil / 1000));
return $fileImport;
}
Trying to maintain some old dusty code, I am facing a problem with phpexcel in a import symfony command.
It seems that the library cannot calculate the formula correctly which is linked to another sheet of the same document as the active sheet.
The error I get is :
[PHPExcel_Calculation_Exception]
Price Template Map!B2 -> Invalid cell coordinate A
My code is :
try {
$inputFileType = \PHPExcel_IOFactory::identify($filePath);
$objReader = \PHPExcel_IOFactory::createReader($inputFileType);
$objReader->setLoadSheetsOnly(array($this->getListName(), 'Template Info'));
$objReader->setIncludeCharts(true);
$objPHPExcel = $objReader->load($filePath);
} catch (\Exception $e) {
throw new \Exception("Invalid file");
}
$sheet = $objPHPExcel->getActiveSheet();
$highestRow = $sheet->getHighestRow();
$highestColumn = $sheet->getHighestColumn();
$fieldsNumber = array();
$filterData = array();
$templateIdList = array();
for ($i = 1; $i <= $highestRow; $i++) {
$rowData = $sheet->rangeToArray('A' . $i . ':' . $highestColumn . $i, null, true, false);
$rowData = $rowData[0];
var_dump($rowData);
}
The first line with the headers is read correctly, but the rest is not.
My formula is :
=VLOOKUP(A18,'Template Info'!A:C,3,FALSE)"
Do not hesitate to ask me more informations if you need it !
Thank you all in advance :) !
The problem is the column reference: the PHPExcel Calculation Engine supports range references (even to other worksheets), but not row or column references
so
=VLOOKUP(A18,'Template Info'!A1:C100,3,FALSE)
would be valid, but
=VLOOKUP(A18,'Template Info'!A:C,3,FALSE)
can't be calculated
Use the getCalculatedValue() function.
I'm using Symfony2.3.4, PHP5.6.3 and PHPExcel 1.8.0.
When I tried to read an excel file it works OK for almost all cells.
If the cell contains a very large number, when I read it and show the value in an html view it outputs false.
I tried to use a custom value binder like Mark Baker instructed here but I couldn't make it work, it just comes as a boolean right from the beginning.
IMPORTANT:
The excels I'm trying to load in the html are downloaded(generated) from another site and I noticed when you try to open them with Microsoft Excel, it first prompts you with a warning window telling the user that the FILE EXTENSION AND THE FILE FORMAT DO NOT MATCH, although if you choose to open it anyway, it opens fine.
I think that's what's causing the problem, I'm almost sure(I can't contact the guys who implemented the other site's download function) they did something like this:
$objWriter = \PHPExcel_IOFactory::createWriter($objPHPExcel, $ext == 'xlsx' ?
'Excel5' : 'Excel2007');
when they should have done something like this:
$objWriter = \PHPExcel_IOFactory::createWriter($objPHPExcel, $ext == 'xls' ?
'Excel5' : 'Excel2007');
making the EXTENSION and the FORMAT match, as instructed in the PHPExcel's docs.
If you need any specific clarification please ask.
My code to load the file into the html:
public function uploadAction() {
$request = $this->getRequest();
$form = $this->createFormBuilder()
->add('file', 'file')
->getForm();
if ($request->getMethod() == 'POST'){
$form->submit($request);
$file = $form['file'];
$file->getData()->move(
'uploads', $form['file']->getData()->getClientOriginalName());
$ext = pathinfo($file->getData()->getClientOriginalName(), PATHINFO_EXTENSION);
$name = pathinfo($file->getData()->getClientOriginalName(), PATHINFO_BASENAME);
//$objReader = \PHPExcel_IOFactory::createReader('xlsx' == $ext ? 'Excel2007' : 'Excel5');
$objReader = \PHPExcel_IOFactory::createReaderForFile('uploads/' . $name);
$objReader->setReadDataOnly(true);
$objPHPExcel = $objReader->load('uploads/' . $name);
$activeSheet = $objPHPExcel->getActiveSheet();
$rowIter = $activeSheet->getRowIterator();
foreach ($rowIter as $key => $row) {
$columns = array();
$cellIterator = $row->getCellIterator();
$cellIterator->setIterateOnlyExistingCells(false);
foreach ($cellIterator as $cell)
$columns[] = $cell->getCalculatedValue();
}
}
}
NOTE: I really don't know the difference between:
$objReader = \PHPExcel_IOFactory::createReader('xlsx' == $ext ? 'Excel2007' : 'Excel5');
and
$objReader = \PHPExcel_IOFactory::createReaderForFile('uploads/' . $name);
I DO know I can't use the first because of the problem I described above about the files being ill-generated and so. If I try to use it, the browser goes:
The filename uploads/<name>.xls is not recognised as an OLE file.
Can anyone point me to a workaround, because it's now me on the hook and I'm supposed to make it work somehow. Maybe there's nothing wrong with the files and it's me doing something wrong. Please help, this is causing me problems with dates too but one step at a time.
EDIT:
This is but the read function in OLERead.php.
I was browsing it and var_dump-ing all I could get my hands on.
As you can see there are two var_dumps in the code below, those output:
string '<div>
' (length=8)
string '��ࡱ�' (length=8)
Which doesn't happen when I try it with a regular .xls file created manually:
string '��ࡱ�' (length=8)
string '��ࡱ�' (length=8)
I guessed you could use this better than me if it helps at all. Thanks again.
public function read($sFileName) {
// Check if file exists and is readable
if (!is_readable($sFileName)) {
throw new PHPExcel_Reader_Exception("Could not open " . $sFileName . " for reading! File does not exist, or it is not readable.");
}
// Get the file identifier
// Don't bother reading the whole file until we know it's a valid OLE file
$this->data = file_get_contents($sFileName, FALSE, NULL, 0, 8);
////VAR_DUMPSSSSSSSSSSSS
var_dump($this->data);
var_dump(self::IDENTIFIER_OLE);
die();
// Check OLE identifier
if ($this->data != self::IDENTIFIER_OLE) {
throw new PHPExcel_Reader_Exception('The filename ' . $sFileName . ' is not recognised as an OLE file');
}
// Get the file data
$this->data = file_get_contents($sFileName);
// Total number of sectors used for the SAT
$this->numBigBlockDepotBlocks = self::_GetInt4d($this->data, self::NUM_BIG_BLOCK_DEPOT_BLOCKS_POS);
// SecID of the first sector of the directory stream
$this->rootStartBlock = self::_GetInt4d($this->data, self::ROOT_START_BLOCK_POS);
// SecID of the first sector of the SSAT (or -2 if not extant)
$this->sbdStartBlock = self::_GetInt4d($this->data, self::SMALL_BLOCK_DEPOT_BLOCK_POS);
// SecID of the first sector of the MSAT (or -2 if no additional sectors are used)
$this->extensionBlock = self::_GetInt4d($this->data, self::EXTENSION_BLOCK_POS);
// Total number of sectors used by MSAT
$this->numExtensionBlocks = self::_GetInt4d($this->data, self::NUM_EXTENSION_BLOCK_POS);
$bigBlockDepotBlocks = array();
$pos = self::BIG_BLOCK_DEPOT_BLOCKS_POS;
$bbdBlocks = $this->numBigBlockDepotBlocks;
if ($this->numExtensionBlocks != 0) {
$bbdBlocks = (self::BIG_BLOCK_SIZE - self::BIG_BLOCK_DEPOT_BLOCKS_POS) / 4;
}
for ($i = 0; $i < $bbdBlocks; ++$i) {
$bigBlockDepotBlocks[$i] = self::_GetInt4d($this->data, $pos);
$pos += 4;
}
for ($j = 0; $j < $this->numExtensionBlocks; ++$j) {
$pos = ($this->extensionBlock + 1) * self::BIG_BLOCK_SIZE;
$blocksToRead = min($this->numBigBlockDepotBlocks - $bbdBlocks, self::BIG_BLOCK_SIZE / 4 - 1);
for ($i = $bbdBlocks; $i < $bbdBlocks + $blocksToRead; ++$i) {
$bigBlockDepotBlocks[$i] = self::_GetInt4d($this->data, $pos);
$pos += 4;
}
$bbdBlocks += $blocksToRead;
if ($bbdBlocks < $this->numBigBlockDepotBlocks) {
$this->extensionBlock = self::_GetInt4d($this->data, $pos);
}
}
$pos = 0;
$this->bigBlockChain = '';
$bbs = self::BIG_BLOCK_SIZE / 4;
for ($i = 0; $i < $this->numBigBlockDepotBlocks; ++$i) {
$pos = ($bigBlockDepotBlocks[$i] + 1) * self::BIG_BLOCK_SIZE;
$this->bigBlockChain .= substr($this->data, $pos, 4 * $bbs);
$pos += 4 * $bbs;
}
$pos = 0;
$sbdBlock = $this->sbdStartBlock;
$this->smallBlockChain = '';
while ($sbdBlock != -2) {
$pos = ($sbdBlock + 1) * self::BIG_BLOCK_SIZE;
$this->smallBlockChain .= substr($this->data, $pos, 4 * $bbs);
$pos += 4 * $bbs;
$sbdBlock = self::_GetInt4d($this->bigBlockChain, $sbdBlock * 4);
}
// read the directory stream
$block = $this->rootStartBlock;
$this->entry = $this->_readData($block);
$this->_readPropertySets();
}
The difference between
$objReader = \PHPExcel_IOFactory::createReader('xlsx' == $ext ? 'Excel2007' : 'Excel5');
and
$objReader = \PHPExcel_IOFactory::createReaderForFile('uploads/' . $name);
The first is trusting that the extension is correct for the actual format of the file, that a file with an extension of .xlsx really is an OfficeOpenXML-format file or an extension of .xls really is a BIFF-format file, and then telling PHPExcel to use the appropriate reader.
This isn't normally a problem unless it isn't (for example) just HTML markup in a file with an .xls or .xlsx extension.... then you're selecting the wrong Reader for the actual format of the file; and this is what MS Excel itself is telling you with its message that "FILE EXTENSION AND THE FILE FORMAT DO NOT MATCH"
The second is using PHPExcel's identify() method to work out what format the file really is (irrespective of what it claims to be based on a false extension), and then selecting the appropriate Reader for that format.
EDIT
Unsure exactly how large your large numbers are, but I'll take a look at the HTML Reader and see if I can identify why it should be giving a boolean false instead of an actual numeric value
I'm uploading an excel file to website and process it for database use.
I'm using toArray() function to get all rows in a php array.
But I want to skip the first row ( header title row). The rest of rows will be stored in array.
How can I skip the first row.
Note : I can't use rangeToArray() function since there is not fixed range to get rows into array. It is dynamic. All i want is get all rows except first.
Eko answers half the problem, you can use rangeToArray(); but you don't need to use a loop at all:
$highestRow = $sheet->getHighestRow();
$highestColumn = $sheet->getHighestColumn();
$sheetData = $sheet->rangeToArray(
'A2:' . $highestColumn . $highestRow,
NULL,TRUE,FALSE
);
Alternatively, use toArray() and then just unset the first element from the returned array
You can achieve that using array_shift this:
$toArray = $worksheet->toArray()
array_shift($toArray);
I create a function to read an excel file using PHPExcel like this below :
function Read_Excel($fname=null,$isheet=0,$irow=1,$icol='A'){
$inputFileName = $fname;
try {
$inputFileType = PHPExcel_IOFactory::identify($inputFileName);
$objReader = PHPExcel_IOFactory::createReader($inputFileType);
$objPHPExcel = $objReader->load($inputFileName);
} catch(Exception $e) {
die('Error loading file "'.pathinfo($inputFileName,PATHINFO_BASENAME).'": '.$e->getMessage());
}
$sheet = $objPHPExcel->getSheet(intval($isheet));
$highestRow = $sheet->getHighestRow();
$highestColumn = $sheet->getHighestColumn();
for ($row = intval($irow); $row <= $highestRow; $row++){
// Read a row of data into an array
$rowData = $sheet->rangeToArray($icol . $row . ':' . $highestColumn . $row,NULL,TRUE,FALSE);
$rec_tbl[] = $rowData[0];
}
return $rec_tbl;
}
you just need to change the $irow=1 in the function parameters to get a row you wanted.
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