From c056db4ce07e4b9d4fca573e0873534e0acc9a4f Mon Sep 17 00:00:00 2001 From: Markus Bader Date: Wed, 15 Nov 2023 17:25:10 +0100 Subject: [PATCH] Fixe reading of decimal numbers when they are saved as int The xls standard allows to save a decimal number like 1.75 as an integer, multiplied by 100. The current implementation did neither detect this as an integer nor as a float and subsequently returns the default value 0. This fix adds the case to RKNumber's Float64() method in order to retrieve the value correctly as float. --- testdata/decimal.xls | Bin 0 -> 5632 bytes xls/structs.go | 8 +++++++- xls/structs_test.go | 25 +++++++++++++++++++++++++ 3 files changed, 32 insertions(+), 1 deletion(-) create mode 100644 testdata/decimal.xls create mode 100644 xls/structs_test.go diff --git a/testdata/decimal.xls b/testdata/decimal.xls new file mode 100644 index 0000000000000000000000000000000000000000..d7c10d0e0a4194d20cb9f5c0f6497bc423691888 GIT binary patch literal 5632 zcmeHLU2IfU5T3i;EqB|}Zc7VVq+S|bTDmn>9>f^zLa9n3QcI17kmz=MTPoX@loB=Z zXDRStB0X34^gYjUe3w%8(P_R?COV{X)x48hsFoi?tCIZzPwExY~YH z%VsUBQ5y1@_BpSd4r!DxA)k5qHE$DyjLpb@!;+AcB?MZy5_(vM_CtPs5adxi~((l~2A9pQGlJ|Nru*;8Tm!^C0WzHrEeMF2A(^KURRh zz5qXb4gYumdnzp%){%6X*0t$!t?SZ3tyiR%X|-2p6GZL zdozaLj9~&r`i>g%v+QDqc6xO>*pTXVUl!FE`zB!E@BxYQi zE-}X==bOm=CUUy@JJNpAY>?z%4*@slLrelZDBOe+`CCG%g5m)f#4T8>Mns_Mk9RJ8 zx4plo^C{)0=bsjGCtU+8529rzxL$j-X*sE~^>T--6^V95oBM`G?ETiG_On*+*hpeD z)@u(PNF~ObqaF7|H#bPDL>H9nNetOmwC9j2IILw9#%xfy*tyO}w}3v>er~e;oYUFr zqfbgRPRapHkH1NY88IWRMLkEwc%_nOC?LS|)Lj#|Gz0Xy(p)GIHS&@= zm*?&oEaETHLw7n4qYYb2q+gB)>%M#2`x5puCOtMUSnPG&m|=lv=Uq{kis@}Bi1kaw*CAn#lIfHd;r zRT18uNOu6^!1U>#G<-;BAr9j0)9-fwuIj_u`s|6jR!5G% z0sCWDKG+IgD2KNjJZ2XTPGqEIZ7sxy$P)ZVJg}JWKVAQvJ)Ccvd~2k=#PI}PpX0Ju z`t=>UH=p=*d3A_3#v78D=8)?O`x ALI3~& literal 0 HcmV?d00001 diff --git a/xls/structs.go b/xls/structs.go index c8d49a7..94dbe4b 100644 --- a/xls/structs.go +++ b/xls/structs.go @@ -27,7 +27,7 @@ type boundSheet struct { Name string } -/////// +// ///// type shRow struct { RowIndex uint16 // 0-based FirstCol uint16 // 0-based @@ -88,6 +88,12 @@ func (r RKNumber) Int() int { func (r RKNumber) Float64() float64 { val := int32(r) >> 2 + + // Value is saved as integer multiplied by 100 + if (r&1) != 0 && (r&2) != 0 { + return float64(val) / 100.0 + } + v2 := math.Float64frombits(uint64(val) << 34) if (r&1) == 0 && (r&2) == 0 { diff --git a/xls/structs_test.go b/xls/structs_test.go new file mode 100644 index 0000000..29d16e7 --- /dev/null +++ b/xls/structs_test.go @@ -0,0 +1,25 @@ +package xls + +import ( + "testing" + + "github.com/pbnjay/grate" +) + +func TestDecimalNumberSavedAsIntegerMultipliedByHundred(t *testing.T) { + wb, _ := grate.Open("../testdata/decimal.xls") + sheets, _ := wb.List() + for _, s := range sheets { + sheet, _ := wb.Get(s) + sheet.Next() + + var value float64 + sheet.Scan(&value) + + if value != 1.75 { + t.Log("Expected value to be 1.75, but actually is", value) + t.Fail() + } + } + wb.Close() +}