123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144 |
- package xvdoc
- import (
- "bytes"
- "encoding/json"
- "fmt"
- )
- func FromJSON(src []byte) (res []*XVDoc, err error) {
- var xv []*XVDoc
- if err = json.Unmarshal(src, &xv); err == nil {
- res = xv
- }
- return
- }
- type XVDoc struct {
- name string
- style string
- rows []*Row
- styles map[string]Style
- dropdowns []*dropDown
- merges []*rectMerge
- columnsWidth []*rectWidths
- styleRects []*styleRect
- images []*cellImage
- }
- func (s *XVDoc) UnmarshalJSON(src []byte) (err error) {
- dec := json.NewDecoder(bytes.NewReader(src))
- var t json.Token
- for dec.More() && err == nil {
- if t, err = dec.Token(); err == nil {
- if _, check := t.(json.Delim); !check {
- switch t.(string) {
- case "name":
- err = dec.Decode(&s.name)
- case "style":
- err = dec.Decode(&s.style)
- case "rows":
- err = dec.Decode(&s.rows)
- case "styles":
- err = dec.Decode(&s.styles)
- case "merges":
- err = dec.Decode(&s.merges)
- case "style_rects":
- err = dec.Decode(&s.styleRects)
- case "columns_width":
- err = dec.Decode(&s.columnsWidth)
- case "images":
- err = dec.Decode(&s.images)
- case "dropdowns":
- err = dec.Decode(&s.dropdowns)
- default:
- err = dec.Decode(new(interface{}))
- }
- }
- }
- }
- return
- }
- func (s *XVDoc) String() (res string) {
- res = fmt.Sprintf("xvDoc %v\n*** rows ***\n", s.name)
- res += fmt.Sprintf("styles: %v\n", s.styles)
- res += fmt.Sprintf("name: %v\n", s.name)
- for i, v := range s.rows {
- res = res + fmt.Sprintf("%v: Cells: %v\n", i, v)
- }
- res = res + "*********************\n"
- return res
- }
- func (s *XVDoc) matrix() Matrix {
- var matrix [][]Cell
- row, rowsHeight := 0, make(map[int]float64)
- // create document matrix
- for _, v := range s.rows {
- // setup row
- if v.offsetY {
- row += v.oy
- } else if v.y >= 0 {
- row = v.y
- }
- // setup custom row height
- if v.IsCustomHeight() {
- rowsHeight[row] = v.Height()
- }
- // fill matrix rows
- if row >= len(matrix) {
- tmp := make([][]Cell, row-len(matrix)+1)
- matrix = append(matrix, tmp...)
- }
- // get row in matrix
- r := matrix[row]
- if v.x+len(v.cells) >= len(r) {
- tmp := make([]Cell, v.x+len(v.cells)-len(r))
- r = append(r, tmp...)
- }
- for i := 0; i < len(v.cells); i++ {
- r[v.x+i] = v.cells[i]
- }
- // setup row in matrix
- matrix[row] = r
- // to next row
- row++
- }
- res := Matrix{
- Name: s.name,
- Cells: matrix,
- Styles: s.styles,
- RowsHeight: rowsHeight,
- Style: s.style,
- StyleRects: s.styleRects,
- Merges: s.merges,
- Images: s.images,
- Dropdowns: s.dropdowns,
- ColumnsWidth: s.columnsWidth,
- }
- return res
- }
- func Export(format string, docs []*XVDoc) ([]byte, error) {
- if method, check := exportMethods[format]; check {
- m := make([]Matrix, len(docs))
- for i, v := range docs {
- m[i] = v.matrix()
- }
- return method(m)
- } else {
- return nil, fmt.Errorf("xvdoc export error :: unexpected format '%v'", format)
- }
- }
|