2010-12-30 142 views
39

Con el siguiente código, puedo leer las celdas de un archivo de Excel con PHPExcel.¿Cómo saber cuántas filas y columnas leer desde un archivo de Excel con PHPExcel?

Actualmente manualmente define cuántas filas y columnas leer.

Hay una manera en que PHPExcel puede decirme cuántas filas y columnas tengo que leer para sacar todos los datos de la hoja de trabajo, p. incluso si algunas filas y columnas se dejan en blanco?

$file_name = htmlentities($_POST['file_name']); 
$sheet_name = htmlentities($_POST['sheet_name']); 
$number_of_columns = htmlentities($_POST['number_of_columns']); 
$number_of_rows = htmlentities($_POST['number_of_rows']); 

$objReader = PHPExcel_IOFactory::createReaderForFile("data/" . $file_name); 
$objReader->setLoadSheetsOnly(array($sheet_name)); 
$objReader->setReadDataOnly(true); 
$objPHPExcel = $objReader->load("data/" . $file_name); 

echo '<table border="1">'; 
for ($row = 1; $row < $number_of_rows; $row++) { 
    echo '<tr>'; 
    for ($column = 0; $column < $number_of_columns; $column++) { 
     $value = $objPHPExcel->setActiveSheetIndex(0)->getCellByColumnAndRow($column, $row)->getValue(); 
     echo '<td>'; 
     echo $value . '&nbsp;'; 
     echo '</td>'; 
    } 
    echo '</tr>'; 
} 
echo '</table>'; 

Solución:

Gracias, Marcos, aquí está la solución completa con esas funciones:

$file_name = htmlentities($_POST['file_name']); 
$sheet_name = htmlentities($_POST['sheet_name']); 
$number_of_columns = htmlentities($_POST['number_of_columns']); 
$number_of_rows = htmlentities($_POST['number_of_rows']); 

$objReader = PHPExcel_IOFactory::createReaderForFile("data/" . $file_name); 
$objReader->setLoadSheetsOnly(array($sheet_name)); 
$objReader->setReadDataOnly(true); 

$objPHPExcel = $objReader->load("data/" . $file_name); 

$highestColumm = $objPHPExcel->setActiveSheetIndex(0)->getHighestColumn(); 
$highestRow = $objPHPExcel->setActiveSheetIndex(0)->getHighestRow(); 

echo 'getHighestColumn() = [' . $highestColumm . ']<br/>'; 
echo 'getHighestRow() = [' . $highestRow . ']<br/>'; 

echo '<table border="1">'; 
foreach ($objPHPExcel->setActiveSheetIndex(0)->getRowIterator() as $row) { 
    $cellIterator = $row->getCellIterator(); 
    $cellIterator->setIterateOnlyExistingCells(false); 
    echo '<tr>'; 
    foreach ($cellIterator as $cell) { 
     if (!is_null($cell)) { 
      $value = $cell->getCalculatedValue(); 
      echo '<td>'; 
      echo $value . '&nbsp;'; 
      echo '</td>'; 
     } 
    } 
    echo '</tr>'; 
} 
echo '</table>'; 

alt text

Respuesta

61
$objPHPExcel->setActiveSheetIndex(0)->getHighestColumn(); 

y

$objPHPExcel->setActiveSheetIndex(0)->getHighestRow(); 

o

$objPHPExcel->setActiveSheetIndex(0)->calculateWorksheetDimension(); 

que devuelve un rango como una cadena como A1: AC2048

aunque se arrastran filas y columnas en blanco se incluyen en estos.

EDITAR

o puede utilizar los iteradores a recorrer las filas y columnas existentes para obtener cada célula dentro de las hojas de trabajo de gama utilizados. Consulte /Tests/28iterator.php en la distribución de producción para ver un ejemplo. Los iteradores se pueden configurar para ignorar espacios en blanco.

+0

Funciona bien, he publicado mi solución anterior, es bueno saber sobre los iteradores. –

+4

¿Sabes cómo deshacerte de las filas y columnas en blanco al final? –

+0

Encontré que LibreOffice puede generar archivos XLSX con 4 filas, pero el informe PHPExcel 'getHighestRow()' es más de un millón. –

0

no creo que pueda hacer eso, lo haría tiene que pasar desde 1000 y retroceder hasta llegar a la primera celda no en blanco y esa sería su última fila o columna.

puede escribir una macro para hacer esto en Excel que puede ayudar, pero no sé si se puede ejecutar con PHPExcel.

+0

PHPExcel no maneja las macros de Excel en la actualidad ... y es una tarea muy importante para ponerlas en práctica (aunque he trabajado a cabo la mecánica básica, que significa escribir un analizador VB/caja de arena en PHP, que es un gran proyecto en sí mismo) –

+0

¿Y qué sucederá, si espera hasta 100 000 filas, por ejemplo? ¿Comenzarás desde 100 000 hacia atrás? ¿Y qué pasará si el archivo tiene 5 filas? ¡Vas a leer 99 995 células por nada! Vea mi solución simple con muy pocas lecturas de celda (la respuesta de Nikolay Ivanov). –

1

Puede hacer mucho menos lecturas de celda que iterar todas las filas (columnas).

En mi caso, la primera columna es SKU del artículo y es obligatoria.

Si espera un archivo con muchas filas, en mi caso puede ser de 100 000 filas o más, estoy leyendo el valor de la primera columna en cada 10 000 filas.

Si la celda A10000 no está vacía, lea A20000 y así sucesivamente.

De esta manera, para un archivo con 100 000 filas, necesito un máximo de 10 lecturas de una sola celda para decidir en qué segmento de 10 000 filas termina el archivo.

Por ejemplo, digamos que está entre 30 000 y 40 000 filas.

Ahora obtener el promedio del valor por encima de - 35 000. Una lectura de la celda A35000 reducirá aún más el alcance de 5000 filas.El promedio siguiente (y la lectura de celda única) reducirá aún más el alcance a 2500 y así sucesivamente.

Aproximadamente necesitará alrededor de 13-14 lecturas de celda única, si sabe en qué 10 000 segmentos es el final del archivo. Si espera un archivo con 100 000 filas, agregue un máximo de 10 lecturas de celda para determinar el segmento exacto de 10 000 filas. Esto significa un máximo de alrededor de 25 lecturas de celda para archivos con 100 000 filas.

Editar: si espera filas vacías - leído poco más células, por ejemplo, si se espera no más de 1 consecuente fila vacía, lea 2 células consiguientes cada vez, por ejemplo A10000 y A10001, uno de ellos debe no estar vacío, o está más allá del final del archivo. Si no espera más de 2 filas vacías consecutivas, lea 3 celdas cada vez, por ejemplo A10000, A10001 y A10002, y así sucesivamente.

+0

Para los curiosos, esto es básicamente una repetición del Problema de dos huevos. http://stackoverflow.com/questions/4171966/two-egg-problem-confusion –

8

Desde el 1.7.6 y por debajo PHPExcel versiones es posible obtener información de la hoja de trabajo sin tener que leer todo el archivo:

$objReader  = PHPExcel_IOFactory::createReader("Excel2007"); 
$worksheetData = $objReader->listWorksheetInfo($uploadedfile); 
$totalRows  = $worksheetData[0]['totalRows']; 
$totalColumns = $worksheetData[0]['totalColumns']; 
+0

Solo para agregar a esto, si tiene una hoja de trabajo específica en mente, puede hacer coincidir con '$ worksheetData [0] ['worksheetName']'. –

0

Siguiendo @nikolay's pensar de respuesta anterior, he decidido hacer la primera celda de cada fila obligatoria . De esta manera, solo miro cada celda de cada fila primero para descubrir cuántas filas realmente tienen datos, dependiendo de la primera fila.

$uploadedfile = \PHPExcel_IOFactory::load(Yii::getAlias('uploads').'/'.$file_location); 
$uploadeddata = $uploadedfile->getActiveSheet()->toArray(null, true, true, true); 

    //we need to first know how many rows actually have data 
    //my first two rows have column labels, so i start with the third row. 
    $row_count = 3; 
    // read through the data and see how many rows actually have data 
    //the idea is that for every row, the first cell should be mandatory... 
    //if we find one that is not, we stop there... 
    do 
    { 
     $row_count++; 
    } while($uploadeddata[$row_count]['A'] == "null"); 

    //get the actual number of rows with data, removing the column labels 
    $actual_rows = $row_count-3; 
Cuestiones relacionadas