custom_analysis_edb.go 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566
  1. package excel
  2. import (
  3. "encoding/json"
  4. "errors"
  5. "eta_gn/eta_api/models/data_manage/excel"
  6. "eta_gn/eta_api/services/data"
  7. excelServices "eta_gn/eta_api/services/excel"
  8. "eta_gn/eta_api/utils"
  9. "fmt"
  10. "github.com/araddon/dateparse"
  11. "github.com/shopspring/decimal"
  12. "github.com/tealeg/xlsx"
  13. "github.com/xuri/excelize/v2"
  14. "strings"
  15. )
  16. func GetCustomAnalysisExcelData(excelInfo *excel.ExcelInfo) (luckySheet excelServices.LuckySheet, err error, errMsg string) {
  17. sheetList, err := excel.GetAllSheetList(excelInfo.ExcelInfoId)
  18. if err != nil {
  19. errMsg = "保存失败"
  20. err = errors.New("查找当前excel的sheet列表失败,Err:" + err.Error())
  21. return
  22. }
  23. currSheetMap := make(map[string]string)
  24. for _, sheet := range sheetList {
  25. currSheetMap[sheet.SheetName] = sheet.SheetName
  26. }
  27. sheetCellDataMapList := make(map[int][]excelServices.LuckySheetCellData)
  28. {
  29. dataList, tmpErr := excel.GetAllSheetDataListByExcelInfoId(excelInfo.ExcelInfoId)
  30. if tmpErr != nil {
  31. err = tmpErr
  32. return
  33. }
  34. for _, cellData := range dataList {
  35. sheetDataList, ok := sheetCellDataMapList[cellData.ExcelSheetId]
  36. if !ok {
  37. sheetDataList = make([]excelServices.LuckySheetCellData, 0)
  38. }
  39. tmpSheetDataList := make([]excelServices.LuckySheetCellData, 0)
  40. err = json.Unmarshal([]byte(cellData.Data), &tmpSheetDataList)
  41. if err != nil {
  42. err = errors.New(fmt.Sprintf("解析data的配置失败,sheetId:%d,Err:%s", cellData.ExcelDataId, err.Error()))
  43. return
  44. }
  45. sheetCellDataMapList[cellData.ExcelSheetId] = append(sheetDataList, tmpSheetDataList...)
  46. }
  47. }
  48. luckySheet = excelServices.LuckySheet{
  49. SheetList: make([]excelServices.LuckySheetData, 0),
  50. }
  51. for _, sheet := range sheetList {
  52. var luckySheetDataConfig excelServices.LuckySheetDataConfig
  53. err = json.Unmarshal([]byte(sheet.Config), &luckySheetDataConfig)
  54. if err != nil {
  55. err = errors.New(fmt.Sprintf("解析sheet的配置失败,sheetId:%d,Err:%s", sheet.ExcelSheetId, err.Error()))
  56. return
  57. }
  58. tmpLuckySheetDataInfo := excelServices.LuckySheetData{
  59. Name: sheet.SheetName,
  60. Index: sheet.Sort,
  61. CellData: sheetCellDataMapList[sheet.ExcelSheetId],
  62. Config: luckySheetDataConfig,
  63. }
  64. luckySheet.SheetList = append(luckySheet.SheetList, tmpLuckySheetDataInfo)
  65. }
  66. return
  67. }
  68. func GenerateExcelCustomAnalysisExcel(excelInfo *excel.ExcelInfo) (downloadFilePath string, err error, errMsg string) {
  69. luckySheet, err, errMsg := GetCustomAnalysisExcelData(excelInfo)
  70. if err != nil {
  71. return
  72. }
  73. downloadFilePath, err = luckySheet.ToExcel(false)
  74. return
  75. }
  76. type dataStruct struct {
  77. Value float64
  78. Ok bool
  79. }
  80. func HandleEdbSequenceVal(dateSequenceVal, dataSequenceVal []string) (newDateList []string, newDataList []float64, err error, errMsg string) {
  81. newDateList = make([]string, 0)
  82. newDataList = make([]float64, 0)
  83. dataList := make([]dataStruct, 0)
  84. {
  85. for _, v := range dataSequenceVal {
  86. if v == `` {
  87. dataList = append(dataList, dataStruct{
  88. Value: 0,
  89. Ok: false,
  90. })
  91. continue
  92. }
  93. v = strings.Replace(v, ",", "", -1)
  94. v = strings.Replace(v, ",", "", -1)
  95. v = strings.Replace(v, " ", "", -1)
  96. var tmpVal float64
  97. if strings.Contains(v, "%") {
  98. isPercentage, percentageValue := utils.IsPercentage(v)
  99. if !isPercentage {
  100. dataList = append(dataList, dataStruct{
  101. Value: 0,
  102. Ok: false,
  103. })
  104. continue
  105. }
  106. tmpValDec, tmpErr := decimal.NewFromString(percentageValue)
  107. if tmpErr != nil {
  108. dataList = append(dataList, dataStruct{
  109. Value: 0,
  110. Ok: false,
  111. })
  112. continue
  113. }
  114. tmpVal, _ = tmpValDec.Div(decimal.NewFromFloat(100)).Float64()
  115. } else {
  116. tmpValDec, tmpErr := decimal.NewFromString(v)
  117. if tmpErr != nil {
  118. dataList = append(dataList, dataStruct{
  119. Value: 0,
  120. Ok: false,
  121. })
  122. continue
  123. }
  124. tmpVal, _ = tmpValDec.Float64()
  125. }
  126. dataList = append(dataList, dataStruct{
  127. Value: tmpVal,
  128. Ok: true,
  129. })
  130. }
  131. }
  132. dateList := make([]string, 0)
  133. {
  134. for _, v := range dateSequenceVal {
  135. if v == `` {
  136. dateList = append(dateList, "")
  137. continue
  138. }
  139. v = strings.Replace(v, " ", "", -1)
  140. t1, tmpErr := dateparse.ParseAny(v)
  141. if tmpErr != nil {
  142. dateList = append(dateList, "")
  143. continue
  144. }
  145. dateList = append(dateList, t1.Format(utils.FormatDate))
  146. }
  147. }
  148. lenData := len(dataList)
  149. lenDate := len(dateList)
  150. num := lenDate
  151. if num > lenData {
  152. num = lenData
  153. }
  154. for i := 0; i < num; i++ {
  155. date := dateList[i]
  156. tmpData := dataList[i]
  157. if !tmpData.Ok || date == `` {
  158. continue
  159. }
  160. newDateList = append(newDateList, date)
  161. newDataList = append(newDataList, tmpData.Value)
  162. }
  163. return
  164. }
  165. type ResetCustomAnalysisData struct {
  166. EdbInfoId int
  167. DateList []string
  168. DataList []float64
  169. }
  170. func Refresh(excelInfo *excel.ExcelInfo, lang string) (err error, errMsg string, isSendEmail bool) {
  171. isSendEmail = true
  172. list, err := excel.GetAllExcelEdbMappingItemByExcelInfoId(excelInfo.ExcelInfoId)
  173. if err != nil {
  174. errMsg = "获取失败"
  175. err = errors.New("查找所有的mapping失败" + err.Error())
  176. return
  177. }
  178. if len(list) <= 0 {
  179. return
  180. }
  181. for k, v := range list {
  182. var tmpCalculateFormula excel.CalculateFormula
  183. err = json.Unmarshal([]byte(v.CalculateFormula), &tmpCalculateFormula)
  184. if err != nil {
  185. errMsg = "获取失败"
  186. err = errors.New(fmt.Sprintf("指标id:%d,公式转换失败,Err:%s", v.EdbInfoId, err.Error()))
  187. return
  188. }
  189. v.DateSequenceStr = tmpCalculateFormula.DateSequenceStr
  190. v.DataSequenceStr = tmpCalculateFormula.DataSequenceStr
  191. list[k] = v
  192. }
  193. luckySheet, err, errMsg := GetCustomAnalysisExcelData(excelInfo)
  194. if err != nil {
  195. err = errors.New(fmt.Sprintf("获取自定义分析Excel数据失败,Err:%s", err.Error()))
  196. return
  197. }
  198. xlsxFile, err := luckySheet.GetExcelData(false)
  199. if err != nil {
  200. err = errors.New(fmt.Sprintf("获取excel表格数据,Err:%s", err.Error()))
  201. return
  202. }
  203. edbInfoIdList := make([]int, 0)
  204. for _, v := range list {
  205. edbInfoIdList = append(edbInfoIdList, v.EdbInfoId)
  206. relDateList, relDataList, tmpErr, tmpErrMsg := getDateAndDataList(v, xlsxFile)
  207. if tmpErr != nil {
  208. err = errors.New(fmt.Sprintf("《%s》获取对应的日期和数据列表,Err:%s", v.EdbName, tmpErr.Error()))
  209. errMsg = fmt.Sprintf("《%s》%s", v.EdbName, tmpErrMsg)
  210. return
  211. }
  212. if len(relDateList) <= 0 {
  213. errMsg = fmt.Sprintf("《%s》的日期序列为空", v.EdbName)
  214. err = errors.New(errMsg)
  215. return
  216. }
  217. if len(relDataList) <= 0 {
  218. errMsg = fmt.Sprintf("《%s》的数据序列为空", v.EdbName)
  219. err = errors.New(errMsg)
  220. return
  221. }
  222. req2 := &ResetCustomAnalysisData{
  223. EdbInfoId: v.EdbInfoId,
  224. DateList: relDateList,
  225. DataList: relDataList,
  226. }
  227. reqJson, tmpErr := json.Marshal(req2)
  228. if tmpErr != nil {
  229. err = errors.New(fmt.Sprintf("结构体转对象失败,Err:%s", tmpErr.Error()))
  230. return
  231. }
  232. respItem, tmpErr := data.ResetCustomAnalysisData(string(reqJson), lang)
  233. if tmpErr != nil {
  234. err = errors.New(fmt.Sprintf("调用指标库去更新,Err:%s", tmpErr.Error()))
  235. return
  236. }
  237. if respItem.Ret != 200 {
  238. errMsg = respItem.Msg
  239. err = errors.New(respItem.ErrMsg)
  240. return
  241. }
  242. }
  243. if len(edbInfoIdList) > 0 {
  244. err, _ = data.EdbInfoRefreshAllFromBaseV3(edbInfoIdList, false, true, true)
  245. }
  246. return
  247. }
  248. func getDateAndDataList(excelEdbMappingItem *excel.ExcelEdbMappingItem, xlsxFile *xlsx.File) (newDateList []string, newDataList []float64, err error, errMsg string) {
  249. var dateList, dataList []string
  250. {
  251. sheetName, startColumnName, endColumnName, startNum, endNum, isAll, isRow, isColumn, tmpErr, tmpErrMsg := GetSheetStr(excelEdbMappingItem.DateSequenceStr)
  252. if tmpErr != nil {
  253. errMsg = tmpErrMsg
  254. err = tmpErr
  255. return
  256. }
  257. sheetInfo, ok := xlsxFile.Sheet[sheetName]
  258. if !ok {
  259. errMsg = "找不到" + sheetName
  260. err = errors.New(errMsg)
  261. return
  262. }
  263. startNum = startNum - 1
  264. endNum = endNum - 1
  265. if isRow {
  266. var startColumn, endColumn int
  267. if isAll {
  268. endColumn = len(sheetInfo.Cols) - 1
  269. } else {
  270. tmpStartColumn, tmpErr := excelize.ColumnNameToNumber(startColumnName)
  271. if tmpErr != nil {
  272. errMsg = "列名异常:" + startColumnName
  273. err = errors.New(errMsg)
  274. return
  275. }
  276. tmpEndColumn, tmpErr := excelize.ColumnNameToNumber(endColumnName)
  277. if tmpErr != nil {
  278. errMsg = "列名异常:" + endColumnName
  279. err = errors.New(errMsg)
  280. return
  281. }
  282. startColumn = tmpStartColumn - 1
  283. endColumn = tmpEndColumn - 1
  284. }
  285. maxCol := len(sheetInfo.Cols)
  286. if endColumn > maxCol {
  287. endColumn = maxCol - 1
  288. }
  289. dateList = make([]string, endColumn-startColumn+1)
  290. i := 0
  291. for currColumn := startColumn; currColumn <= endColumn; currColumn++ {
  292. currCell := sheetInfo.Cell(startNum, currColumn)
  293. if currCell == nil {
  294. errMsg = fmt.Sprintf("第%d列,第%d行数据异常", startColumn, startNum)
  295. err = errors.New(errMsg)
  296. return
  297. }
  298. dateList[i] = currCell.Value
  299. i++
  300. }
  301. } else if isColumn { // 选择列的数据
  302. if isAll {
  303. endNum = len(sheetInfo.Rows) - 1
  304. }
  305. startColumn, tmpErr := excelize.ColumnNameToNumber(startColumnName)
  306. if tmpErr != nil {
  307. errMsg = "列名异常:" + startColumnName
  308. err = errors.New(errMsg)
  309. return
  310. }
  311. startColumn = startColumn - 1
  312. maxRow := len(sheetInfo.Rows)
  313. if endNum > maxRow {
  314. endNum = maxRow - 1
  315. }
  316. dateList = make([]string, endNum-startNum+1)
  317. i := 0
  318. for currRow := startNum; currRow <= endNum; currRow++ {
  319. currCell := sheetInfo.Cell(currRow, startColumn)
  320. if currCell == nil {
  321. errMsg = fmt.Sprintf("第%d列,第%d行数据异常", startColumn, startNum)
  322. err = errors.New(errMsg)
  323. return
  324. }
  325. dateList[i] = currCell.Value
  326. i++
  327. }
  328. }
  329. }
  330. {
  331. sheetName, startColumnName, endColumnName, startNum, endNum, isAll, isRow, isColumn, tmpErr, tmpErrMsg := GetSheetStr(excelEdbMappingItem.DataSequenceStr)
  332. if tmpErr != nil {
  333. errMsg = tmpErrMsg
  334. err = tmpErr
  335. return
  336. }
  337. sheetInfo, ok := xlsxFile.Sheet[sheetName]
  338. if !ok {
  339. errMsg = "找不到" + sheetName
  340. err = errors.New(errMsg)
  341. return
  342. }
  343. startNum = startNum - 1
  344. endNum = endNum - 1
  345. if isRow {
  346. var startColumn, endColumn int
  347. if isAll {
  348. endColumn = len(sheetInfo.Cols) - 1
  349. } else {
  350. tmpStartColumn, tmpErr := excelize.ColumnNameToNumber(startColumnName)
  351. if tmpErr != nil {
  352. errMsg = "列名异常:" + startColumnName
  353. err = errors.New(errMsg)
  354. return
  355. }
  356. tmpEndColumn, tmpErr := excelize.ColumnNameToNumber(endColumnName)
  357. if tmpErr != nil {
  358. errMsg = "列名异常:" + endColumnName
  359. err = errors.New(errMsg)
  360. return
  361. }
  362. startColumn = tmpStartColumn - 1
  363. endColumn = tmpEndColumn - 1
  364. }
  365. maxCol := len(sheetInfo.Cols)
  366. if endColumn > maxCol {
  367. endColumn = maxCol - 1
  368. }
  369. dataList = make([]string, endColumn-startColumn+1)
  370. i := 0
  371. for currColumn := startColumn; currColumn <= endColumn; currColumn++ {
  372. currCell := sheetInfo.Cell(startNum, currColumn)
  373. if currCell == nil {
  374. errMsg = fmt.Sprintf("第%d列,第%d行数据异常", startColumn, startNum)
  375. err = errors.New(errMsg)
  376. return
  377. }
  378. dataList[i] = currCell.Value
  379. i++
  380. }
  381. } else if isColumn { // 选择列的数据
  382. if isAll {
  383. endNum = len(sheetInfo.Rows) - 1
  384. }
  385. startColumn, tmpErr := excelize.ColumnNameToNumber(startColumnName)
  386. if tmpErr != nil {
  387. errMsg = "列名异常:" + startColumnName
  388. err = errors.New(errMsg)
  389. return
  390. }
  391. startColumn = startColumn - 1
  392. maxRow := len(sheetInfo.Rows)
  393. if endNum > maxRow {
  394. endNum = maxRow - 1
  395. }
  396. dataList = make([]string, endNum-startNum+1)
  397. i := 0
  398. for currRow := startNum; currRow <= endNum; currRow++ {
  399. currCell := sheetInfo.Cell(currRow, startColumn)
  400. if currCell == nil {
  401. errMsg = fmt.Sprintf("第%d列,第%d行数据异常", startColumn, startNum)
  402. err = errors.New(errMsg)
  403. return
  404. }
  405. dataList[i] = currCell.Value
  406. i++
  407. }
  408. }
  409. }
  410. newDateList, newDataList, err, errMsg = HandleEdbSequenceVal(dateList, dataList)
  411. return
  412. }
  413. func GetSheetStr(sequenceStr string) (sheetName, startColumnName, endColumnName string, startNum, endNum int, isAll, isRow, isColumn bool, err error, errMsg string) {
  414. tmpList := strings.Split(sequenceStr, "!")
  415. if len(tmpList) != 2 {
  416. errMsg = "错误的公式,查找sheet异常:" + sequenceStr
  417. err = errors.New(errMsg)
  418. return
  419. }
  420. sheetName = tmpList[0]
  421. tmpList = strings.Split(tmpList[1], ":")
  422. if len(tmpList) != 2 {
  423. errMsg = "错误的公式,查找开始/结束单元格异常:" + sequenceStr
  424. err = errors.New(errMsg)
  425. return
  426. }
  427. startList := strings.Split(tmpList[0], "$")
  428. endList := strings.Split(tmpList[1], "$")
  429. lenList := len(startList)
  430. if lenList != len(endList) {
  431. errMsg = "错误的公式,开始与结束单元格异常:" + sequenceStr
  432. err = errors.New(errMsg)
  433. return
  434. }
  435. if lenList != 3 && lenList != 2 {
  436. errMsg = "错误的公式:" + sequenceStr
  437. err = errors.New(errMsg)
  438. return
  439. }
  440. startColumnName = startList[1]
  441. endColumnName = endList[1]
  442. if lenList == 2 {
  443. isAll = true
  444. startDeci, tmpErr1 := decimal.NewFromString(startList[1])
  445. endDeci, tmpErr2 := decimal.NewFromString(endList[1])
  446. if tmpErr1 == nil && tmpErr2 == nil {
  447. isRow = true // 正常转换的话,那么就是整行
  448. startNum = int(startDeci.IntPart())
  449. endNum = int(endDeci.IntPart())
  450. startColumnName = ``
  451. endColumnName = ``
  452. return
  453. }
  454. if tmpErr1 == nil || tmpErr2 == nil {
  455. err = errors.New("错误的公式2:" + sequenceStr)
  456. return
  457. }
  458. isColumn = true
  459. return
  460. }
  461. startDeci, tmpErr1 := decimal.NewFromString(startList[2])
  462. endDeci, tmpErr2 := decimal.NewFromString(endList[2])
  463. if tmpErr1 != nil && errors.Is(tmpErr1, tmpErr2) {
  464. err = errors.New("错误的公式3:" + sequenceStr)
  465. return
  466. }
  467. startNum = int(startDeci.IntPart())
  468. endNum = int(endDeci.IntPart())
  469. if startColumnName != endColumnName && startNum != endNum {
  470. errMsg = `选区不允许跨行或者跨列`
  471. err = errors.New(errMsg)
  472. }
  473. if startColumnName == endColumnName {
  474. isColumn = true // 列数据
  475. } else {
  476. isRow = true // 行数据
  477. }
  478. return
  479. }