Parse xlsx with go

Hi all
I’ve found package excelize for work with xlsx files
And now I’m trying to parse my file to a struct fields
my code

type Test struct {
	field1 string
	field2 string
	field2 string
}

func main() {

var allTestInXlsx []Test
xlsx, err := excelize.OpenFile("./test.xlsx")
if err != nil {
	log.Println(err)
	return
}

sheetsXLSX := xlsx.GetSheetMap()
rows, _  := xlsx.Rows(sheetsXLSX[2])
for rows.Next() {
	s := rows.Columns()
	var tD Test
	tD.field1 = s[0]
	tD.field2 = s[1]
	tD.field3 = s[2]
	allTestInXlsx = append(allTestInXlsx, tD)
}
	log.Println(len(allData))
}

When I run program in console i have error - index out of range
And I’ don’t understand why?
Because in my test.xlsx exists values
Anybody work with this package - what i’m doing wrong?
Thanks!

Did you try to print the len of s that you get from rows.Columns()? You should not assume that you have elements in a slice.

1 Like

Yes, of course
rows.Columns() not give empty result
In xlsx i have several sheets and i trying to parse only one
On this sheet in some cells has data with formula value
Formula is correct and in xlsx show correct result
Maybe i’ve lost some logic to get data from cell with formula?
And get this data like s[cell] - wrong?
But i dont wanna recalc data from parse sheet - on golang side

Could you do a fmt.Printf("%+v\n", rows.Columns()) and paste the result? This way we can see what content you get from the XSLX parser.

1 Like

Very strange it return []
But in the same time xlsx.GetSheetMap() returns me correct map

sheetsXLSX := xlsx.GetSheetMap()
log.Println(sheetsXLSX[2])

allRowsFromSheet, _ := xlsx.Rows(sheetsXLSX[2])
log.Printf("%+v\n", allRowsFromSheet.Columns())

sheetOne
[]

Try

allRowsFromSheet, _ := xlsx.Rows(sheetsXLSX[2])
for _, row := range allRowsFromSheet {
	for _, colCell := range row {
		fmt.Print(colCell, "\t")
	}
	fmt.Println()
}
1 Like

Thanks
In this case all works fine
But now i’m using another package

github.com/tealeg/xlsx

because package has several cool funcs like

cell.FormattedValue()

Also i’ve got new problem
When i parse file (only sheet[2]) it returns me values

cellOne - ok
cellTwo - ok
cellThree - value of cell from sheet[1]

I look at the file and some cells from sheet[1] consist formula which calculate values from sheet[2]
but in sheet[2] no links on sheet[1]
I’m not understand why this happened(((

Can you post the code you are using…

1 Like

all fine my mistake
thanks!

What was the problem?

In xlsx sheet - 46 columns
first case

for _, v := range file.Sheet["Name"].Rows {
	var d = MyType{}
	for i, v := range v.Cells {
		d[i] = v
	}
}

returns err index out of range - I don’t understand why
but second case

for _, v := range file.Sheet["Name"].Rows {
	var d = MyType{}
    if len(v.Cells) == 46 {
	for i, v := range v.Cells {
		d[i] = v
	 }
   }
 }

works good

Hmm… Right, this is a bit hard for us to understand without you also posting the xlsx file somewhere. Are you trying to parse values from the xlsx file into a Go object/type?

Looks like that package has a function for that already, https://godoc.org/github.com/tealeg/xlsx#example-Row-ReadStruct

If I’m understanding your code example correctly, v in for _, v := range file.Sheet["Name"].Rows { is the row, right?

Then you could do something like

for _, v := range file.Sheet["Name"].Rows {
    var d = MyType{}
    err := row.ReadStruct(d)
    if err != nil {
        panic(err)
    }
    // Do whatever you want with d here, such as add to a slice of all read rows.
    fmt.Println(d)
}

Which would be more idiomatic Go :slight_smile:

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.