123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269 |
- package xvdoc
- import (
- "encoding/json"
- "fmt"
- "reflect"
- "strconv"
- "github.com/xuri/excelize/v2"
- )
- type JSONMap map[string]interface{}
- func (s JSONMap) Bool(key string, defaultVal bool) bool {
- if res, check := s[key].(bool); check {
- return res
- }
- return defaultVal
- }
- func (s JSONMap) Int(key string, defaultVal int64) int64 {
- if iface, check := s[key]; check {
- rVal := reflect.ValueOf(iface)
- switch rVal.Kind() {
- case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
- return rVal.Int()
- case reflect.Float32, reflect.Float64:
- return int64(rVal.Float())
- }
- }
- return defaultVal
- }
- func (s JSONMap) Value(key string, defaultVal interface{}) interface{} {
- if iface, check := s[key]; check {
- dVal := reflect.ValueOf(defaultVal)
- if !dVal.IsValid() {
- return iface
- } else {
- lVal := reflect.ValueOf(iface)
- if !lVal.IsValid() {
- return defaultVal
- } else if lVal.Kind() == dVal.Kind() {
- return iface
- } else if lVal.Type().ConvertibleTo(dVal.Type()) {
- return lVal.Convert(dVal.Type()).Interface()
- } else {
- if lVal.Kind() == reflect.String {
- switch dVal.Kind() {
- case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
- if val, err := strconv.Atoi(lVal.String()); err != nil {
- return defaultVal
- } else {
- lVal = reflect.ValueOf(val)
- return lVal.Convert(dVal.Type())
- }
- case reflect.Float32, reflect.Float64:
- if val, err := strconv.ParseFloat(lVal.String(), 64); err != nil {
- return defaultVal
- } else {
- lVal = reflect.ValueOf(val)
- return lVal.Convert(dVal.Type())
- }
- }
- }
- }
- }
- }
- return defaultVal
- }
- func (s JSONMap) StringVal(key, defaultVal string) string {
- if iface, check := s[key]; check {
- return fmt.Sprint(iface)
- }
- return defaultVal
- }
- func (s JSONMap) Interface(key string) interface{} {
- return s[key]
- }
- func (s JSONMap) StringArray(key string) (res []string) {
- if arr, check := s[key].([]interface{}); check {
- res = make([]string, len(arr))
- for i, v := range arr {
- res[i] = fmt.Sprint(v)
- }
- }
- return
- }
- func (s JSONMap) Array(key string) (res []interface{}) {
- if arr, check := s[key].([]interface{}); check {
- res = arr
- }
- return
- }
- func (s JSONMap) JSONMap(key string) (res JSONMap) {
- if m, check := s[key].(map[string]interface{}); check {
- res = JSONMap(m)
- }
- return
- }
- func (s JSONMap) KeyExists(key string) (check bool) {
- _, check = s[key]
- return check
- }
- func (s JSONMap) Copy() JSONMap {
- res := make(JSONMap)
- for key, val := range s {
- res[key] = val
- }
- return res
- }
- func (s JSONMap) JSON() (res []byte) {
- res, _ = json.Marshal(&s)
- return
- }
- func (s JSONMap) Map() map[string]interface{} {
- return map[string]interface{}(s)
- }
- func copyMap(m map[string]interface{}) (res map[string]interface{}) {
- res = make(map[string]interface{})
- for key, val := range m {
- switch val.(type) {
- case []interface{}:
- res[key] = copySlice(val.([]interface{}))
- case map[string]interface{}:
- res[key] = copyMap(val.(map[string]interface{}))
- default:
- res[key] = val
- }
- }
- return
- }
- func copySlice(arr []interface{}) (res []interface{}) {
- res = make([]interface{}, len(arr))
- for i, v := range arr {
- switch v.(type) {
- case []interface{}:
- res[i] = copySlice(v.([]interface{}))
- case map[string]interface{}:
- res[i] = copyMap(v.(map[string]interface{}))
- default:
- res[i] = v
- }
- }
- return
- }
- func mergeSlices(aSource, aMerge []interface{}) []interface{} {
- return append(aSource, aMerge...)
- }
- func mergeMaps(mSource, mMerge map[string]interface{}) (res map[string]interface{}) {
- res = copyMap(mSource)
- // merge result with result map
- for key, val := range mMerge {
- if sVal, check := res[key]; check {
- switch val.(type) {
- case map[string]interface{}:
- {
- if m, check := sVal.(map[string]interface{}); check {
- res[key] = mergeMaps(m, val.(map[string]interface{}))
- } else if val == nil {
- res[key] = val
- }
- }
- case []interface{}:
- {
- if arr, check := sVal.([]interface{}); check {
- res[key] = mergeSlices(arr, val.([]interface{}))
- } else if val == nil {
- res[key] = val
- }
- }
- default:
- res[key] = val
- }
- } else {
- switch val.(type) {
- case map[string]interface{}:
- res[key] = copyMap(val.(map[string]interface{}))
- case []interface{}:
- res[key] = copySlice(val.([]interface{}))
- default:
- res[key] = val
- }
- }
- }
- return
- }
- func (s JSONMap) ToGraphicOptions() (res *excelize.GraphicOptions) {
- res = &excelize.GraphicOptions{
- LockAspectRatio: s.Bool("lock_aspect_ratio", false),
- AutoFit: s.Bool("autofit", false),
- OffsetX: int(s.Int("offset_x", 0)),
- OffsetY: int(s.Int("offset_y", 0)),
- Hyperlink: s.StringVal("link", ""),
- HyperlinkType: s.StringVal("link_type", ""),
- Positioning: s.StringVal("positioning", ""),
- }
- return
- }
- func (s JSONMap) ToStyle() (res *excelize.Style) {
- res = &excelize.Style{}
- // borders
- if arr := s.Array("border"); len(arr) > 0 {
- for _, val := range arr {
- if m, check := val.(map[string]any); check {
- jm := JSONMap(m)
- res.Border = append(res.Border, excelize.Border{
- Type: jm.StringVal("type", "top"),
- Color: jm.StringVal("color", "#000000"),
- Style: int(jm.Int("style", 0)),
- })
- }
- }
- }
- if s.KeyExists("fill") {
- mf := s.JSONMap("fill")
- res.Fill = excelize.Fill{
- Type: mf.StringVal("type", ""),
- Pattern: int(mf.Int("pattern", 0)),
- }
- for _, color := range mf.Array("color") {
- res.Fill.Color = append(res.Fill.Color, fmt.Sprint(color))
- }
- // Shading ???
- }
- if s.KeyExists("font") {
- mf := s.JSONMap("font")
- res.Font = &excelize.Font{
- Bold: mf.Bool("bold", false),
- Italic: mf.Bool("italic", false),
- Underline: mf.StringVal("underline", ""),
- Family: mf.StringVal("family", ""),
- Size: float64(mf.Int("size", 0)),
- Strike: mf.Bool("strike", false),
- Color: mf.StringVal("color", "#000000"),
- //VertAlign: ???,
- }
- }
- if s.KeyExists("alignment") {
- ma := s.JSONMap("alignment")
- res.Alignment = &excelize.Alignment{
- Horizontal: ma.StringVal("horizontal", ""),
- Vertical: ma.StringVal("vertical", ""),
- WrapText: ma.Bool("wrap", false),
- }
- }
- return
- }
- func mapJSON(m map[string]interface{}) (res []byte) {
- res, _ = json.Marshal(&m)
- return
- }
|