114 lines
2.3 KiB
Go
114 lines
2.3 KiB
Go
package gocsvtable
|
|
|
|
import (
|
|
"encoding/csv"
|
|
"fmt"
|
|
"io"
|
|
"os"
|
|
)
|
|
|
|
type GoCSVtable struct {
|
|
file *csv.Reader
|
|
rows int
|
|
data [][]string
|
|
Headers map[string]int
|
|
|
|
Separator rune
|
|
Comment rune
|
|
|
|
lastRow int
|
|
|
|
// Row is the active CSV row, the data will start at 1
|
|
Row int
|
|
}
|
|
|
|
func (gct *GoCSVtable) OpenCSV(filename string) error {
|
|
osfile, err := os.Open(filename)
|
|
if err != nil {
|
|
return fmt.Errorf("Not possible to os.Open file: %s\n", err)
|
|
}
|
|
defer osfile.Close()
|
|
|
|
// The default rune is 0
|
|
if gct.Separator != 0 {
|
|
gct.file.Comma = gct.Separator
|
|
}
|
|
|
|
// The default rune is 0
|
|
if gct.Comment != 0 {
|
|
gct.file.Comment = gct.Comment
|
|
}
|
|
|
|
gct.file = csv.NewReader(osfile)
|
|
gct.data, err = gct.file.ReadAll()
|
|
if err != nil {
|
|
return fmt.Errorf("Not possible to csv.ReadAll file: %s\n", err)
|
|
}
|
|
|
|
gct.getHeaders()
|
|
|
|
// First data row is 1
|
|
gct.Row = 1
|
|
|
|
// Last row number
|
|
gct.lastRow = len(gct.data) - 1
|
|
|
|
return nil
|
|
}
|
|
|
|
// getHeaders will associate the Headers names with the correct column number
|
|
func (gct *GoCSVtable) getHeaders() {
|
|
header := gct.data[0]
|
|
columnsNumber := len(header)
|
|
|
|
// Initiate Headers
|
|
gct.Headers = make(map[string]int)
|
|
|
|
for field := 0; field < columnsNumber; field++ {
|
|
name := header[field]
|
|
gct.Headers[name] = field
|
|
}
|
|
}
|
|
|
|
// Next will jump to the next CSV row. If file is over, will return an io.EOF
|
|
func (gct *GoCSVtable) Next() error {
|
|
|
|
if gct.Row >= gct.lastRow {
|
|
return io.EOF
|
|
}
|
|
gct.Row++
|
|
return nil
|
|
}
|
|
|
|
// GetNumberOfRows will return the number of data rows, not considering the
|
|
// header
|
|
func (gct *GoCSVtable) GetNumberOfRows() int {
|
|
return gct.lastRow
|
|
}
|
|
|
|
// Read return a specific field from active row
|
|
func (gct *GoCSVtable) Read(field string) string {
|
|
col := gct.Headers[field]
|
|
return gct.data[gct.Row][col]
|
|
}
|
|
|
|
// Read and return the entire row
|
|
func (gct *GoCSVtable) ReadRow(row int) ([]string, error) {
|
|
if row > gct.lastRow {
|
|
return []string{}, fmt.Errorf("Not possible to read row %v. Data has max of %v rows.\n", row, gct.lastRow)
|
|
}
|
|
return gct.data[row], nil
|
|
}
|
|
|
|
// ReadCol will return a slice with all row values from a single column (field)
|
|
func (gct *GoCSVtable) ReadCol(field string) ([]string, error) {
|
|
data := []string{}
|
|
fieldNumber := gct.Headers[field]
|
|
|
|
for row := 1; row <= gct.lastRow; row++ {
|
|
data = append(data, gct.data[row][fieldNumber])
|
|
}
|
|
|
|
return data, nil
|
|
}
|