Delete row phpexcel - php

I want to load my file.xls and check if my elements contains the character ^; then, I want to remove it.
Here my code so far:
$objPHPExcel = PHPExcel_IOFactory::load("trainbayes.xlsx");
foreach ($objPHPExcel->getWorksheetIterator() as $worksheet){
$column = 'C';
$lastRow = $worksheet->getHighestRow();
for ($row = 2; $row <= $lastRow; $row++) {
$cell = $worksheet->getCell($column.$row);
if (preg_match("/([\^])/",$cell)){
$objPHPExcel->getActiveSheet()->removeRow($row,$row);
}
}
}
But it didn't work. Can you help me? Thank you :)

$cell = $worksheet->getCell($column.$row);
Returns a Cell object and assigns it to $cell; you are then treating that cell object as though it was a string in your preg_match() call.
Surely you should be checking the value of the cell
$cell = $worksheet->getCell($column.$row)->getValue();
Additionally,
$objPHPExcel->getActiveSheet()->removeRow($row,$row);
Do you really mean to pass $row twice? Second argument is the number of rows to delete, first argument is the row number to start deleting, so if you pass $row is 5, then PHPExcel will delete 5 rows, starting at row number 5.
Surely you mean
$objPHPExcel->getActiveSheet()->removeRow($row, 1);
or simply
$objPHPExcel->getActiveSheet()->removeRow($row);

Related

PHP & CSV - Echo Result only once

i am fairly new to PHP and tried several hours to get something going, sadly without a result. I hope you can point me into the right direction.
So what i got is a CSV file containing Articles. They are separated into diff columns and always the same structure, for example :
ArtNo, ArtName, ColorCode, Color, Size
When an article has different color codes in the CSV, the article is simply repeated with the same information except for the color code, see an example:
ABC237;Fingal Edition;48U;Nautical Blue;S - 5XL;
ABC237;Fingal Edition;540;Navy;S - 5XL;
My problem is, i want to display all the articles in a table, include an article image etc.. so far i got that working which is not a problem, but instead of showing the article twice for every different color code i want to create only one line per ArtNo (First CSV Line) but still read the second duplicate line to add the article color to the first one, like :
ABC237; Fingal Edition ;540;Nautical Blue, Navy;S - 5XL;
Is this even possible or am I going into a complete wrong direction here? My code looks like this
<?php
$csv = readCSV('filename.csv');
foreach ($csv as $c) {
$artNo = $c[0]; $artName = $c[1]; $colorCode = $c[2]; $color = $c[3]; $sizes = $c[4]; $catalogue = $c[5]; $GEP = $c[6]; $UVP = $c[7]; $flyerPrice = $c[8]; $artDesc = $c[9]; $size1 = $c[10]; $size2 = $c[11]; $size3 = $c[12]; $size4 = $c[13]; $size5 = $c[14]; $size6 = $c[15]; $size7 = $c[16]; $size8 = $c[17]; $picture = $c[0] . "-" . $c[2] . "-d.jpg";
// Echo HTML Stuff
}
?>
Read CSV Function
<?php
function readCSV($csvFile){
$file_handle = fopen($csvFile, 'r');
while (!feof($file_handle) )
{
$line_of_text[] = fgetcsv($file_handle, 0, ";");
}
fclose($file_handle);
return $line_of_text;
}
?>
I tried to get along with array_unique etc but couldn't find a proper solution.
Read all the data into an array, using the article number as the key....
while (!feof($file_handle) ) {
$values = fgetcsv($file_handle, 0, ";");
$artno = array_shift($values);
if (!isset($data[$artno])) $data[$artno]=array();
$data[$artno][]=$values;
}
And then output it:
foreach ($data as $artno=>$v) {
$first=each($v);
print $artno . "; " . each($first);
foreach ($v as $i) {
$discard=array_shift($i);
print implode(";", $i);
}
print "\n";
}
(code not tested, YMMV)
You need to know exactly how many items belong to each ArtNo group. This means a loop to group, and another loop to display.
When grouping, I steal the ArtNo from the row of data and use it as the grouping key. The remaining data in the row will be an indexed subarray of that group/ArtNo.
I am going to show you some printf() and sprintf() syntax to keep things clean. printf() will display the first parameter's content and using any subsequent values to replace the placeholders in the string. In this case, the 2nd parameter is a conditional expression. On the first iteration of the group, ($i = 0), we want to show the ArtNo as the first cell of the row and declare the number of rows that it should span. sprinf() is just like printf() except it produces a value (silently). Upon any subsequent iterations of the group, $i will be greater than zero and therefore an empty string is passed as the value.
Next, I'm going to use implode() which is beautifully flexible when you don't know exactly how many columns your table will have (or if the number of columns may change during the lifetime of your project).
Tested Code:
$csv = <<<CSV
ABC237;Fingal Edition;48U;Nautical Blue;S - 5XL
ABC236;Fingal Edition;540;Navy;S - 5XL
ABC237;Fingal Edition;49U;Sea Foam;L - XL
ABC237;Fingal Edition;540;Navy;S - 5XL
CSV;
$lines = explode(PHP_EOL, $csv);
foreach ($lines as $line) {
$row = str_getcsv($line, ';');
$grouped[array_shift($row)][] = $row;
}
echo '<table>';
foreach ($grouped as $artNo => $group) {
foreach ($group as $i => $values) {
printf(
'<tr>%s<td>%s</td></tr>',
(!$i ? sprintf('<td rowspan="%s">%s</td>', count($group), $artNo) : ''),
implode('</td><td>', $values)
);
}
}
echo '</table>';
Output:

PHPExcel loop through rows and columns

Need help identifying weird problem that i'm facing. I did tried searching in stack overflow but didn't find any possible answer.
Here is sample program that works displaying all rows and columns on UI
<?php
date_default_timezone_set('America/Los_Angeles');
require_once 'PHPExcel-1.8/Classes/PHPExcel.php';
include 'PHPExcel-1.8/Classes/PHPExcel/IOFactory.php';
$path = 'demo.xlsx';
$sheet = $objPHPExcel->getSheet(0);
$highestRow = $sheet->getHighestRow();
$highestColumn = $sheet->getHighestColumn();
$highestColumnIndex = PHPExcel_Cell::columnIndexFromString($highestColumn);
for ($row = 2; $row <= $highestRow; ++ $row) {
$val=array();
for ($col = 0; $col < $highestColumnIndex; ++ $col) {
$cell = $worksheet->getCellByColumnAndRow($col, $row);
$val[] = $cell->getValue();
//End of For loop
}
$Col1 = $val[0] ;
$Col2 = $val[1] ;
$Col3 = $val[2];
echo $Col1;
echo $Col2;
echo $Col3;
echo "<br>";
//End of for loop
}
?>
This program works perfectly fine printing all columns and rows for n-lenght
Problem - Now our requirement is to get values of Col1, Col2, Col3 and using mysql_query compare into database and do further action.
Minute we add anything above //End of for loop. It only iterates once and stops without throwing any php errors.
e.g.
.....
echo $Col1;
echo $Col2;
echo $Col3;
echo "<br>";
**$sql = mysql_query("select COALESCE(MAX(SrNo), 0) AS Max_No from TABLEA where ColumnA = 1 and ColumnB = '$Col3'");
$row = mysql_fetch_array($sql);
echo $row["Max_No"];**
//End of for loop
}
?>
If we add above SQL the same program only iterates once and stops? It doesn't show any errors in logs or on screen.
Thanks in advance for your help!.
If you try to iterate with for ($col = 2; $col <= $highestColumn; ++ $col){...} it will work for columns from A to Z, but it fails pass the Z (Ex. iterate between 'A' to 'AB').
In order to iterate pass 'Z', you need to convert the column to integer, increment, compare, and get it as string again:
$MAX_COL = $sheet->getHighestDataColumn();
$MAX_COL_INDEX = PHPExcel_Cell::columnIndexFromString($MAX_COL);
for($index=0 ; $index <= $MAX_COL_INDEX ; $index++){
$col = PHPExcel_Cell::stringFromColumnIndex($index);
// do something, like set the column width...
$sheet->getColumnDimension($col)->setAutoSize(TRUE);
}
With this, you easy iterate pass the 'Z' column.
As you're using the same variable $row for the row number in the Excel iteration and for the result of your select query, it's not surprising that you're running into problems.....
The integer value that holds the Excel row number is being overwritten by the array that you get from your SQL query, and then you're trying to use that result array as the next Excel row number
Solution: Use a different variable for these two elements.
$rowData = mysql_fetch_array($sql);
echo $rowData["Max_No"];**

Adding some data to an array

ok here is some code
$highestRow = 16; // e.g. 10
$highestColumn = 'F'; // e.g 'F'
$highestColumnIndex = PHPExcel_Cell::columnIndexFromString($highestColumn); // e.g. 5
for ($row = 9; $row <= $highestRow; ++$row) {
$val=array(); //i have initialized the array
for ($col = 1; $col <= $highestColumnIndex; ++$col) {
$cell=$objWorksheet->getCellByColumnAndRow($col, $row);
$val[]=$cell->getValue();
}
echo $val[0] //from what is read from excel, it returns data like this 7563
}
How the data was in the excel sheet before, B9 had 75, B10 had 6 and B11 had 3
After reading i echo $val[0] //output 7563
Now i would like to add additional data to the result so if i echo $val[0] after adding the info it shows the output as
echo $val[0] //output average=75% ; rsd = 6%; n=3% instead of just 7563
foreach ($k as $key=>$value) {
echo $key."=".$value."; ";
}
Depending on the type of array that you have you can either directly edit it as a string, or you have to turn it into a string.
If the value is already a string you can simply do string manipulation, you can create a temporary or use the original string and edit it all at once to be echoed, depends on what you prefer.
$strTemp = "output average=substr($var[0],0,2)% ; "rsd =substr($var[0]%,2,1); n=substr($var[0]%,3,1);" //can also use $var[0] instead of strTemp
If the values are in integer format you will have to turn the values into strings and then you can move on from there. If you don't know how, I advise this thread: Converting an integer to a string in PHP
Another thing, I'd advise storing the numbers in different parts of the array, that way its easier to reference them and tell them apart.

Trouble with adding to array in while loop

I have a while loop that uses the fgetcsv function and iterates through a csv file until the end. In the loop I want to add a value from a specific column to a new array.
Everything works as it echos the value from the column that I need. However when I put the line in to add to the array it does not work. I have a HTML table that prints after the PHP code however when I use the line to add to the array it does not work.
I have looked on the internet and everything I have seen is doing it the way I have done so I am a little confused.
Here is my code:
$amountRecords = 0;
$totalValue = 0;
$valueArray = array();
$handle = fopen('data.csv', 'r');
// to skip the header names/values
fgetcsv($handle);
while($row = fgetcsv($handle, "\r"))
{
$valueArray[$amountRecords] += $row[1]; // THIS IS THE LINE THAT IS NOT WORKING
$totalValue = $totalValue + $row[1];
$amountRecords++;
}
There is some strangeness with your code. You're incrementing $amountRecords each time, so you'll never access the same index in $valueArray twice, yet, you're adding values to each element. Possibly you simply mean to assign the value with $valueArray[$amountRecords] = $row[1]; instead of +=?
If that's the case, it looks like you're simply attempting to add the item onto the end of the array, extracting column 1 into its own array. You should use array_push or array[]= syntax for that:
while($row = fgetcsv($handle, "\r"))
{
// Add $row[1] to the end of $valueArray
$valueArray[] = $row[1];
$totalValue = $totalValue + $row[1];
}
The += operator is for adding something to an existing value. Typing a += b is the same as typing a = a + b. You should be using that operator on the next line, for example:
$totalValue += $row[1];
As a final suggestion, learn to do some basic debugging. If your loop isn't working, make it show you what it's doing during each iteration. Use var_dump to inspect your variables and make sure they actually contain what you think they contain. Using var_dump($row) would be especially useful in making sure that $row[1] is the correct index.
echo "Before loop\n";
while($row = fgetcsv($handle, "\r"))
{
echo '$row contains: ';
var_dump($row);
$valueArray[] += $row[1]; // THIS IS THE LINE THAT IS NOT WORKING
echo '$valueArray now contains ':
var_dump($valueArray);
$totalValue = $totalValue + $row[1];
}
echo "After loop\n";
From my understand of your script $valueArray[$amountRecords] += $row[1]; would not make any logical sense because its dependent on $amountRecords ++; which would always increase .
I think your script would work fine like this
while ( $row = fgetcsv($handle, "\r") ) {
$valueArray[] = $row[1]; // Put all Row[1] Into a array
$totalValue += $row[1]; // Sum total Value
$amountRecords ++; //Get Record Count
}

PHPExcel Column Loop

How can I do a loop which based on Excel worksheet columns? I found (and used) WorksheetIterator, RowIterator and CellIterator but nothing about columns.
There is no ColumnIterator, so you'll have to do this by hand.
For any given worksheet:
To loop rows for a column:
$column = 'A';
$lastRow = $worksheet->getHighestRow();
for ($row = 1; $row <= $lastRow; $row++) {
$cell = $worksheet->getCell($column.$row);
// Do what you want with the cell
}
To loop columns in a row, you can take advantage of PHP's Perls-style ability to increment characters:
$row = 1;
$lastColumn = $worksheet->getHighestColumn();
$lastColumn++;
for ($column = 'A'; $column != $lastColumn; $column++) {
$cell = $worksheet->getCell($column.$row);
// Do what you want with the cell
}
Note that when comparing column letters to test for the last column in the loop, we can't simply use < or <= because we're comparing strings, and "B" > "AZ" in standard string comparison, so we use a != comparison, having incremented the highest column value to give the first column ID past the end point.
You can also use
$worksheet->cellExists($column.$row);
in the loop to test for the existence of a cell before accessing it using getCell() (or not) to emulate the iterator getIterateOnlyExistingCells() behaviour
The iterators are actually fairly slow, so you may well find these simple loops are faster than using the iterators.
UPDATE (2015-05-06)
PHPExcel version 1.8.1 has introduced a new Column Iterator. The Row and Column iterators also allows you to specify a range of rows or columns to iterate, and allow you to use prev() and well as next() when looping through
This short snippet provides loop throught rows of columns.
It gets the indexes of last non empty column (and its row) and loops to that indexes, so be aware of forgotten values in excel.
Code loops throught rows of column A, then rows of column B ...
$objReader = new PHPExcel_Reader_Excel2007();
$objReader->setReadDataOnly(true);
$objPHPExcel = $objReader->load($file);
foreach ($objPHPExcel->getWorksheetIterator() as $worksheet)
{
$worksheetTitle = $worksheet->getTitle();
$highestColumn = $worksheet->getHighestColumn();
$highestColumnIndex = PHPExcel_Cell::columnIndexFromString($highestColumn);
// expects same number of row records for all columns
$highestRow = $worksheet->getHighestRow();
for($col = 0; $col < $highestColumnIndex; $col++)
{
// if you do not expect same number of row records for all columns
// get highest row index for each column
// $highestRow = $worksheet->getHighestRow();
for ($row = 1; $row <= $highestRow; $row++)
{
$cell = $worksheet->getCellByColumnAndRow($col, $row);
$val = $cell->getValue();
// do what you want with cell value
}
}
}
loop columns as range
foreach ( range('A', $Excel->getActiveSheet()->getHighestColumn()) as $column_key) {
}
Try this! Work!
$limit = 10000;
$value='sua mensagem'
for($i=0,$j='A';$i<$limit;$i++,$j++) {
$objPHPExcel->setActiveSheetIndex(0)
->setCellValue($j.$i, $value);
}
set in $value what you want print.
This is the fix for the getColumnLetter method of the last message, it allows you to get the "letters" of the columns, whatever the number of columns you have
function getColumnLetter( $number ){
$prefix = '';
$suffix = '';
$prefNum = intval( $number/26 );
if( $number > 25 ){
$prefix = getColumnLetter( $prefNum - 1 );
}
$suffix = chr( fmod( $number, 26 )+65 );
return $prefix.$suffix;
}
This recursive method was designed allows you to get the "letters" of the columns, whatever the number of columns you have, from "A" to "ZZZZZZZZZ..." :
function getColumnLetter( $number )
{
$prefix = '';
$suffix = '';
$prefNum = intval( $number/26 );
if( $prefNum > 25 )
{
$prefix = getColumnLetter( $prefNum );
}
$suffix = chr( fmod( $number, 26 )+65 );
return $prefix.$suffix;
}
So you can loop the columns of an PHP array on index number and convert it to a string of letters and use it in PHPExcel methods, like "setCellValue" ...
But solutions above are surely faster if you can use them !
In PhpSpreadsheet ( which replaces PHPExcel ) you can do:
foreach( $sheet->getColumnIterator() as $col )
{
$sheet->getColumnDimension( $col->getColumnIndex() )->setAutosize( true );
}

Categories