20
0
xls/col.go

253 lines
4.6 KiB
Go
Raw Normal View History

2015-03-19 10:39:41 +01:00
package xls
import (
"fmt"
"math"
"strconv"
"strings"
2017-06-12 04:31:26 +02:00
2017-07-26 04:17:25 +02:00
"time"
2020-03-27 21:08:23 +01:00
yymmdd "github.com/extrame/goyymmdd"
2015-03-19 10:39:41 +01:00
)
2020-09-11 08:25:20 +02:00
// content type
2015-09-30 04:40:01 +02:00
type contentHandler interface {
2015-03-24 06:06:52 +01:00
String(*WorkBook) []string
FirstCol() uint16
LastCol() uint16
}
2015-03-19 10:39:41 +01:00
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 {
2015-03-24 06:06:52 +01:00
return []string{"default"}
2015-03-19 10:39:41 +01:00
}
type XfRk struct {
Index uint16
Rk RK
}
2015-03-25 07:47:26 +01:00
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
2017-06-12 04:31:26 +02:00
if formatter := wb.Formats[fNo]; formatter != nil {
2019-03-05 21:25:31 +01:00
formatterLower := strings.ToLower(formatter.str)
if formatterLower == "general" ||
strings.Contains(formatter.str, "#") ||
strings.Contains(formatter.str, ".00") ||
2019-03-06 21:13:03 +01:00
strings.Contains(formatterLower, "m/y") ||
strings.Contains(formatterLower, "d/y") ||
strings.Contains(formatterLower, "m.y") ||
strings.Contains(formatterLower, "d.y") ||
strings.Contains(formatterLower, "h:") ||
strings.Contains(formatterLower, "д.г") {
2020-09-11 08:25:20 +02:00
// If format contains # or .00 then this is a number
2019-03-05 20:31:15 +01:00
return xf.Rk.String()
} else {
i, f, isFloat := xf.Rk.number()
if !isFloat {
f = float64(i)
}
t := timeFromExcelTime(f, wb.dateMode == 1)
return yymmdd.Format(t, formatter.str)
}
2015-10-30 09:01:42 +01:00
}
2017-07-26 04:17:25 +02:00
// see http://www.openoffice.org/sc/excelfileformat.pdf Page #174
2016-06-01 02:09:38 +02:00
} else if 14 <= fNo && fNo <= 17 || fNo == 22 || 27 <= fNo && fNo <= 36 || 50 <= fNo && fNo <= 58 { // jp. date format
i, f, isFloat := xf.Rk.number()
if !isFloat {
f = float64(i)
}
t := timeFromExcelTime(f, wb.dateMode == 1)
2020-09-11 08:25:20 +02:00
return t.Format(time.RFC3339) // TODO it should be international
2015-03-25 07:47:26 +01:00
}
}
return xf.Rk.String()
2015-03-25 07:47:26 +01:00
}
2015-03-19 10:39:41 +01:00
type RK uint32
func (rk RK) number() (intNum int64, floatNum float64, isFloat bool) {
2015-03-19 10:39:41 +01:00
multiplied := rk & 1
isInt := rk & 2
val := int32(rk) >> 2
2015-03-19 10:39:41 +01:00
if isInt == 0 {
isFloat = true
floatNum = math.Float64frombits(uint64(val) << 34)
2015-03-19 10:39:41 +01:00
if multiplied != 0 {
floatNum = floatNum / 100
2015-03-19 10:39:41 +01:00
}
return
}
2017-06-12 04:31:26 +02:00
if multiplied != 0 {
isFloat = true
floatNum = float64(val) / 100
return
}
return int64(val), 0, false
}
func (rk RK) String() string {
i, f, isFloat := rk.number()
if isFloat {
2016-08-12 05:17:17 +02:00
return strconv.FormatFloat(f, 'f', -1, 64)
2015-03-19 10:39:41 +01:00
}
return strconv.FormatInt(i, 10)
2015-03-19 10:39:41 +01:00
}
2015-03-25 07:47:26 +01:00
var ErrIsInt = fmt.Errorf("is int")
func (rk RK) Float() (float64, error) {
_, f, isFloat := rk.number()
if !isFloat {
return 0, ErrIsInt
2015-03-25 07:47:26 +01:00
}
return f, nil
2015-03-25 07:47:26 +01:00
}
2015-03-19 10:39:41 +01:00
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]
2015-03-25 07:47:26 +01:00
res[i] = xfrk.String(wb)
2015-03-19 10:39:41 +01:00
}
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 {
2020-03-27 21:08:35 +01:00
if fNo := wb.Xfs[c.Index].formatNo(); fNo != 0 {
t := timeFromExcelTime(c.Float, wb.dateMode == 1)
return []string{yymmdd.Format(t, wb.Formats[fNo].str)}
}
2016-08-12 05:31:13 +02:00
return []string{strconv.FormatFloat(c.Float, 'f', -1, 64)}
2015-03-19 10:39:41 +01:00
}
type FormulaStringCol struct {
Col
RenderedValue string
}
func (c *FormulaStringCol) String(wb *WorkBook) []string {
return []string{c.RenderedValue}
}
2020-09-11 08:25:20 +02:00
// str, err = wb.get_string(buf_item, size)
// wb.sst[offset_pre] = wb.sst[offset_pre] + str
2015-03-19 10:39:41 +01:00
type FormulaCol struct {
2015-03-24 06:06:52 +01:00
Header struct {
Col
IndexXf uint16
Result [8]byte
Flags uint16
_ uint32
}
Bts []byte
}
func (c *FormulaCol) String(wb *WorkBook) []string {
return []string{"FormulaCol"}
2015-03-19 10:39:41 +01:00
}
2015-03-24 06:06:52 +01:00
2015-03-19 10:39:41 +01:00
type RkCol struct {
Col
Xfrk XfRk
}
func (c *RkCol) String(wb *WorkBook) []string {
return []string{c.Xfrk.String(wb)}
2015-03-19 10:39:41 +01:00
}
type LabelsstCol struct {
Col
Xf uint16
Sst uint32
}
func (c *LabelsstCol) String(wb *WorkBook) []string {
return []string{wb.sst[int(c.Sst)]}
}
2016-05-28 04:39:46 +02:00
type labelCol struct {
BlankCol
Str string
}
func (c *labelCol) String(wb *WorkBook) []string {
return []string{c.Str}
}
2015-03-19 10:39:41 +01:00
type BlankCol struct {
Col
Xf uint16
}
2015-03-24 06:06:52 +01:00
func (c *BlankCol) String(wb *WorkBook) []string {
return []string{""}
}
2020-09-11 08:25:20 +02:00
type MergeCells struct {
Count uint16
Refs []Ref8
}
type Ref8 struct {
RwFirst uint16
RwLast uint16
ColFirst uint16
ColLast uint16
}