2010-12-30 15 views
39

Con il seguente codice, sono in grado di leggere le celle da un file Excel con PHPExcel.Come scoprire quante righe e colonne leggere da un file Excel con PHPExcel?

Attualmente manualmente definisco quante righe e colonne da leggere.

C'è un modo in cui PHPExcel può dirmi quante righe e colonne devo leggere per ottenere tutti i dati dal foglio di lavoro, ad es. anche se alcune righe e colonne sono vuote?

$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>'; 

Soluzione:

Grazie, Marco, ecco la soluzione completa con le funzioni:

$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

risposta

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

e

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

o

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

che restituisce un intervallo come una stringa come A1: AC2048

sebbene trascinamento righe e colonne vuote sono inclusi in questi.

EDIT

oppure è possibile utilizzare le iteratori per scorrere le righe e le colonne esistenti per ottenere ogni cella all'interno dei fogli di lavoro utilizzati gamma. Vedi /Tests/28iterator.php nella distribuzione di produzione per un esempio. Gli iteratori possono essere impostati per ignorare gli spazi vuoti.

+0

Funziona bene, ho postato la mia soluzione sopra, bello sapere degli iteratori. –

+4

Sai come sbarazzarsi di righe e colonne vuote finali? –

+0

Ho trovato che LibreOffice può generare file XLSX con 4 righe, ma PHPExcel che riporta 'getHighestRow()' deve essere superiore a un milione. –

0

non credo che si può fare, si farebbe passare da inizio a dire 1000 e andare indietro finché non si preme la prima cella non vuota e quella sarà l'ultima riga o colonna.

È possibile scrivere una macro per farlo in Excel, il che può essere di aiuto, ma non so se è possibile eseguirlo con PHPExcel.

+0

PHPExcel non gestisce le macro di Excel attualmente ... ed è un compito piuttosto importante per la loro attuazione (anche se ho elaborato la meccanica di base, significa scrivere un parser VB/sandbox in PHP, che è un grande progetto a sé stante) –

+0

E cosa succederà, se si prevedono fino a 100.000 righe, ad esempio? Partirai da 100.000 all'indietro? E cosa succederà se il file ha 5 righe? Hai intenzione di leggere 99 995 celle per niente! Vedere la mia soluzione semplice con letture di celle molto meno (la risposta di Nikolay Ivanov). –

1

Si può fare molto meno letture di celle che iterare tutte le righe (colonne).

Nel mio caso, la prima colonna è SKU dell'articolo ed è obbligatoria.

Se si prevede un file con molte righe, nel mio caso può essere 100.000 righe o più, sto leggendo il valore della prima colonna ogni 10.000 righe.

Se la cella A10000 non è vuota, leggere A20000 e così via.

In questo modo, per un file con 100.000 righe ho bisogno di max 10 letture di una singola cella per decidere in quale segmento di 10.000 righe il file termina.

Ad esempio, diciamo che è tra 30.000 e 40.000 righe.

Ora ottenere la media dal valore superiore - 35 000. Una lettura della cella A35000 ridurrà ulteriormente l'ambito a 5000 righe.La prossima media (e la singola cella letta) ridurrà ulteriormente lo scope a 2500 e così via.

Approssimativamente occorreranno circa 13-14 letture di celle singole, se sapete in quale segmento di 10.000 è la fine del file. Se si prevede che il file con 100.000 righe aggiunga un massimo di 10 letture di celle per determinare il segmento esatto di 10.000 righe. Questo significa un massimo di circa 25 letture di celle per file con 100.000 righe.

Edit: se ci si aspetta righe vuote - letto poco più celle, per esempio, se ci si aspetta non più di 1 conseguente riga vuota, leggere 2 conseguenti cellule ogni volta, per esempio A10000 e A10001, uno di loro dovrebbe essere non vuoto, o sei oltre la fine del file. Se non si prevedono più di 2 righe vuote consecutive, leggere 3 celle ogni volta, ad esempio A10000, A10001 e A10002 e così via.

+0

Per i curiosi, questo è fondamentalmente un rehash del Two Egg Problem. http://stackoverflow.com/questions/4171966/two-egg-problem-confusion –

8

Dal 1.7.6 e al di sotto PHPExcel versioni è possibile ottenere informazioni foglio di lavoro senza leggere tutto il file:

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

Solo per aggiungere a questo se si ha in mente un foglio di lavoro specifico, è possibile trovare corrispondenza con '$ worksheetData [0] ['worksheetName']'. –

0

seguito @nikolay's pensando di risposta di cui sopra, ho deciso di fare la prima cella di ogni riga obbligatoria . In questo modo, guardo prima ogni cella di ogni riga per scoprire quante righe hanno effettivamente dati, a seconda della prima riga.

$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; 
Problemi correlati