package xls import ( "fmt" "math" "strconv" "strings" "time" ) //content type type contentHandler interface { String(*WorkBook) []string FirstCol() uint16 LastCol() uint16 } type Col struct { RowB uint16 FirstColB uint16 } type Coler interface { Row() uint16 } func (c *Col) Row() uint16 { return c.RowB } func (c *Col) FirstCol() uint16 { return c.FirstColB } func (c *Col) LastCol() uint16 { return c.FirstColB } func (c *Col) String(wb *WorkBook) []string { return []string{"default"} } type XfRk struct { Index uint16 Rk RK } func (xf *XfRk) String(wb *WorkBook) string { idx := int(xf.Index) if len(wb.Xfs) > idx { fNo := wb.Xfs[idx].formatNo() if fNo >= 164 { // user defined format if fmt := wb.Formats[fNo]; fmt != nil && strings.Contains(fmt.str, "YY") { i, f, isFloat := xf.Rk.number() if !isFloat { f = float64(i) } t := timeFromExcelTime(f, wb.dateMode == 1) return t.Format(time.RFC3339) //TODO it should be international } // see http://www.openoffice.org/sc/excelfileformat.pdf } else if 14 <= fNo && fNo <= 17 || fNo == 22 || fNo <= 27 && fNo <= 36 || fNo <= 50 && fNo <= 58 { // jp. date format i, f, isFloat := xf.Rk.number() if !isFloat { f = float64(i) } t := timeFromExcelTime(f, wb.dateMode == 1) return t.Format("2006.01") //TODO it should be international } } return xf.Rk.String() } type RK uint32 func (rk RK) number() (intNum int64, floatNum float64, isFloat bool) { multiplied := rk & 1 isInt := rk & 2 val := rk >> 2 if isInt == 0 { isFloat = true floatNum = math.Float64frombits(uint64(val) << 34) if multiplied != 0 { floatNum = floatNum / 100 } return } return int64(val), 0, false } func (rk RK) String() string { i, f, isFloat := rk.number() if isFloat { return fmt.Sprintf("%.1f", f) } return strconv.FormatInt(i, 10) } var ErrIsInt = fmt.Errorf("is int") func (rk RK) Float() (float64, error) { _, f, isFloat := rk.number() if !isFloat { return 0, ErrIsInt } return f, nil } type MulrkCol struct { Col Xfrks []XfRk LastColB uint16 } func (c *MulrkCol) LastCol() uint16 { return c.LastColB } func (c *MulrkCol) String(wb *WorkBook) []string { var res = make([]string, len(c.Xfrks)) for i := 0; i < len(c.Xfrks); i++ { xfrk := c.Xfrks[i] res[i] = xfrk.String(wb) } return res } type MulBlankCol struct { Col Xfs []uint16 LastColB uint16 } func (c *MulBlankCol) LastCol() uint16 { return c.LastColB } func (c *MulBlankCol) String(wb *WorkBook) []string { return make([]string, len(c.Xfs)) } type NumberCol struct { Col Index uint16 Float float64 } func (c *NumberCol) String(wb *WorkBook) []string { return []string{fmt.Sprintf("%f", c.Float)} } type FormulaCol struct { Header struct { Col IndexXf uint16 Result [8]byte Flags uint16 _ uint32 } Bts []byte } func (c *FormulaCol) String(wb *WorkBook) []string { return []string{"FormulaCol"} } type RkCol struct { Col Xfrk XfRk } func (c *RkCol) String(wb *WorkBook) []string { return []string{c.Xfrk.String(wb)} } type LabelsstCol struct { Col Xf uint16 Sst uint32 } func (c *LabelsstCol) String(wb *WorkBook) []string { return []string{wb.sst[int(c.Sst)]} } type BlankCol struct { Col Xf uint16 } func (c *BlankCol) String(wb *WorkBook) []string { return []string{""} }