Archivi delle etichette: library

Leggere un foglio di calcolo .ods in Go

Sommario

Una breve descrizione di come leggere il contenuto di un foglio di calcolo nel formato Open Document Format di estensione .ods con una piccola libreria in Go.

Obiettivo

Dato un foglio di calcolo di Libre Office od anche di Apache Open Office vorremmo leggere il contenuto della cella “A1” della prima tabella, utilizzando il Go, il linguaggio open source creato da Google.

I prerequisiti per poter essere operativi e tentare la sfida sono: un file nel formato OpenDocument, standard ISO, di un foglio di calcolo naturalmente, ed una installazione di Go per il vostro sistema operativo.

Un piccolo trucco

Sappiamo che il file di estensione .ods è in realtà un file compresso contenente dati xml. Occorre quindi decomprimere il file, leggere all’interno il file relativo ai dati ed interpretare il codice testuale xml.

Ebbene, il piccolo trucco consiste proprio in questo: procurarsi una libreria già pronta che fa tutto questo per noi. Guarda caso una libreria così esiste davvero ed è ospitata su github e messa gentilmente a disposizione per l’uso e lo sviluppo libero da knieriem.
Lo sviluppo comunitario è qualcosa di incredibile anche per il numero elevatissimo di progetti, qualcosa che a pensarci mi sorprende sempre. Grazie davvero.

La libreria odf contiene pochissimi file ed è, al momento, praticamente priva di documentazione, ma può leggere e scrivere fogli di calcolo nel formato aperto della collezione OpenDocument.

Per installarla un semplice comando farà al caso nostro e se va tutto bene ci vuole veramente un attimo:

 $ go get github.com/knieriem/odf

Il codice di lettura del file ods

Bene, adesso tocca a noi!
Diamo al file del foglio elettronico il nome di “test.ods” (questo nome lo ritroveremo nel sorgente) e posizioniamolo in una directory assieme al nostro sorgente che per adesso è ancora un file vuoto.

La prima cosa che dovrà fare il programma, a regola, è aprire il file in lettura. Dunque proviamo questo primo codice in Go (prima di poterlo eseguire naturalmente occorre compilarlo):

package main

import (
	"github.com/knieriem/odf/ods"
	"fmt"
	)

func main() {
	f, err := ods.Open("test.ods")
	if err != nil {
		fmt.Println(err)
		return
	}
	defer f.Close()
}

Il programma non fa ancora nulla: semplicemente apre il foglio elettronico ed esce, e serve solo per provare che sia tutto a posto e per cominciare, perché no, a prendere confidenza con la sintassi del Go.

Leggere il contenuto della cella

Siamo pronti per chiudere la sfida (a nostro favore ovvio). Il prossimo passo una volta aperto il file è quello di leggerne il contenuto. La libreria odf mette a disposizione la funzione ParseContent() che accetta come parametro il puntatore ad una struct documento e restituisce un eventuale errore.
Per saperne di più sui puntatori basta leggere i precedenti post sull’argomento in particolare questo.

Disponendo ora del documento possiamo accedere tramite alcuni metodi (ancora in corso di esplorazione da parte mia), ai dati del foglio elettronico ed in particolare possiamo osare nell’ordine a fare:

  1. stampare il numero delle tabelle contenute nel file;
  2. stampare il nome del primo foglio di calcolo;
  3. stampare (finalmente) il contenuto della cella A1;

Ecco il listato completo che chiude questa breve esplorazione.

Ma prima un saluto a tutti, ed in particolare a Juhan che non credo possa fare altrettanto con i linguaggi che frequenta lui: uno ha il nome di un temibile serpente, un altro somiglia ad una pietra preziosa di colore rosso, eccetera.
🙂

package main

import (
	"github.com/knieriem/odf/ods"
	"fmt"
	)

func main() {
	f, err := ods.Open("./test.ods")
	if err != nil {
		fmt.Println(err)
		return
	}
	defer f.Close()

	// parsing del contenuto del file
	var doc ods.Doc
	if err := f.ParseContent(&doc); err != nil {
		fmt.Println(err)
		return
	}

	// stampa il numero di tabelle
	fmt.Println(len(doc.Table))

	// stampa il nome del primo foglio
	fmt.Println(doc.Table[0].Name)

	// stampa cella "A1"
	firstrow := doc.Table[0].Strings()[0]
	fmt.Println(firstrow[0])
}