xvdoc.go 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. package xvdoc
  2. import (
  3. "bytes"
  4. "encoding/json"
  5. "fmt"
  6. )
  7. func FromJSON(src []byte) (res []*XVDoc, err error) {
  8. var xv []*XVDoc
  9. if err = json.Unmarshal(src, &xv); err == nil {
  10. res = xv
  11. }
  12. return
  13. }
  14. type XVDoc struct {
  15. name string
  16. style string
  17. rows []*Row
  18. styles map[string]Style
  19. dropdowns []*dropDown
  20. merges []*rectMerge
  21. columnsWidth []*rectWidths
  22. styleRects []*styleRect
  23. images []*cellImage
  24. }
  25. func (s *XVDoc) UnmarshalJSON(src []byte) (err error) {
  26. dec := json.NewDecoder(bytes.NewReader(src))
  27. var t json.Token
  28. for dec.More() && err == nil {
  29. if t, err = dec.Token(); err == nil {
  30. if _, check := t.(json.Delim); !check {
  31. switch t.(string) {
  32. case "name":
  33. err = dec.Decode(&s.name)
  34. case "style":
  35. err = dec.Decode(&s.style)
  36. case "rows":
  37. err = dec.Decode(&s.rows)
  38. case "styles":
  39. err = dec.Decode(&s.styles)
  40. case "merges":
  41. err = dec.Decode(&s.merges)
  42. case "style_rects":
  43. err = dec.Decode(&s.styleRects)
  44. case "columns_width":
  45. err = dec.Decode(&s.columnsWidth)
  46. case "images":
  47. err = dec.Decode(&s.images)
  48. case "dropdowns":
  49. err = dec.Decode(&s.dropdowns)
  50. default:
  51. err = dec.Decode(new(interface{}))
  52. }
  53. }
  54. }
  55. }
  56. return
  57. }
  58. func (s *XVDoc) String() (res string) {
  59. res = fmt.Sprintf("xvDoc %v\n*** rows ***\n", s.name)
  60. res += fmt.Sprintf("styles: %v\n", s.styles)
  61. res += fmt.Sprintf("name: %v\n", s.name)
  62. for i, v := range s.rows {
  63. res = res + fmt.Sprintf("%v: Cells: %v\n", i, v)
  64. }
  65. res = res + "*********************\n"
  66. return res
  67. }
  68. func (s *XVDoc) matrix() Matrix {
  69. var matrix [][]Cell
  70. row, rowsHeight := 0, make(map[int]float64)
  71. // create document matrix
  72. for _, v := range s.rows {
  73. // setup row
  74. if v.offsetY {
  75. row += v.oy
  76. } else if v.y >= 0 {
  77. row = v.y
  78. }
  79. // setup custom row height
  80. if v.IsCustomHeight() {
  81. rowsHeight[row] = v.Height()
  82. }
  83. // fill matrix rows
  84. if row >= len(matrix) {
  85. tmp := make([][]Cell, row-len(matrix)+1)
  86. matrix = append(matrix, tmp...)
  87. }
  88. // get row in matrix
  89. r := matrix[row]
  90. if v.x+len(v.cells) >= len(r) {
  91. tmp := make([]Cell, v.x+len(v.cells)-len(r))
  92. r = append(r, tmp...)
  93. }
  94. for i := 0; i < len(v.cells); i++ {
  95. r[v.x+i] = v.cells[i]
  96. }
  97. // setup row in matrix
  98. matrix[row] = r
  99. // to next row
  100. row++
  101. }
  102. res := Matrix{
  103. Name: s.name,
  104. Cells: matrix,
  105. Styles: s.styles,
  106. RowsHeight: rowsHeight,
  107. Style: s.style,
  108. StyleRects: s.styleRects,
  109. Merges: s.merges,
  110. Images: s.images,
  111. Dropdowns: s.dropdowns,
  112. ColumnsWidth: s.columnsWidth,
  113. }
  114. return res
  115. }
  116. func Export(format string, docs []*XVDoc) ([]byte, error) {
  117. if method, check := exportMethods[format]; check {
  118. m := make([]Matrix, len(docs))
  119. for i, v := range docs {
  120. m[i] = v.matrix()
  121. }
  122. return method(m)
  123. } else {
  124. return nil, fmt.Errorf("xvdoc export error :: unexpected format '%v'", format)
  125. }
  126. }