report.go 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606
  1. package api
  2. import (
  3. "box-cost/db/model"
  4. "box-cost/db/repo"
  5. "errors"
  6. "fmt"
  7. "strings"
  8. "time"
  9. "github.com/gin-gonic/gin"
  10. "github.com/go-redis/redis/v8"
  11. "github.com/xuri/excelize/v2"
  12. "go.mongodb.org/mongo-driver/bson/primitive"
  13. )
  14. // 统计报表 按时间范围,供应商 包装-计划(多选) 维度进行过滤,形成报表。可以下载
  15. func Report(r *GinRouter) {
  16. // 加工列表
  17. r.GET("/report/produce/list", ReportProduceList)
  18. // 采购列表
  19. r.GET("/report/purchase/list", ReportPurchaseList)
  20. r.GET("/report/product/list", ReportProductList)
  21. r.GET("/report/produce/download", ReportProduceDownload)
  22. r.GET("/report/purchase/download", ReportPurchaseDownload)
  23. r.GET("/report/product/download", ReportProductDownload)
  24. r.GETJWT("/report/list", ReportList)
  25. r.GETJWT("/report/download", ReportListDownload)
  26. }
  27. // 加工单
  28. func ReportListDownload(c *gin.Context, apictx *ApiSession) (interface{}, error) {
  29. _, _, query := UtilQueryPageSize(c)
  30. // start, stop := CreatePageRange(page, size)
  31. supplierId := primitive.NilObjectID
  32. if _supplierId, ok := query["supplierId"]; ok {
  33. supplierId, _ = primitive.ObjectIDFromHex(_supplierId.(string))
  34. }
  35. timeRange := []interface{}{}
  36. if _timeRange, ok := query["timeRange"]; ok {
  37. timeRange, _ = _timeRange.([]interface{})
  38. }
  39. filtter := handleReportQuery(query)
  40. purchases := []*model.PurchaseBill{}
  41. produces := []*model.ProduceBill{}
  42. products := []*model.ProductBill{}
  43. repo.RepoDocsSearch(apictx.CreateRepoCtx(), &repo.PageSearchOptions{
  44. CollectName: repo.CollectionBillPurchase,
  45. Query: filtter,
  46. Project: []string{"_id", "completeTime"},
  47. }, &purchases)
  48. repo.RepoDocsSearch(apictx.CreateRepoCtx(), &repo.PageSearchOptions{
  49. CollectName: repo.CollectionBillProduce,
  50. Query: filtter,
  51. Project: []string{"_id", "completeTime"},
  52. }, &produces)
  53. repo.RepoDocsSearch(apictx.CreateRepoCtx(), &repo.PageSearchOptions{
  54. CollectName: repo.CollectionBillProduct,
  55. Query: filtter,
  56. Project: []string{"_id", "completeTime"},
  57. }, &products)
  58. // 加入redis有序集合中
  59. redisCli := apictx.Svc.Redis
  60. reportBillKey := "report-bill-list:" + apictx.User.Parent
  61. isExist := redisCli.Exists(apictx.CreateRepoCtx().Ctx, reportBillKey).Val()
  62. // 不存在这个key时
  63. if isExist < 1 {
  64. if len(purchases) > 0 {
  65. for _, purchase := range purchases {
  66. member := "purchase_" + purchase.Id.Hex()
  67. score := purchase.CompleteTime.Unix()
  68. redisCli.ZAdd(apictx.CreateRepoCtx().Ctx, reportBillKey, &redis.Z{Score: float64(score), Member: member})
  69. }
  70. }
  71. if len(produces) > 0 {
  72. for _, produce := range produces {
  73. member := "produce_" + produce.Id.Hex()
  74. score := produce.CompleteTime.Unix()
  75. redisCli.ZAdd(apictx.CreateRepoCtx().Ctx, reportBillKey, &redis.Z{Score: float64(score), Member: member})
  76. }
  77. }
  78. if len(products) > 0 {
  79. for _, product := range products {
  80. member := "product_" + product.Id.Hex()
  81. score := product.CompleteTime.Unix()
  82. redisCli.ZAdd(apictx.CreateRepoCtx().Ctx, reportBillKey, &redis.Z{Score: float64(score), Member: member})
  83. }
  84. }
  85. // 设置过期时间
  86. redisCli.Expire(apictx.CreateRepoCtx().Ctx, reportBillKey, 20*time.Second)
  87. }
  88. total, err := redisCli.ZCard(apictx.CreateRepoCtx().Ctx, reportBillKey).Uint64()
  89. fmt.Println(total)
  90. if err != nil {
  91. fmt.Println(err)
  92. return nil, err
  93. }
  94. reports, err := redisCli.ZRevRange(apictx.CreateRepoCtx().Ctx, reportBillKey, 0, -1).Result()
  95. if err != nil {
  96. return nil, err
  97. }
  98. if len(reports) < 1 {
  99. return nil, errors.New("没有单据信息")
  100. }
  101. lists := []map[string]interface{}{}
  102. for _, report := range reports {
  103. billArray := strings.Split(report, "_")
  104. billType := billArray[0]
  105. _billId := billArray[1]
  106. billId, _ := primitive.ObjectIDFromHex(_billId)
  107. billData := map[string]interface{}{}
  108. found := false
  109. if billType == "purchase" {
  110. found, billData = repo.RepoSeachDocMap(apictx.CreateRepoCtx(), &repo.DocSearchOptions{
  111. CollectName: repo.CollectionBillPurchase,
  112. Query: repo.Map{"_id": billId},
  113. })
  114. }
  115. if billType == "produce" {
  116. found, billData = repo.RepoSeachDocMap(apictx.CreateRepoCtx(), &repo.DocSearchOptions{
  117. CollectName: repo.CollectionBillProduce,
  118. Query: repo.Map{"_id": billId},
  119. })
  120. }
  121. if billType == "product" {
  122. found, billData = repo.RepoSeachDocMap(apictx.CreateRepoCtx(), &repo.DocSearchOptions{
  123. CollectName: repo.CollectionBillProduct,
  124. Query: repo.Map{"_id": billId},
  125. })
  126. }
  127. if found {
  128. billData["billType"] = billType
  129. lists = append(lists, billData)
  130. }
  131. }
  132. f := excelize.NewFile()
  133. defer f.Close()
  134. index := f.NewSheet("Sheet1")
  135. f.SetActiveSheet(index)
  136. f.SetDefaultFont("宋体")
  137. report := NewReportExcel(f)
  138. supplier := model.Supplier{}
  139. supplierName := "【所有供应商】"
  140. if !supplierId.IsZero() {
  141. repo.RepoSeachDoc(apictx.CreateRepoCtx(), &repo.DocSearchOptions{
  142. CollectName: repo.CollectionSupplier,
  143. Query: repo.Map{"supplierId": supplierId},
  144. Project: []string{"name"},
  145. }, &supplier)
  146. supplierName = supplier.Name
  147. }
  148. report.SupplierName = supplierName
  149. if len(timeRange) == 2 {
  150. report.TimeRange = append(report.TimeRange, timeRange[0].(string), timeRange[1].(string))
  151. }
  152. report.Content = lists
  153. report.Draws()
  154. c.Header("Content-Type", "application/octet-stream")
  155. c.Header("Content-Disposition", "attachment; filename="+"report.xlsx")
  156. c.Header("Content-Transfer-Encoding", "binary")
  157. err = f.Write(c.Writer)
  158. if err != nil {
  159. return nil, err
  160. }
  161. return nil, nil
  162. }
  163. // 加工单
  164. func ReportList(c *gin.Context, apictx *ApiSession) (interface{}, error) {
  165. page, size, query := UtilQueryPageSize(c)
  166. start, stop := CreatePageRange(page, size)
  167. filtter := handleReportQuery(query)
  168. purchases := []*model.PurchaseBill{}
  169. produces := []*model.ProduceBill{}
  170. products := []*model.ProductBill{}
  171. repo.RepoDocsSearch(apictx.CreateRepoCtx(), &repo.PageSearchOptions{
  172. CollectName: repo.CollectionBillPurchase,
  173. Query: filtter,
  174. Project: []string{"_id", "completeTime"},
  175. }, &purchases)
  176. repo.RepoDocsSearch(apictx.CreateRepoCtx(), &repo.PageSearchOptions{
  177. CollectName: repo.CollectionBillProduce,
  178. Query: filtter,
  179. Project: []string{"_id", "completeTime"},
  180. }, &produces)
  181. repo.RepoDocsSearch(apictx.CreateRepoCtx(), &repo.PageSearchOptions{
  182. CollectName: repo.CollectionBillProduct,
  183. Query: filtter,
  184. Project: []string{"_id", "completeTime"},
  185. }, &products)
  186. // 加入redis有序集合中
  187. redisCli := apictx.Svc.Redis
  188. reportBillKey := "report-bill-list:" + apictx.User.Parent
  189. isExist := redisCli.Exists(apictx.CreateRepoCtx().Ctx, reportBillKey).Val()
  190. // 不存在这个key时
  191. if isExist < 1 {
  192. if len(purchases) > 0 {
  193. for _, purchase := range purchases {
  194. member := "purchase_" + purchase.Id.Hex()
  195. score := purchase.CompleteTime.Unix()
  196. redisCli.ZAdd(apictx.CreateRepoCtx().Ctx, reportBillKey, &redis.Z{Score: float64(score), Member: member})
  197. }
  198. }
  199. if len(produces) > 0 {
  200. for _, produce := range produces {
  201. member := "produce_" + produce.Id.Hex()
  202. score := produce.CompleteTime.Unix()
  203. redisCli.ZAdd(apictx.CreateRepoCtx().Ctx, reportBillKey, &redis.Z{Score: float64(score), Member: member})
  204. }
  205. }
  206. if len(products) > 0 {
  207. for _, product := range products {
  208. member := "product_" + product.Id.Hex()
  209. score := product.CompleteTime.Unix()
  210. redisCli.ZAdd(apictx.CreateRepoCtx().Ctx, reportBillKey, &redis.Z{Score: float64(score), Member: member})
  211. }
  212. }
  213. // 设置过期时间
  214. redisCli.Expire(apictx.CreateRepoCtx().Ctx, reportBillKey, 20*time.Second)
  215. }
  216. total, err := redisCli.ZCard(apictx.CreateRepoCtx().Ctx, reportBillKey).Uint64()
  217. if err != nil {
  218. fmt.Println(err)
  219. return nil, err
  220. }
  221. reports, err := redisCli.ZRevRange(apictx.CreateRepoCtx().Ctx, reportBillKey, start, stop).Result()
  222. if err != nil {
  223. return nil, err
  224. }
  225. if len(reports) < 1 {
  226. return repo.PageResult{
  227. Page: page,
  228. Size: size,
  229. Total: 0,
  230. }, nil
  231. }
  232. lists := []map[string]interface{}{}
  233. for _, report := range reports {
  234. billArray := strings.Split(report, "_")
  235. billType := billArray[0]
  236. _billId := billArray[1]
  237. billId, _ := primitive.ObjectIDFromHex(_billId)
  238. billData := map[string]interface{}{}
  239. found := false
  240. if billType == "purchase" {
  241. found, billData = repo.RepoSeachDocMap(apictx.CreateRepoCtx(), &repo.DocSearchOptions{
  242. CollectName: repo.CollectionBillPurchase,
  243. Query: repo.Map{"_id": billId},
  244. })
  245. }
  246. if billType == "produce" {
  247. found, billData = repo.RepoSeachDocMap(apictx.CreateRepoCtx(), &repo.DocSearchOptions{
  248. CollectName: repo.CollectionBillProduce,
  249. Query: repo.Map{"_id": billId},
  250. })
  251. }
  252. if billType == "product" {
  253. found, billData = repo.RepoSeachDocMap(apictx.CreateRepoCtx(), &repo.DocSearchOptions{
  254. CollectName: repo.CollectionBillProduct,
  255. Query: repo.Map{"_id": billId},
  256. })
  257. }
  258. if found {
  259. billData["billType"] = billType
  260. lists = append(lists, billData)
  261. }
  262. }
  263. return repo.PageResult{
  264. List: lists,
  265. Total: int64(total),
  266. Page: page,
  267. Size: size,
  268. }, nil
  269. }
  270. func CreatePageRange(page, size int64) (int64, int64) {
  271. if page < 1 {
  272. page = 1
  273. }
  274. if size < 1 {
  275. size = 10
  276. }
  277. start := (page - 1) * size
  278. stop := page*size - 1
  279. return start, stop
  280. }
  281. func ReportProduceList(c *gin.Context, apictx *ApiSession) (interface{}, error) {
  282. page, size, query := UtilQueryPageSize(c)
  283. // 条件处理
  284. // 获取采购单符合条件的信息
  285. return repo.RepoPageSearch(apictx.CreateRepoCtx(), &repo.PageSearchOptions{
  286. CollectName: repo.CollectionBillProduce,
  287. Query: handleReportQuery(query),
  288. Page: page,
  289. Size: size,
  290. })
  291. }
  292. // 采购单
  293. func ReportPurchaseList(c *gin.Context, apictx *ApiSession) (interface{}, error) {
  294. page, size, query := UtilQueryPageSize(c)
  295. return repo.RepoPageSearch(apictx.CreateRepoCtx(), &repo.PageSearchOptions{
  296. CollectName: repo.CollectionBillPurchase,
  297. Query: handleReportQuery(query),
  298. Page: page,
  299. Size: size,
  300. })
  301. }
  302. func ReportProductList(c *gin.Context, apictx *ApiSession) (interface{}, error) {
  303. page, size, query := UtilQueryPageSize(c)
  304. return repo.RepoPageSearch(apictx.CreateRepoCtx(), &repo.PageSearchOptions{
  305. CollectName: repo.CollectionBillProduct,
  306. Query: handleReportQuery(query),
  307. Page: page,
  308. Size: size,
  309. })
  310. }
  311. func ReportProduceDownload(c *gin.Context, apictx *ApiSession) (interface{}, error) {
  312. _, _, query := UtilQueryPageSize(c)
  313. // 获取采符合条件的信息
  314. produces := []*model.ProduceBill{}
  315. err := repo.RepoDocsSearch(apictx.CreateRepoCtx(), &repo.PageSearchOptions{
  316. CollectName: repo.CollectionBillProduce,
  317. Query: handleReportQuery(query),
  318. }, &produces)
  319. if err != nil || len(produces) < 1 {
  320. return nil, errors.New("数据不存在")
  321. }
  322. f := excelize.NewFile()
  323. index := f.NewSheet("Sheet1")
  324. sheetName := f.GetSheetName(index)
  325. f.SetActiveSheet(index)
  326. f.SetDefaultFont("宋体")
  327. border := []excelize.Border{
  328. {Type: "top", Style: 1, Color: "000000"},
  329. {Type: "left", Style: 1, Color: "000000"},
  330. {Type: "right", Style: 1, Color: "000000"},
  331. {Type: "bottom", Style: 1, Color: "000000"},
  332. }
  333. alignCenterStyle, _ := f.NewStyle(&excelize.Style{
  334. Alignment: &excelize.Alignment{Horizontal: "center", Vertical: "center"},
  335. Border: border,
  336. })
  337. companyName := getCompanyName(apictx)
  338. var budgetAmount float64 = 0
  339. var realAmount float64 = 0
  340. var row int = 0
  341. for _, produce := range produces {
  342. produceExcel := NewReportProduceExcel(f)
  343. produceExcel.Row = row
  344. produceExcel.Content = produce
  345. produceExcel.Title = fmt.Sprintf("%s加工单", companyName)
  346. //设置对应的数据
  347. produceExcel.Draws()
  348. budgetAmount += produceExcel.BudgetAmount
  349. realAmount += produceExcel.RealAmount
  350. row = produceExcel.Row + 3
  351. }
  352. row = row - 2
  353. startCell := fmt.Sprintf("%s%d", "A", row)
  354. endCell := fmt.Sprintf("%s%d", "H", row)
  355. f.MergeCell(sheetName, startCell, endCell)
  356. f.SetCellStyle(sheetName, startCell, endCell, alignCenterStyle)
  357. f.SetCellValue(sheetName, startCell, "汇总金额")
  358. // 预算金额汇总
  359. budgetAmountCell := fmt.Sprintf("%s%d", "I", row)
  360. budgetAmountStr := ""
  361. if budgetAmount > 0 {
  362. budgetAmountStr = fmt.Sprintf("%.3f", budgetAmount)
  363. }
  364. f.SetCellValue(sheetName, budgetAmountCell, budgetAmountStr)
  365. f.SetCellStyle(sheetName, budgetAmountCell, budgetAmountCell, alignCenterStyle)
  366. // 实际金额汇总
  367. realAmountCell := fmt.Sprintf("%s%d", "J", row)
  368. realAmountStr := ""
  369. if realAmount > 0 {
  370. realAmountStr = fmt.Sprintf("%.3f", realAmount)
  371. }
  372. f.SetCellValue(sheetName, realAmountCell, realAmountStr)
  373. f.SetCellStyle(sheetName, realAmountCell, realAmountCell, alignCenterStyle)
  374. f.SetRowHeight(sheetName, row, 21)
  375. c.Header("Content-Type", "application/octet-stream")
  376. c.Header("Content-Disposition", "attachment; filename="+"reportProduce.xlsx")
  377. c.Header("Content-Transfer-Encoding", "binary")
  378. err = f.Write(c.Writer)
  379. if err != nil {
  380. return nil, err
  381. }
  382. return nil, nil
  383. }
  384. func ReportPurchaseDownload(c *gin.Context, apictx *ApiSession) (interface{}, error) {
  385. _, _, query := UtilQueryPageSize(c)
  386. purchases := []model.PurchaseBill{}
  387. err := repo.RepoDocsSearch(apictx.CreateRepoCtx(), &repo.PageSearchOptions{
  388. CollectName: repo.CollectionBillPurchase,
  389. Query: handleReportQuery(query),
  390. }, &purchases)
  391. if err != nil || len(purchases) < 1 {
  392. return nil, errors.New("数据不存在")
  393. }
  394. f := excelize.NewFile()
  395. index := f.NewSheet("Sheet1")
  396. sheetName := f.GetSheetName(index)
  397. f.SetActiveSheet(index)
  398. f.SetDefaultFont("宋体")
  399. border := []excelize.Border{
  400. {Type: "top", Style: 1, Color: "000000"},
  401. {Type: "left", Style: 1, Color: "000000"},
  402. {Type: "right", Style: 1, Color: "000000"},
  403. {Type: "bottom", Style: 1, Color: "000000"},
  404. }
  405. alignCenterStyle, _ := f.NewStyle(&excelize.Style{
  406. Alignment: &excelize.Alignment{Horizontal: "center", Vertical: "center"},
  407. Border: border,
  408. })
  409. companyName := getCompanyName(apictx)
  410. var budgetCount float64 = 0
  411. var realCount float64 = 0
  412. var row int = 0
  413. for _, purchase := range purchases {
  414. var reportBill *ReportPurchaseExcel
  415. if len(purchase.Paper) > 0 {
  416. reportBill = NewReportPurchaseExcel(f)
  417. }
  418. if reportBill == nil {
  419. return nil, errors.New("数据不存在")
  420. }
  421. reportBill.Row = row
  422. reportBill.Content = &purchase
  423. reportBill.Title = fmt.Sprintf("%s原材料采购单", companyName)
  424. reportBill.Draws()
  425. budgetCount += reportBill.BudgetAmount
  426. realCount += reportBill.RealAmount
  427. row = reportBill.Row + 3
  428. }
  429. row = row - 2
  430. startCell := fmt.Sprintf("%s%d", "A", row)
  431. endCell := fmt.Sprintf("%s%d", "H", row)
  432. f.MergeCell(sheetName, startCell, endCell)
  433. f.SetCellStyle(sheetName, startCell, endCell, alignCenterStyle)
  434. f.SetCellValue(sheetName, startCell, "汇总金额")
  435. // 预算金额汇总
  436. budgetCountCell := fmt.Sprintf("%s%d", "I", row)
  437. budgetCountStr := ""
  438. if realCount > 0 {
  439. budgetCountStr = fmt.Sprintf("%.3f", budgetCount)
  440. }
  441. f.SetCellValue(sheetName, budgetCountCell, budgetCountStr)
  442. f.SetCellStyle(sheetName, budgetCountCell, budgetCountCell, alignCenterStyle)
  443. // 实际金额汇总
  444. RealCountCell := fmt.Sprintf("%s%d", "J", row)
  445. realCountStr := ""
  446. if realCount > 0 {
  447. realCountStr = fmt.Sprintf("%.3f", realCount)
  448. }
  449. f.SetCellValue(sheetName, RealCountCell, realCountStr)
  450. f.SetCellStyle(sheetName, RealCountCell, RealCountCell, alignCenterStyle)
  451. f.SetRowHeight(sheetName, row, 21)
  452. c.Header("Content-Type", "application/octet-stream")
  453. c.Header("Content-Disposition", "attachment; filename="+"reportPurchase.xlsx")
  454. c.Header("Content-Transfer-Encoding", "binary")
  455. err = f.Write(c.Writer)
  456. if err != nil {
  457. return nil, err
  458. }
  459. return nil, nil
  460. }
  461. func ReportProductDownload(c *gin.Context, apictx *ApiSession) (interface{}, error) {
  462. _, _, query := UtilQueryPageSize(c)
  463. // 获取采符合条件的信息
  464. products := []*model.ProductBill{}
  465. err := repo.RepoDocsSearch(apictx.CreateRepoCtx(), &repo.PageSearchOptions{
  466. CollectName: repo.CollectionBillProduct,
  467. Query: handleReportQuery(query),
  468. }, &products)
  469. if err != nil || len(products) < 1 {
  470. return nil, errors.New("数据不存在")
  471. }
  472. f := excelize.NewFile()
  473. index := f.NewSheet("Sheet1")
  474. sheetName := f.GetSheetName(index)
  475. f.SetActiveSheet(index)
  476. f.SetDefaultFont("宋体")
  477. border := []excelize.Border{
  478. {Type: "top", Style: 1, Color: "000000"},
  479. {Type: "left", Style: 1, Color: "000000"},
  480. {Type: "right", Style: 1, Color: "000000"},
  481. {Type: "bottom", Style: 1, Color: "000000"},
  482. }
  483. alignCenterStyle, _ := f.NewStyle(&excelize.Style{
  484. Alignment: &excelize.Alignment{Horizontal: "center", Vertical: "center"},
  485. Border: border,
  486. })
  487. companyName := getCompanyName(apictx)
  488. var budgetAmount float64 = 0
  489. var realAmount float64 = 0
  490. var row int = 0
  491. for _, product := range products {
  492. productExcel := NewReportProductBill(f)
  493. productExcel.Row = row
  494. productExcel.Content = product
  495. productExcel.Title = companyName
  496. productExcel.Draws()
  497. budgetAmount += productExcel.BudgetAmount
  498. realAmount += productExcel.RealAmount
  499. row = productExcel.Row + 3
  500. }
  501. row = row - 2
  502. startCell := fmt.Sprintf("%s%d", "A", row)
  503. endCell := fmt.Sprintf("%s%d", "H", row)
  504. f.MergeCell(sheetName, startCell, endCell)
  505. f.SetCellStyle(sheetName, startCell, endCell, alignCenterStyle)
  506. f.SetCellValue(sheetName, startCell, "汇总金额")
  507. // 预算金额汇总
  508. budgetAmountCell := fmt.Sprintf("%s%d", "I", row)
  509. budgetCountStr := ""
  510. if realAmount > 0 {
  511. budgetCountStr = fmt.Sprintf("%.3f", realAmount)
  512. }
  513. f.SetCellValue(sheetName, budgetAmountCell, budgetCountStr)
  514. f.SetCellStyle(sheetName, budgetAmountCell, budgetAmountCell, alignCenterStyle)
  515. // 实际金额汇总
  516. realAmountCell := fmt.Sprintf("%s%d", "J", row)
  517. realAmountStr := ""
  518. if realAmount > 0 {
  519. realAmountStr = fmt.Sprintf("%.3f", realAmount)
  520. }
  521. f.SetCellValue(sheetName, realAmountCell, realAmountStr)
  522. f.SetCellStyle(sheetName, realAmountCell, realAmountCell, alignCenterStyle)
  523. f.SetRowHeight(sheetName, row, 21)
  524. c.Header("Content-Type", "application/octet-stream")
  525. c.Header("Content-Disposition", "attachment; filename="+"reportProduce.xlsx")
  526. c.Header("Content-Transfer-Encoding", "binary")
  527. err = f.Write(c.Writer)
  528. if err != nil {
  529. return nil, err
  530. }
  531. return nil, nil
  532. }