PHPExcel How to get only 1 cell value? - php

I would think that a getCell($X, $y) or getCellValue($X, $y) would be available for one to easily pick a a certain value. This can be usefully, as example crosscheck data prior to a larger process.
How do you get a specific value from say cell C3.
I do not want an array of values to sort through.

Section 4.5.2 of the developer documentation
Retrieving a cell by coordinate
To retrieve the value of a cell, the cell should first be retrieved from the worksheet using the getCell method. A cell’s value can be read again using the following line of code:
$objPHPExcel->getActiveSheet()->getCell('B8')->getValue();
Section 4.5.4 of the developer documentation
Retrieving a cell by column and row
To retrieve the value of a cell, the cell should first be retrieved from the worksheet using the getCellByColumnAndRow method. A cell’s value can be read again using the following line of code:
// Get cell B8
$objPHPExcel->getActiveSheet()->getCellByColumnAndRow(1, 8)->getValue();
If you need the calculated value of a cell, use the following code. This is further explained in 4.4.35
// Get cell B8
$objPHPExcel->getActiveSheet()->getCellByColumnAndRow(1, 8)->getCalculatedValue();

By far the simplest - and it uses normal Excel co-ordinates:
// Assuming $sheet is a PHPExcel_Worksheet
$value = $sheet->getCell( 'A1' )->getValue();
You can separate the co-ordinates out in a function if you like:
function getCell( PHPExcel_Worksheet $sheet, /* string */ $x = 'A', /* int */ $y = 1 ) {
return $sheet->getCell( $x . $y );
}
// eg:
getCell( $sheet, 'B', 2 )->getValue();

This is a source based answer feel free to improve or comment.
function toNumber($dest)
{
if ($dest)
return ord(strtolower($dest)) - 96;
else
return 0;
}
function myFunction($s,$x,$y){
$x = toNumber($x);
return $s->getCellByColumnAndRow($x, $y)->getFormattedValue();
}
$objReader = PHPExcel_IOFactory::createReader($inputFileType);
$objPHPExcel = $objReader->load($inputFileName);
$objPHPExcel->setActiveSheetIndex(0);
$sheetData = $objPHPExcel->getActiveSheet();
$cellData = myFunction($sheetData,'B','2');
var_dump($cellData);
This does not work past the letter Z, and could be improved but works for my needs.

Related

Read excel sheet containing merged cells using PHPExcel

I want to read an excel sheet completely and using AJAX send each row to another page for processing. So I have used the following code for converting the excel sheet data into JSON array(Reference PHPExcel example provided in Library):
<?php
error_reporting(E_ALL);
set_time_limit(0);
date_default_timezone_set('Asia/Kolkata');
set_include_path(get_include_path() . PATH_SEPARATOR . 'PHPExcel-1.8/Classes/');
require_once 'PHPExcel/IOFactory.php';
$inputFileType = PHPExcel_IOFactory::identify($fileLocation);
$objReader = PHPExcel_IOFactory::createReader($inputFileType);
$objReader->setLoadSheetsOnly("SHEETNAME");
$objPHPExcel = $objReader->load($fileLocation);
$data = $objPHPExcel->getActiveSheet()->toArray(null,true,true,true);
?>
Here $filelocation is the location of the uploaded file which is to be read for sending the rows individually using AJAX to another page.
I am using $data in javascript as
DataToBeUploaded=<?php echo json_encode($data);?>;
But the excel sheet contains some merged cells so PHPExcel is not able to read the values in these merged cells. Hence values in these cells are read as NULL.
Is there a way where I can use the merged cells' upper left cell value for all of the subsequent cells? (Actually in my case cells are merged vertically only)
Eg.
I have (Assume rows are numbered from 1 and columns from A)
Here PHPExcel reads this as:
data[1][A]='abc'
$data[1][B]='123'
$data[2][A]=''
$data[2][B]='456'
$data[3][A]=''
$data[3][B]='789'
I want the snippet to result in these values:
data[1][A]='abc'
$data[1][B]='123'
$data[2][A]='abc'
$data[2][B]='456'
$data[3][A]='abc'
$data[3][B]='789'
Referring to https://github.com/PHPOffice/PHPExcel/issues/643
I have written the following snippet:
$referenceRow=array();
for ( $row = 2; $row <= $noOfBooks; $row++ ){
for ( $col = 0; $col < 7; $col++ ){
if (!$objPHPExcel->getActiveSheet()->getCellByColumnAndRow( $col, $row )->isInMergeRange() || $objPHPExcel->getActiveSheet()->getCellByColumnAndRow( $col, $row )->isMergeRangeValueCell()) {
// Cell is not merged cell
$data[$row][$col] = $objPHPExcel->getActiveSheet()->getCellByColumnAndRow( $col, $row )->getCalculatedValue();
$referenceRow[$col]=$data[$row][$col];
//This will store the value of cell in $referenceRow so that if the next row is merged then it will use this value for the attribute
} else {
// Cell is part of a merge-range
$data[$row][$col]=$referenceRow[$col];
//The value stored for this column in $referenceRow in one of the previous iterations is the value of the merged cell
}
}
}
This will give the result exactly as required

PHPExcel: Value not available (#N/A) from formula in Excel spreadsheet [duplicate]

I have the following Excel file:
I read it in by looping over every cell and getting the value with getCell(...)->getValue():
$highestColumnAsLetters = $this->objPHPExcel->setActiveSheetIndex(0)->getHighestColumn(); //e.g. 'AK'
$highestRowNumber = $this->objPHPExcel->setActiveSheetIndex(0)->getHighestRow();
$highestColumnAsLetters++;
for ($row = 1; $row < $highestRowNumber + 1; $row++) {
$dataset = array();
for ($columnAsLetters = 'A'; $columnAsLetters != $highestColumnAsLetters; $columnAsLetters++) {
$dataset[] = $this->objPHPExcel->setActiveSheetIndex(0)->getCell($columnAsLetters.$row)->getValue();
if ($row == 1)
{
$this->column_names[] = $columnAsLetters;
}
}
$this->datasets[] = $dataset;
}
However, although it reads in the data fine, it reads in the calculations literally:
I understand from discussions like this one that I can use getCalculatedValue() for calculated cells.
The problem is that in the Excel sheets I am importing, I do not know beforehand which cells are calculated and which are not.
Is there a way for me to read in the value of a cell in a way that automatically gets the value if it has a simple value and gets the result of the calculation if it is a calculation?
Answer:
It turns out that getCalculatedValue() works for all cells, makes me wonder why this isn't the default for getValue() since I would think one would usually want the value of the calculations instead of the equations themselves, in any case this works:
...->getCell($columnAsLetters.$row)->getCalculatedValue();
getCalculatedValue() seems to work for all cells, see above
If you are unsure about the content of a cell (value or formula included),
I recommend you to primarily do a check if the cell has a formula and then copy - paste accordingly. getOldCalculatedValue() is very helpful in this case. Here is an example of that:
$code = $sheet->getCell('A'.$y)->getValue();
if(strstr($code,'=')==true)
{
$code = $sheet->getCell('A'.$y)->getOldCalculatedValue();
}
$objPHPExcel4->setActiveSheetIndex(0)
->setCellValue('A'.$l, $code);
For large data sets, getCalculatedValue() function is really cumbersome and lots of memory will be required to perform correctly.
Looks like getCalculatedValue() is deprecated. Try using getFormattedValue() instead.
getCalculatedValue() seems to do the right job you wanted. It will return the correct value if the cell contains FBV ( formula based value ). If not then the normal value will be returned instead.
getCalculatedValue
seems to work for all cells
$sheets = $spreadsheet->getAllSheets();
$priceCasegetCellByColumnAndRow = $sheet->getCellByColumnAndRow(14, ($key))->getCalculatedValue()
$priceCasegetCell = $sheet->getCell('O' . $key)->getCalculatedValue();
I have never imported an excel file in PHP so this is just a stab in the dark.
Why not check the first character in the cell for an "="
If true getCalculatedValue()
if not getCell()

Merging cells in Excel by rows and columns together using PHPExcel

I need to merge cells in Excel (xlsx) by rows and again by columns using PHPExcel. I tried the following.
$sheet->mergeCells("G".($row_count+1).":G".($row_count+4));
$sheet->mergeCells("H".($row_count+1).":H".($row_count+4));
$sheet->mergeCells("I".($row_count+1).":I".($row_count+4));
Where the variable $row_count has some unpredictable dynamic value like 25, 50, 75 and so on (no regular pattern).
It merges the cells as shown in the preceding snap shot as can be seen immediately below the Note cell. After merging these cells by rows, I'm trying to merge them by columns as follows.
$sheet->mergeCells("G".($row_count+1).":I".($row_count+1));
but it doesn't work. When I try to open the excel file, it asks for a confirmation (with a confirmation box)
Excel found unreadable content in 'report.xlsx'. Do you want to
recover the contents of this workbook? If you trust the source of this
workbook, click Yes.
How to merge cells by rows and columns together in Excel then?
Merging simply requires a valid range of cells like A1:B2, so your
$sheet->mergeCells("G".($row_count+1).":I".($row_count+1));
should work without any problem.
Can you please experiment with a simple test case to prove that this is causing you a problem, and not something else in your script
EDIT
After rereading your question:
Your problem may be that you're trying to merge cells that are already part of a merge range, rather than merging each row, then trying to merge by column, try merging the full rangein one go.
$sheet->mergeCells("G".($row_count+1).":I".($row_count+4));
There is one more method for cell merging
/**
* Set merge on a cell range by using numeric cell coordinates
*
* #param int $pColumn1 Numeric column coordinate of the first cell
* #param int $pRow1 Numeric row coordinate of the first cell
* #param int $pColumn2 Numeric column coordinate of the last cell
* #param int $pRow2 Numeric row coordinate of the last cell
* #throws Exception
* #return PHPExcel_Worksheet
*/
public function mergeCellsByColumnAndRow($pColumn1 = 0, $pRow1 = 1, $pColumn2 = 0, $pRow2 = 1)
function cellsToMergeByColsRow($start = -1, $end = -1, $row = -1){
$merge = 'A1:A1';
if($start>=0 && $end>=0 && $row>=0){
$start = PHPExcel_Cell::stringFromColumnIndex($start);
$end = PHPExcel_Cell::stringFromColumnIndex($end);
$merge = "$start{$row}:$end{$row}";
}
return $merge;
}
Addition to the case:
$objPHPExcel->getActiveSheet()->mergeCells(cellsToMergeByColsRow(0,2,3))
I make a simple function to calc cells to merge by cols and row.
function cellsToMergeByColsRow($start = NULL, $end = NULL, $row = NULL){
$merge = 'A1:A1';
if($start && $end && $row){
$start = PHPExcel_Cell::stringFromColumnIndex($start);
$end = PHPExcel_Cell::stringFromColumnIndex($end);
$merge = "$start{$row}:$end{$row}";
}
return $merge;
}
And call
$sheet->mergeCells(cellsToMergeByColsRow($col, $col+5, $row));
Thanks #Mark Baker
I was also looking solution for this question. where i want to merge cell and put content (value) on that. After few search i got some solution on this. but did not checked because i am using Maatawebsite for get Excel file.
But any one can try thing.. Solution is based on PHPExcel nit sure ,it will work on Maatawebsite.
Source Link
Merge from column A row 1 to column E row 1
$objPHPExcel->getActiveSheet()->mergeCells('A1:E1');
// add some text
$objPHPExcel->getActiveSheet()->setCellValue('A1','The quick brown fox.');
Merge from column A row 1 to column E row 3
$objPHPExcel->getActiveSheet()->mergeCells('A1:E3');
// add some text
$objPHPExcel->getActiveSheet()->setCellValue('A1','The quick brown fox.');
I checked maatawebsite document and they have same method mergeCells. so i think i would be work.
This Solution from Maatawebste.
$sheet->cells('A1:C1', function($cells) {
$cells->setBorder('thin', 'thin', 'thin', 'thin');
});
$sheet->mergeCells('A1:C1');
Solution 2nd
$sheet->setMergeColumn(array(
'columns' => array('A','B','C','D'),
'rows' => array(
array(2,3),
array(5,11),
)
));
$sheet -> mergeCellsByColumnAndRow($col1, $row1, col2, row2);
is the function.

PHPExcel. How to check if current cell is merged with another?

I use PHPExcel to import Excel files to my site. For example, there is two cells, A1 and A2, both merged. Is there a way to to find out is A1 merged to another cell (A2 or other) or not?
$workbook = new PHPExcel;
$sheet = $workbook->getActiveSheet();
$sheet->mergeCells('A1:E1');
$cell = $sheet->getCell('A1');
// Check if cell is merged
foreach ($sheet->getMergeCells() as $cells) {
if ($cell->isInRange($cells)) {
echo 'Cell is merged!'
break;
}
}
I think there isn't better solution because of the way phpexcel stores information about merged cells.
The easiest way is to use the getMergeRange() method.
if ($cell->getMergeRange()) {
// cell is merged
}
I suspect many people will want to know the value of the merged cell, in which case you can refer to the following code:
if (($range = $cell->getMergeRange()) && !$cell->isMergeRangeValueCell()) {
$first_in_range_coordinates = strtok($range, ':');
$value = $sheet->getCell($first_in_range_coordinates)->getValue();
}

How to automatically read in calculated values with PHPExcel?

I have the following Excel file:
I read it in by looping over every cell and getting the value with getCell(...)->getValue():
$highestColumnAsLetters = $this->objPHPExcel->setActiveSheetIndex(0)->getHighestColumn(); //e.g. 'AK'
$highestRowNumber = $this->objPHPExcel->setActiveSheetIndex(0)->getHighestRow();
$highestColumnAsLetters++;
for ($row = 1; $row < $highestRowNumber + 1; $row++) {
$dataset = array();
for ($columnAsLetters = 'A'; $columnAsLetters != $highestColumnAsLetters; $columnAsLetters++) {
$dataset[] = $this->objPHPExcel->setActiveSheetIndex(0)->getCell($columnAsLetters.$row)->getValue();
if ($row == 1)
{
$this->column_names[] = $columnAsLetters;
}
}
$this->datasets[] = $dataset;
}
However, although it reads in the data fine, it reads in the calculations literally:
I understand from discussions like this one that I can use getCalculatedValue() for calculated cells.
The problem is that in the Excel sheets I am importing, I do not know beforehand which cells are calculated and which are not.
Is there a way for me to read in the value of a cell in a way that automatically gets the value if it has a simple value and gets the result of the calculation if it is a calculation?
Answer:
It turns out that getCalculatedValue() works for all cells, makes me wonder why this isn't the default for getValue() since I would think one would usually want the value of the calculations instead of the equations themselves, in any case this works:
...->getCell($columnAsLetters.$row)->getCalculatedValue();
getCalculatedValue() seems to work for all cells, see above
If you are unsure about the content of a cell (value or formula included),
I recommend you to primarily do a check if the cell has a formula and then copy - paste accordingly. getOldCalculatedValue() is very helpful in this case. Here is an example of that:
$code = $sheet->getCell('A'.$y)->getValue();
if(strstr($code,'=')==true)
{
$code = $sheet->getCell('A'.$y)->getOldCalculatedValue();
}
$objPHPExcel4->setActiveSheetIndex(0)
->setCellValue('A'.$l, $code);
For large data sets, getCalculatedValue() function is really cumbersome and lots of memory will be required to perform correctly.
Looks like getCalculatedValue() is deprecated. Try using getFormattedValue() instead.
getCalculatedValue() seems to do the right job you wanted. It will return the correct value if the cell contains FBV ( formula based value ). If not then the normal value will be returned instead.
getCalculatedValue
seems to work for all cells
$sheets = $spreadsheet->getAllSheets();
$priceCasegetCellByColumnAndRow = $sheet->getCellByColumnAndRow(14, ($key))->getCalculatedValue()
$priceCasegetCell = $sheet->getCell('O' . $key)->getCalculatedValue();
I have never imported an excel file in PHP so this is just a stab in the dark.
Why not check the first character in the cell for an "="
If true getCalculatedValue()
if not getCell()

Categories