custom_analysis.go 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439
  1. package excel
  2. import (
  3. "encoding/json"
  4. "errors"
  5. "eta/eta_api/models/data_manage/excel"
  6. "eta/eta_api/models/data_manage/excel/request"
  7. "eta/eta_api/models/system"
  8. "eta/eta_api/utils"
  9. "strconv"
  10. "time"
  11. )
  12. var cellSplitNum = 10000 // 基础分割单元格数
  13. // AddCustomAnalysisTable 添加自定义分析表格
  14. func AddCustomAnalysisTable(excelName, content, excelImage string, excelClassifyId int, sysUser *system.Admin) (excelInfo *excel.ExcelInfo, err error, errMsg string, isSendEmail bool) {
  15. isSendEmail = true
  16. contentByte := []byte(content)
  17. var luckySheetList []LuckySheet
  18. err = json.Unmarshal(contentByte, &luckySheetList)
  19. if err != nil {
  20. return
  21. }
  22. // sheet内容为空
  23. if len(luckySheetList) <= 0 {
  24. errMsg = "sheet内容为空"
  25. err = errors.New(errMsg)
  26. isSendEmail = false
  27. return
  28. }
  29. excelClassify, err := excel.GetExcelClassifyById(excelClassifyId)
  30. if err != nil {
  31. if err.Error() == utils.ErrNoRow() {
  32. errMsg = "分类不存在"
  33. err = errors.New(errMsg)
  34. isSendEmail = false
  35. return
  36. }
  37. errMsg = "获取分类信息失败"
  38. err = errors.New("获取分类信息失败,Err:" + err.Error())
  39. return
  40. }
  41. if excelClassify == nil {
  42. errMsg = "分类不存在"
  43. err = errors.New(errMsg)
  44. isSendEmail = false
  45. return
  46. }
  47. if excelClassify.Source != utils.CUSTOM_ANALYSIS_TABLE {
  48. errMsg = "当前分类不是自定义分析分类"
  49. err = errors.New("当前分类不是自定义分析分类")
  50. isSendEmail = false
  51. return
  52. }
  53. // 校验是否同名文件
  54. {
  55. var condition string
  56. var pars []interface{}
  57. condition += " AND excel_classify_id=? "
  58. pars = append(pars, excelClassifyId)
  59. condition += " AND excel_name=? "
  60. pars = append(pars, excelName)
  61. // 获取分类下是否存在该表格名称
  62. count, tmpErr := excel.GetExcelInfoCountByCondition(condition, pars)
  63. if tmpErr != nil {
  64. errMsg = "判断表格名称是否存在失败"
  65. err = errors.New("判断表格名称是否存在失败,Err:" + tmpErr.Error())
  66. return
  67. }
  68. if count > 0 {
  69. errMsg = "表格名称已存在,请重新填写表格名称"
  70. err = errors.New(errMsg)
  71. isSendEmail = false
  72. return
  73. }
  74. }
  75. timestamp := strconv.FormatInt(time.Now().UnixNano(), 10)
  76. // 表格
  77. excelInfo = &excel.ExcelInfo{
  78. //ExcelInfoId: 0,
  79. ExcelName: excelName,
  80. Source: utils.CUSTOM_ANALYSIS_TABLE,
  81. //ExcelType: req.ExcelType,
  82. UniqueCode: utils.MD5(utils.EXCEL_DATA_PREFIX + "_" + timestamp),
  83. ExcelClassifyId: excelClassifyId,
  84. SysUserId: sysUser.AdminId,
  85. SysUserRealName: sysUser.RealName,
  86. Content: ``,
  87. ExcelImage: excelImage,
  88. Sort: 0,
  89. IsDelete: 0,
  90. ModifyTime: time.Now(),
  91. CreateTime: time.Now(),
  92. }
  93. addSheetList := make([]excel.AddExcelSheetParams, 0)
  94. // sheet处理
  95. sheetNameMap := make(map[string]string)
  96. for k, sheetInfo := range luckySheetList {
  97. sheetName := utils.TrimLRStr(sheetInfo.Name)
  98. _, ok := sheetNameMap[sheetName]
  99. if ok {
  100. errMsg = "excel表中存在同名sheet"
  101. err = errors.New(errMsg)
  102. isSendEmail = false
  103. return
  104. }
  105. sheetConf, tmpErr := json.Marshal(sheetInfo.Config)
  106. if tmpErr != nil {
  107. err = tmpErr
  108. return
  109. }
  110. // 计算公式
  111. sheetCalcChain, tmpErr := json.Marshal(sheetInfo.CalcChain)
  112. if tmpErr != nil {
  113. err = tmpErr
  114. return
  115. }
  116. sheetFrozen, tmpErr := json.Marshal(sheetInfo.Frozen)
  117. if tmpErr != nil {
  118. err = tmpErr
  119. return
  120. }
  121. addSheetItem := excel.AddExcelSheetParams{
  122. ExcelSheetId: 0,
  123. ExcelInfoId: 0,
  124. SheetName: sheetName,
  125. Index: sheetInfo.Index,
  126. Sort: k,
  127. Config: string(sheetConf),
  128. CalcChain: string(sheetCalcChain),
  129. Frozen: string(sheetFrozen),
  130. }
  131. lenCellData := len(sheetInfo.CellData)
  132. splitLen := lenCellData / cellSplitNum
  133. residue := lenCellData % cellSplitNum
  134. if residue > 0 {
  135. splitLen += 1
  136. }
  137. sheetDataList := make([]*excel.ExcelSheetData, 0)
  138. for i := 0; i < splitLen; i++ {
  139. startRow := i * cellSplitNum
  140. endRow := (i + 1) * cellSplitNum
  141. if i == splitLen-1 && residue > 0 {
  142. endRow = lenCellData
  143. }
  144. tmpData := sheetInfo.CellData[startRow:endRow]
  145. tmpDataByte, tmpErr := json.Marshal(tmpData)
  146. if tmpErr != nil {
  147. errMsg = "保存失败"
  148. err = errors.New("保存失败:" + tmpErr.Error())
  149. return
  150. }
  151. sheetDataList = append(sheetDataList, &excel.ExcelSheetData{
  152. ExcelDataId: 0,
  153. ExcelInfoId: 0,
  154. ExcelSheetId: 0,
  155. Sort: i + 1,
  156. Data: string(tmpDataByte),
  157. ModifyTime: time.Now(),
  158. CreateTime: time.Now(),
  159. })
  160. }
  161. addSheetItem.DataList = sheetDataList
  162. addSheetList = append(addSheetList, addSheetItem)
  163. }
  164. err = excel.AddExcelInfoAndSheet(excelInfo, addSheetList)
  165. return
  166. }
  167. // SaveCustomAnalysisTable 编辑自定义分析表格
  168. func SaveCustomAnalysisTable(excelInfo *excel.ExcelInfo, excelName, content, excelImage string, excelClassifyId int, sheetOpList []request.SheetOp) (err error, errMsg string, isSendEmail bool) {
  169. isSendEmail = true
  170. contentByte := []byte(content)
  171. var luckySheetList []LuckySheet
  172. err = json.Unmarshal(contentByte, &luckySheetList)
  173. if err != nil {
  174. return
  175. }
  176. // sheet内容为空
  177. if len(luckySheetList) <= 0 {
  178. errMsg = "sheet内容为空"
  179. err = errors.New(errMsg)
  180. isSendEmail = false
  181. return
  182. }
  183. // sheet内容为空
  184. //if len(sheetOpList) <= 0 {
  185. // errMsg = "sheet操作为空"
  186. // err = errors.New(errMsg)
  187. // isSendEmail = false
  188. // return
  189. //}
  190. excelClassify, err := excel.GetExcelClassifyById(excelClassifyId)
  191. if err != nil {
  192. if err.Error() == utils.ErrNoRow() {
  193. errMsg = "分类不存在"
  194. err = errors.New(errMsg)
  195. isSendEmail = false
  196. return
  197. }
  198. errMsg = "获取分类信息失败"
  199. err = errors.New("获取分类信息失败,Err:" + err.Error())
  200. return
  201. }
  202. if excelClassify == nil {
  203. errMsg = "分类不存在"
  204. err = errors.New(errMsg)
  205. isSendEmail = false
  206. return
  207. }
  208. if excelClassify.Source != utils.CUSTOM_ANALYSIS_TABLE {
  209. errMsg = "当前分类不是自定义分析分类"
  210. err = errors.New("当前分类不是自定义分析分类")
  211. isSendEmail = false
  212. return
  213. }
  214. // 校验是否同名文件
  215. {
  216. var condition string
  217. var pars []interface{}
  218. condition += " AND excel_classify_id=? AND excel_info_id !=? "
  219. pars = append(pars, excelClassifyId, excelInfo.ExcelInfoId)
  220. condition += " AND excel_name=? "
  221. pars = append(pars, excelName)
  222. // 获取分类下是否存在该表格名称
  223. count, tmpErr := excel.GetExcelInfoCountByCondition(condition, pars)
  224. if tmpErr != nil {
  225. errMsg = "判断表格名称是否存在失败"
  226. err = errors.New("判断表格名称是否存在失败,Err:" + tmpErr.Error())
  227. return
  228. }
  229. if count > 0 {
  230. errMsg = "表格名称已存在,请重新填写表格名称"
  231. err = errors.New(errMsg)
  232. isSendEmail = false
  233. return
  234. }
  235. }
  236. //// 查找当前excel的sheet列表
  237. //currSheetList, err := excel.GetAllSheetList(excelInfo.ExcelInfoId)
  238. //if err != nil {
  239. // errMsg = "保存失败"
  240. // err = errors.New("查找当前excel的sheet列表失败,Err:" + err.Error())
  241. // return
  242. //}
  243. //currSheetMap := make(map[string]string)
  244. //for _, currSheet := range currSheetList {
  245. // currSheetMap[currSheet.SheetName] = currSheet.SheetName
  246. //}
  247. //
  248. //for k, sheetOp := range sheetOpList {
  249. // sheetName := utils.TrimLRStr(sheetOp.SheetName)
  250. // switch sheetOp.OpType {
  251. // case "add":
  252. // // 新增
  253. // _, ok := currSheetMap[sheetName]
  254. // if ok {
  255. // errMsg = "存在同名sheet:" + sheetName
  256. // err = errors.New(errMsg)
  257. // isSendEmail = false
  258. // return
  259. // }
  260. // case "replace":
  261. // // 替换
  262. // case "append":
  263. // // 追加
  264. // default:
  265. // errMsg = fmt.Sprint("第", k+1, "个sheet,错误的操作类型")
  266. // err = errors.New(errMsg + "op:" + sheetOp.OpType)
  267. // isSendEmail = false
  268. // return
  269. // }
  270. //}
  271. // 表格
  272. excelInfo.ExcelName = excelName
  273. // 如果分类不传入的话,那么分类不变更
  274. if excelClassifyId <= 0 {
  275. excelInfo.ExcelClassifyId = excelClassifyId
  276. }
  277. // 如果缩略图不传入的话,那么缩略图不变更
  278. if excelImage != `` {
  279. excelInfo.ExcelImage = excelImage
  280. }
  281. excelInfo.ModifyTime = time.Now()
  282. updateExcelInfoParam := []string{"ExcelName", "ExcelClassifyId", "ExcelImage", "ModifyTime"}
  283. addSheetList := make([]excel.AddExcelSheetParams, 0)
  284. // sheet处理
  285. sheetNameMap := make(map[string]string)
  286. for k, sheetInfo := range luckySheetList {
  287. sheetName := utils.TrimLRStr(sheetInfo.Name)
  288. _, ok := sheetNameMap[sheetName]
  289. if ok {
  290. errMsg = "excel表中存在同名sheet"
  291. err = errors.New(errMsg)
  292. isSendEmail = false
  293. return
  294. }
  295. sheetConf, tmpErr := json.Marshal(sheetInfo.Config)
  296. if tmpErr != nil {
  297. err = tmpErr
  298. return
  299. }
  300. // 计算公式
  301. sheetCalcChain, tmpErr := json.Marshal(sheetInfo.CalcChain)
  302. if tmpErr != nil {
  303. err = tmpErr
  304. return
  305. }
  306. sheetFrozen, tmpErr := json.Marshal(sheetInfo.Frozen)
  307. if tmpErr != nil {
  308. err = tmpErr
  309. return
  310. }
  311. addSheetItem := excel.AddExcelSheetParams{
  312. ExcelSheetId: 0,
  313. ExcelInfoId: excelInfo.ExcelInfoId,
  314. SheetName: sheetName,
  315. Index: sheetInfo.Index,
  316. Sort: k,
  317. Config: string(sheetConf),
  318. CalcChain: string(sheetCalcChain),
  319. Frozen: string(sheetFrozen),
  320. }
  321. lenCellData := len(sheetInfo.CellData)
  322. splitLen := lenCellData / cellSplitNum
  323. residue := lenCellData % cellSplitNum
  324. if residue > 0 {
  325. splitLen += 1
  326. }
  327. sheetDataList := make([]*excel.ExcelSheetData, 0)
  328. for i := 0; i < splitLen; i++ {
  329. startRow := i * cellSplitNum
  330. endRow := (i + 1) * cellSplitNum
  331. if i == splitLen-1 && residue > 0 {
  332. endRow = lenCellData
  333. }
  334. tmpData := sheetInfo.CellData[startRow:endRow]
  335. tmpDataByte, tmpErr := json.Marshal(tmpData)
  336. if tmpErr != nil {
  337. errMsg = "保存失败"
  338. err = errors.New("保存失败:" + tmpErr.Error())
  339. return
  340. }
  341. sheetDataList = append(sheetDataList, &excel.ExcelSheetData{
  342. ExcelDataId: 0,
  343. ExcelInfoId: excelInfo.ExcelInfoId,
  344. ExcelSheetId: 0,
  345. Sort: i + 1,
  346. Data: string(tmpDataByte),
  347. ModifyTime: time.Now(),
  348. CreateTime: time.Now(),
  349. })
  350. }
  351. addSheetItem.DataList = sheetDataList
  352. addSheetList = append(addSheetList, addSheetItem)
  353. }
  354. err = excel.SaveExcelInfoAndSheet(excelInfo, updateExcelInfoParam, addSheetList)
  355. return
  356. }
  357. type LuckySheet struct {
  358. Name string `json:"name"`
  359. //Config struct {
  360. // Columnlen struct {
  361. // Num15 int `json:"15"`
  362. // Num16 int `json:"16"`
  363. // Num20 int `json:"20"`
  364. // Num34 int `json:"34"`
  365. // Num35 int `json:"35"`
  366. // } `json:"columnlen"`
  367. //} `json:"config"`
  368. Config interface{}
  369. Index string `json:"index"`
  370. Order int `json:"order"`
  371. ZoomRatio float64 `json:"zoomRatio"`
  372. ShowGridLines string `json:"showGridLines"`
  373. DefaultColWidth int `json:"defaultColWidth"`
  374. DefaultRowHeight int `json:"defaultRowHeight"`
  375. CellData []LuckySheetCellData `json:"celldata"`
  376. CalcChain []interface{} `json:"calcChain"`
  377. Frozen interface{} `json:"frozen"`
  378. //DataVerification struct {
  379. //} `json:"dataVerification"`
  380. //Hyperlink struct {
  381. //} `json:"hyperlink"`
  382. //Hide int `json:"hide"`
  383. }
  384. // LuckySheetCellData 单元格数据
  385. type LuckySheetCellData struct {
  386. R int `json:"r"`
  387. C int `json:"c"`
  388. V interface{} `json:"v,omitempty"`
  389. }