21
0
Fork 0
xls/worksheet.go

115 lines
2.4 KiB
Go

package xls
import (
"encoding/binary"
"fmt"
"io"
)
type Boundsheet struct {
Filepos uint32
Type byte
Visible byte
Name byte
}
type WorkSheet struct {
bs *Boundsheet
wb *WorkBook
Name string
Rows map[uint16]*Row
MaxRow uint16
}
func (w *WorkSheet) Parse(buf io.ReadSeeker) {
w.Rows = make(map[uint16]*Row)
bof := new(BOF)
var bof_pre *BOF
for {
if err := binary.Read(buf, binary.LittleEndian, bof); err == nil {
bof_pre = w.parseBof(buf, bof, bof_pre)
} else {
fmt.Println(err)
break
}
}
}
func (w *WorkSheet) parseBof(buf io.ReadSeeker, bof *BOF, pre *BOF) *BOF {
var col Coler
switch bof.Id {
case 0x0E5: //MERGEDCELLS
// ws.mergedCells(buf)
case 0x208: //ROW
r := new(RowInfo)
binary.Read(buf, binary.LittleEndian, r)
w.addRow(r)
case 0x0BD: //MULRK
mc := new(MulrkCol)
size := (bof.Size - 6) / 6
binary.Read(buf, binary.LittleEndian, &mc.Col)
mc.Xfrks = make([]XfRk, size)
for i := uint16(0); i < size; i++ {
binary.Read(buf, binary.LittleEndian, &mc.Xfrks[i])
}
binary.Read(buf, binary.LittleEndian, &mc.LastColB)
col = mc
case 0x0BE: //MULBLANK
mc := new(MulBlankCol)
size := (bof.Size - 6) / 2
binary.Read(buf, binary.LittleEndian, &mc.Col)
mc.Xfs = make([]uint16, size)
for i := uint16(0); i < size; i++ {
binary.Read(buf, binary.LittleEndian, &mc.Xfs[i])
}
binary.Read(buf, binary.LittleEndian, &mc.LastColB)
col = mc
case 0x203: //NUMBER
col = new(NumberCol)
binary.Read(buf, binary.LittleEndian, col)
case 0x06: //FORMULA
col = new(FormulaCol)
binary.Read(buf, binary.LittleEndian, col)
case 0x27e: //RK
col = new(RkCol)
binary.Read(buf, binary.LittleEndian, col)
case 0xFD: //LABELSST
col = new(LabelsstCol)
binary.Read(buf, binary.LittleEndian, col)
case 0x201: //BLANK
col = new(BlankCol)
binary.Read(buf, binary.LittleEndian, col)
default:
buf.Seek(int64(bof.Size), 1)
}
if col != nil {
w.addCell(col)
}
return bof
}
func (w *WorkSheet) addCell(col Coler) {
var row *Row
var ok bool
if row, ok = w.Rows[col.Row()]; !ok {
info := new(RowInfo)
info.Index = col.Row()
row = w.addRow(info)
}
row.Cols[col.FirstCol()] = col
}
func (w *WorkSheet) addRow(info *RowInfo) (row *Row) {
if info.Index > w.MaxRow {
w.MaxRow = info.Index
}
var ok bool
if row, ok = w.Rows[info.Index]; ok {
row.info = info
} else {
row = &Row{info: info, Cols: make(map[uint16]Coler)}
w.Rows[info.Index] = row
}
return
}