diff --git a/BigTable.xls b/BigTable.xls new file mode 100644 index 0000000..e7c7481 Binary files /dev/null and b/BigTable.xls differ diff --git a/bigtable_test.go b/bigtable_test.go new file mode 100644 index 0000000..356579a --- /dev/null +++ b/bigtable_test.go @@ -0,0 +1,59 @@ +package xls + +import ( + "fmt" + "testing" + "time" +) + +func TestBigTable(t *testing.T) { + xlFile, err := Open("BigTable.xls", "utf-8") + if err != nil { + t.Fatalf("Cant open xls file: %s", err) + } + + sheet := xlFile.GetSheet(0) + if sheet == nil { + t.Fatal("Cant get sheet") + } + + cnt1 := 1 + cnt2 := 10000 + cnt3 := 20000 + date1, _ := time.Parse("2006-01-02", "2015-01-01") + date2, _ := time.Parse("2006-01-02", "2016-01-01") + date3, _ := time.Parse("2006-01-02", "2017-01-01") + + for i := 1; i <= 4999; i++ { + row := sheet.Row(i) + if row == nil { + continue + } + + col2sample := fmt.Sprintf("%d от %s", cnt1, date1.Format("02.01.2006")) + col5sample := fmt.Sprintf("%d от %s", cnt2, date2.Format("02.01.2006")) + col8sample := fmt.Sprintf("%d от %s", cnt3, date3.Format("02.01.2006")) + + col2 := row.Col(2) + col5 := row.Col(5) + col8 := row.Col(8) + + if col2 != col2sample { + t.Fatalf("Row %d: col 2 val not eq base value: %s != %s", i, col2, col2sample) + } + if col5 != col5sample { + t.Fatalf("Row %d: col 5 val not eq base value: %s != %s", i, col5, col5sample) + } + if col8 != col8sample { + t.Fatalf("Row %d: col 8 val not eq base value: %s != %s", i, col8, col8sample) + } + + cnt1++ + cnt2++ + cnt3++ + date1 = date1.AddDate(0, 0, 1) + date2 = date2.AddDate(0, 0, 1) + date3 = date3.AddDate(0, 0, 1) + + } +} diff --git a/workbook.go b/workbook.go index fd655e5..3644867 100644 --- a/workbook.go +++ b/workbook.go @@ -86,6 +86,11 @@ func (wb *WorkBook) parseBof(buf io.ReadSeeker, b *bof, pre *bof, offset_pre int case 0x042: // CODEPAGE binary.Read(buf_item, binary.LittleEndian, &wb.Codepage) case 0x3c: // CONTINUE + // step back if previous element not yet completed + if wb.continue_utf16 > 0 { + offset_pre-- + } + if pre.Id == 0xfc { var size uint16 var err error @@ -119,6 +124,8 @@ func (wb *WorkBook) parseBof(buf io.ReadSeeker, b *bof, pre *bof, offset_pre int wb.sst = make([]string, info.Count) var size uint16 var i = 0 + // dont forget to initialize offset + offset = 0 for ; i < int(info.Count); i++ { var err error if err = binary.Read(buf_item, binary.LittleEndian, &size); err == nil { @@ -192,10 +199,20 @@ func (w *WorkBook) get_string(buf io.ReadSeeker, size uint16) (res string, err e if flag&0x1 != 0 { var bts = make([]uint16, size) var i = uint16(0) + // we need local err here + var err error for ; i < size && err == nil; i++ { err = binary.Read(buf, binary.LittleEndian, &bts[i]) } - runes := utf16.Decode(bts[:i]) + + // when eof found, we dont want to append last element + var runes []rune + if err == io.EOF { + runes = utf16.Decode(bts[:i-1]) + } else { + runes = utf16.Decode(bts[:i]) + } + res = string(runes) if i < size { w.continue_utf16 = size - i + 1