Buena pregunta...
Yo el método que uso es hacer un bucle por las filas mientras exista contenido en la columna que yo sé que siempre debe contener información.
Using perl Syntax Highlighting
- my $BASE = ReadData($FICHERO_BASE, cells => 0, attr => 1);
- die "ERROR: Base de datos no encontrada" if not $BASE;
- my %HOJAS = %{$BASE->[0]->{sheet}}; # Relación hojas -> índices
- my $HOJA = $BASE->[ $HOJAS{$sector} ]->{cell}; # Referencia a la hoja $sector
- for (my $fila = 1; $HOJA->[$columna]->[$fila]; $fila++) {
- # Hacer algo con el contenido de la celda $HOJA->[$columna]->[$fila]
- }
Coloreado en 0.003 segundos, usando GeSHi 1.0.8.4
Este trozo de código hace lo siguiente:
- Leemos el fichero Excel. Como opciones, le indico (cells=>0) que no estoy interesado en que cree los accesos del tipo {A3}, sino que voy a acceder usando las coordenadas de fila y columna. Además (attr=>1) quiero que me saque otra estructura matricial semejante a las celdas, con los atributos de cada celda, porque quiero saber si lo que contienen son números, fórmulas o con qué codificación está escrito el texto que hay en la celda.
- Si no ha podido leerlo, terminamos.
- Inicializo el diccionario %HOJAS con los nombres de las hojas presentes en el libro Excel. Resulta que Spreadsheet::Read guarda en el arreglo que crea, en el elemento [0], una serie de informaciones. Una de ellas es un hash con datos del libro Excel. Y una de las claves es 'sheet', que contiene una referencia a otro hash que relaciona el nombre de cada hoja con el número de hoja dentro del libro. Así, si sabemos que la hoja se llama 'Hoja 1', esto nos indicará que es la hoja 1 (o la 2 o la 3, etc.) del libro Excel. Esto nos servirá para la siguiente línea.
- $sector contiene el nombre de la hoja. Así que $HOJAS{$sector} nos devuelve el número que es esa hoja dentro del libro. Ese número lo usamos como índice dentro de todo el libro $BASE, y con eso apuntamos a la hoja. De ella, nos interesa solo las celdas, así que extraemos una referencia a ellas que está bajo la clave 'cell'. Al final, en $HOJA tenemos una referencia a una estructura bidimensional de las celdas.
- Aquí, inicializo $fila a 1 porque los objetos Spreadsheet::Read lo hacen de esa manera, para facilitar el acceso. En cada vuelta, lo voy incrementando. Y el bucle se termina si el contenido de la celda no contiene ningún valor (o un valor indefinido), en la $columna y $fila correspondiente.
Pero... hay una forma más cómoda... Spreadsheet::Read sí que guarda el número máximo de filas y columnas. Lo hace como atributos de la hoja. En nuestro ejemplo, sería con
Using perl Syntax Highlighting
my $maximo_filas = $BASE->[ $HOJAS{$sector} ]->{maxrow};
my $maximo_cols = $BASE->[ $HOJAS{$sector} ]->{maxcol};
my $maximo_cols = $BASE->[ $HOJAS{$sector} ]->{maxcol};
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
y a partir de aquí ya se puede hacer un bucle.
Using perl Syntax Highlighting
El porqué lo hago de la primera manera es porque estoy seguro que mi $columna contiene datos en todas las filas con información. Si lo hago de la segunda manera, es posible que haga ciclos sobre filas que no contienen información interesante (hay muchos casos en los que hay hojas Excel con filas que aparentemente no contienen información, pero sí estilos, o que tuvieron información y luego se borró, pero mantienen la información de formato de celda).