excel_to_lucky_sheet.go 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247
  1. package excel
  2. import (
  3. "encoding/json"
  4. "eta/eta_api/utils"
  5. "fmt"
  6. "github.com/shopspring/decimal"
  7. "github.com/xuri/excelize/v2"
  8. )
  9. // ConvToLuckySheet 普通的excel转luckySheet数据
  10. func ConvToLuckySheet(filePath string) (err error) {
  11. defer func() {
  12. if err != nil {
  13. fmt.Println(err)
  14. }
  15. }()
  16. f, err := excelize.OpenFile(filePath)
  17. if err != nil {
  18. fmt.Println(err)
  19. return
  20. }
  21. sheetDataList := make([]SimpleLuckySheetData, 0)
  22. // 获取所有sheet
  23. sheetList := f.GetSheetList()
  24. for sheetIndex, sheetName := range sheetList {
  25. sheetData, tmpErr := getLuckySheetData(f, sheetIndex, sheetName)
  26. if tmpErr != nil {
  27. err = tmpErr
  28. return
  29. }
  30. sheetDataList = append(sheetDataList, sheetData)
  31. }
  32. byteS, err := json.Marshal(sheetDataList)
  33. if err != nil {
  34. return
  35. }
  36. utils.FileLog.Info(string(byteS))
  37. return
  38. }
  39. // SimpleLuckySheetData sheet表格数据
  40. type SimpleLuckySheetData struct {
  41. Name string `json:"name" description:"工作表名称"`
  42. Index int `json:"index" description:"工作表索引"`
  43. //Row int `json:"row" description:"行数"`
  44. //Column int `json:"column" description:"列数"`
  45. CellData []SimpleLuckySheetCellData `json:"celldata" description:"单元格数据"`
  46. Config SimpleLuckySheetDataConfig `json:"config" description:""`
  47. CalcChain []CalcChain `json:"calcChain" description:"公式链"`
  48. //Status int64 `json:"status" description:"激活状态"`
  49. }
  50. type CalcChain struct {
  51. Col int64 `json:"c"` //列数
  52. Row int64 `json:"r"` //行数
  53. Index int `json:"index"` //工作表id
  54. Func []interface{} `json:"func"` //公式信息,包含公式计算结果和公式字符串
  55. Color string `json:"color"` //"w":采用深度优先算法 "b":普通计算
  56. //Parent interface{} `json:"parent"`
  57. //Chidren struct {
  58. //} `json:"chidren"`
  59. Times int `json:"times"`
  60. }
  61. // SimpleLuckySheetDataConfig sheet表单的配置
  62. type SimpleLuckySheetDataConfig struct {
  63. BorderInfo []LuckySheetDataConfigBorderInfo `json:"borderInfo" description:"边框"`
  64. Colhidden map[string]int64 `json:"colhidden" description:"隐藏列,示例值:\"colhidden\":{\"30\":0,\"31\":0}"`
  65. //CustomHeight struct {
  66. // Zero int64 `json:"0"`
  67. //} `json:"customHeight" description:""`
  68. //CustomWidth struct {
  69. // Two int64 `json:"2" description:""`
  70. //} `json:"customWidth" description:""`
  71. Merge map[string]LuckySheetDataConfigMerge `json:"merge" description:"合并单元格"`
  72. //Rowlen map[string]float64 `json:"rowlen" description:"每个单元格的行高"`
  73. Columnlen map[string]float64 `json:"columnlen" description:"每个单元格的列宽"`
  74. }
  75. // SimpleLuckySheetCellData 单个单元格数据
  76. type SimpleLuckySheetCellData struct {
  77. Col int64 `json:"c" description:"列"`
  78. Row int64 `json:"r" description:"行"`
  79. Value SimpleLuckySheetDataValue `json:"v" description:"单元格内值的数据"`
  80. }
  81. // SimpleLuckySheetDataValue 单元格内值的数据
  82. type SimpleLuckySheetDataValue struct {
  83. CellType LuckySheetDataCellType `json:"ct" description:"单元格值格式:文本、时间等 "`
  84. Value interface{} `json:"v" description:"原始值"`
  85. Monitor string `json:"m" description:"显示值"`
  86. //Fontsize int `description:"字体大小,14"`
  87. TextBeak int `description:"文本换行, 0 截断、1溢出、2 自动换行"`
  88. Tb interface{} `json:"tb" description:"文本换行, 0 截断、1溢出、2 自动换行"`
  89. //Ps LuckySheetDataCellComment `json:"ps" description:"批注"`
  90. Function string `json:"f" description:"公式"`
  91. //MergeCell LuckySheetDataConfigMerge `json:"mc" description:"合并单元格信息"`
  92. }
  93. func getLuckySheetData(f *excelize.File, sheetIndex int, sheetName string) (sheetData SimpleLuckySheetData, err error) {
  94. cellData := make([]SimpleLuckySheetCellData, 0) // excel数据
  95. mergeData := make(map[string]LuckySheetDataConfigMerge) //合并单元格数据
  96. calcChainList := make([]CalcChain, 0) //公式链信息
  97. sheetData = SimpleLuckySheetData{
  98. Name: sheetName,
  99. Index: sheetIndex,
  100. //Row: 0,
  101. //Column: 0,
  102. CellData: cellData,
  103. Config: SimpleLuckySheetDataConfig{},
  104. }
  105. rows, tmpErr := f.GetRows(sheetName)
  106. if tmpErr != nil {
  107. err = tmpErr
  108. return
  109. }
  110. //sheetData.Row = len(rows)
  111. //sheetData.Column = len(Column)
  112. // 最大单元格数
  113. maxColumnIndex := 0
  114. mergeCellList, err := f.GetMergeCells(sheetName)
  115. if err != nil {
  116. return
  117. }
  118. for _, v := range mergeCellList {
  119. // 左上角单元格位置
  120. cStartIndex, rStartIndex, tmpErr := excelize.CellNameToCoordinates(v.GetStartAxis())
  121. if tmpErr != nil {
  122. err = tmpErr
  123. return
  124. }
  125. // 右下角单元格位置
  126. cEndIndex, rEndIndex, tmpErr := excelize.CellNameToCoordinates(v.GetEndAxis())
  127. if tmpErr != nil {
  128. err = tmpErr
  129. return
  130. }
  131. //fmt.Println(v.GetEndAxis())
  132. tmpLuckySheetDataConfigMerge := LuckySheetDataConfigMerge{
  133. Row: rStartIndex - 1,
  134. Column: cStartIndex - 1,
  135. Rs: rEndIndex - rStartIndex + 1,
  136. Cs: cEndIndex - cStartIndex + 1,
  137. }
  138. mergeData[fmt.Sprint(rStartIndex-1, "_", cStartIndex-1)] = tmpLuckySheetDataConfigMerge
  139. }
  140. sheetData.Config.Merge = mergeData
  141. colWidthMap := make(map[string]float64)
  142. for rIndex, row := range rows {
  143. for cIndex, colCell := range row {
  144. if rIndex == 0 {
  145. //colName, tmpErr := excelize.ColumnNumberToName(cIndex + 1)
  146. //if tmpErr != nil {
  147. // err = tmpErr
  148. // return
  149. //}
  150. //colWidth, tmpErr := f.GetColWidth(sheetName, colName)
  151. //if tmpErr != nil {
  152. // err = tmpErr
  153. // return
  154. //}
  155. //colWidthMap[fmt.Sprint(cIndex)] = emuToPx(colWidth)
  156. }
  157. if maxColumnIndex < cIndex {
  158. maxColumnIndex = cIndex
  159. }
  160. cellName, tmpErr := excelize.CoordinatesToCellName(cIndex+1, rIndex+1)
  161. if tmpErr != nil {
  162. err = tmpErr
  163. return
  164. }
  165. cellType, tmpErr := f.GetCellType(sheetName, cellName)
  166. if tmpErr != nil {
  167. err = tmpErr
  168. return
  169. }
  170. cellFormula, tmpErr := f.GetCellFormula(sheetName, cellName)
  171. if tmpErr != nil {
  172. err = tmpErr
  173. return
  174. }
  175. fmt.Println(cellName, ": ", "类型:", cellType, ",公式:", cellFormula, ",值", colCell, "\t")
  176. var colCellIntfac interface{}
  177. cellTypeT := "g"
  178. //colCell = utils.Tof
  179. tmpDec, tmpErr := decimal.NewFromString(colCell)
  180. if tmpErr != nil {
  181. colCellIntfac = colCell
  182. } else {
  183. colCellIntfac, _ = tmpDec.Float64()
  184. cellTypeT = "n"
  185. }
  186. if cellFormula != `` {
  187. cellFormula = `=` + cellFormula
  188. calcChainList = append(calcChainList, CalcChain{
  189. Col: int64(cIndex),
  190. Row: int64(rIndex),
  191. Index: sheetIndex,
  192. Func: []interface{}{true, colCell, cellFormula},
  193. Color: "w",
  194. Times: 0,
  195. })
  196. }
  197. cellData = append(cellData, SimpleLuckySheetCellData{
  198. Col: int64(cIndex),
  199. Row: int64(rIndex),
  200. Value: SimpleLuckySheetDataValue{
  201. CellType: LuckySheetDataCellType{
  202. Fa: "General",
  203. T: cellTypeT,
  204. //S: nil,
  205. },
  206. Value: colCellIntfac,
  207. Monitor: colCell,
  208. //Background: "",
  209. //FontFamily: 0,
  210. //FontColor: "",
  211. Function: cellFormula,
  212. //MergeCell: LuckySheetDataConfigMerge{},
  213. },
  214. })
  215. }
  216. }
  217. sheetData.Config.Columnlen = colWidthMap
  218. sheetData.CellData = cellData
  219. sheetData.CalcChain = calcChainList
  220. //sheetData.Column = maxColumnIndex + 1
  221. return
  222. }
  223. // emuToPx 计量单位emu转px
  224. func emuToPx(num float64) float64 {
  225. return num * 15
  226. }