report.go 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607
  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, 1*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{"_id": 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, 1*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. List: []map[string]interface{}{},
  228. Page: page,
  229. Size: size,
  230. Total: 0,
  231. }, nil
  232. }
  233. lists := []map[string]interface{}{}
  234. for _, report := range reports {
  235. billArray := strings.Split(report, "_")
  236. billType := billArray[0]
  237. _billId := billArray[1]
  238. billId, _ := primitive.ObjectIDFromHex(_billId)
  239. billData := map[string]interface{}{}
  240. found := false
  241. if billType == "purchase" {
  242. found, billData = repo.RepoSeachDocMap(apictx.CreateRepoCtx(), &repo.DocSearchOptions{
  243. CollectName: repo.CollectionBillPurchase,
  244. Query: repo.Map{"_id": billId},
  245. })
  246. }
  247. if billType == "produce" {
  248. found, billData = repo.RepoSeachDocMap(apictx.CreateRepoCtx(), &repo.DocSearchOptions{
  249. CollectName: repo.CollectionBillProduce,
  250. Query: repo.Map{"_id": billId},
  251. })
  252. }
  253. if billType == "product" {
  254. found, billData = repo.RepoSeachDocMap(apictx.CreateRepoCtx(), &repo.DocSearchOptions{
  255. CollectName: repo.CollectionBillProduct,
  256. Query: repo.Map{"_id": billId},
  257. })
  258. }
  259. if found {
  260. billData["billType"] = billType
  261. lists = append(lists, billData)
  262. }
  263. }
  264. return repo.PageResult{
  265. List: lists,
  266. Total: int64(total),
  267. Page: page,
  268. Size: size,
  269. }, nil
  270. }
  271. func CreatePageRange(page, size int64) (int64, int64) {
  272. if page < 1 {
  273. page = 1
  274. }
  275. if size < 1 {
  276. size = 10
  277. }
  278. start := (page - 1) * size
  279. stop := page*size - 1
  280. return start, stop
  281. }
  282. func ReportProduceList(c *gin.Context, apictx *ApiSession) (interface{}, error) {
  283. page, size, query := UtilQueryPageSize(c)
  284. // 条件处理
  285. // 获取采购单符合条件的信息
  286. return repo.RepoPageSearch(apictx.CreateRepoCtx(), &repo.PageSearchOptions{
  287. CollectName: repo.CollectionBillProduce,
  288. Query: handleReportQuery(query),
  289. Page: page,
  290. Size: size,
  291. })
  292. }
  293. // 采购单
  294. func ReportPurchaseList(c *gin.Context, apictx *ApiSession) (interface{}, error) {
  295. page, size, query := UtilQueryPageSize(c)
  296. return repo.RepoPageSearch(apictx.CreateRepoCtx(), &repo.PageSearchOptions{
  297. CollectName: repo.CollectionBillPurchase,
  298. Query: handleReportQuery(query),
  299. Page: page,
  300. Size: size,
  301. })
  302. }
  303. func ReportProductList(c *gin.Context, apictx *ApiSession) (interface{}, error) {
  304. page, size, query := UtilQueryPageSize(c)
  305. return repo.RepoPageSearch(apictx.CreateRepoCtx(), &repo.PageSearchOptions{
  306. CollectName: repo.CollectionBillProduct,
  307. Query: handleReportQuery(query),
  308. Page: page,
  309. Size: size,
  310. })
  311. }
  312. func ReportProduceDownload(c *gin.Context, apictx *ApiSession) (interface{}, error) {
  313. _, _, query := UtilQueryPageSize(c)
  314. // 获取采符合条件的信息
  315. produces := []*model.ProduceBill{}
  316. err := repo.RepoDocsSearch(apictx.CreateRepoCtx(), &repo.PageSearchOptions{
  317. CollectName: repo.CollectionBillProduce,
  318. Query: handleReportQuery(query),
  319. }, &produces)
  320. if err != nil || len(produces) < 1 {
  321. return nil, errors.New("数据不存在")
  322. }
  323. f := excelize.NewFile()
  324. index := f.NewSheet("Sheet1")
  325. sheetName := f.GetSheetName(index)
  326. f.SetActiveSheet(index)
  327. f.SetDefaultFont("宋体")
  328. border := []excelize.Border{
  329. {Type: "top", Style: 1, Color: "000000"},
  330. {Type: "left", Style: 1, Color: "000000"},
  331. {Type: "right", Style: 1, Color: "000000"},
  332. {Type: "bottom", Style: 1, Color: "000000"},
  333. }
  334. alignCenterStyle, _ := f.NewStyle(&excelize.Style{
  335. Alignment: &excelize.Alignment{Horizontal: "center", Vertical: "center"},
  336. Border: border,
  337. })
  338. companyName := getCompanyName(apictx)
  339. var budgetAmount float64 = 0
  340. var realAmount float64 = 0
  341. var row int = 0
  342. for _, produce := range produces {
  343. produceExcel := NewReportProduceExcel(f)
  344. produceExcel.Row = row
  345. produceExcel.Content = produce
  346. produceExcel.Title = fmt.Sprintf("%s加工单", companyName)
  347. //设置对应的数据
  348. produceExcel.Draws()
  349. budgetAmount += produceExcel.BudgetAmount
  350. realAmount += produceExcel.RealAmount
  351. row = produceExcel.Row + 3
  352. }
  353. row = row - 2
  354. startCell := fmt.Sprintf("%s%d", "A", row)
  355. endCell := fmt.Sprintf("%s%d", "H", row)
  356. f.MergeCell(sheetName, startCell, endCell)
  357. f.SetCellStyle(sheetName, startCell, endCell, alignCenterStyle)
  358. f.SetCellValue(sheetName, startCell, "汇总金额")
  359. // 预算金额汇总
  360. budgetAmountCell := fmt.Sprintf("%s%d", "I", row)
  361. budgetAmountStr := ""
  362. if budgetAmount > 0 {
  363. budgetAmountStr = fmt.Sprintf("%.3f", budgetAmount)
  364. }
  365. f.SetCellValue(sheetName, budgetAmountCell, budgetAmountStr)
  366. f.SetCellStyle(sheetName, budgetAmountCell, budgetAmountCell, alignCenterStyle)
  367. // 实际金额汇总
  368. realAmountCell := fmt.Sprintf("%s%d", "J", row)
  369. realAmountStr := ""
  370. if realAmount > 0 {
  371. realAmountStr = fmt.Sprintf("%.3f", realAmount)
  372. }
  373. f.SetCellValue(sheetName, realAmountCell, realAmountStr)
  374. f.SetCellStyle(sheetName, realAmountCell, realAmountCell, alignCenterStyle)
  375. f.SetRowHeight(sheetName, row, 21)
  376. c.Header("Content-Type", "application/octet-stream")
  377. c.Header("Content-Disposition", "attachment; filename="+"reportProduce.xlsx")
  378. c.Header("Content-Transfer-Encoding", "binary")
  379. err = f.Write(c.Writer)
  380. if err != nil {
  381. return nil, err
  382. }
  383. return nil, nil
  384. }
  385. func ReportPurchaseDownload(c *gin.Context, apictx *ApiSession) (interface{}, error) {
  386. _, _, query := UtilQueryPageSize(c)
  387. purchases := []model.PurchaseBill{}
  388. err := repo.RepoDocsSearch(apictx.CreateRepoCtx(), &repo.PageSearchOptions{
  389. CollectName: repo.CollectionBillPurchase,
  390. Query: handleReportQuery(query),
  391. }, &purchases)
  392. if err != nil || len(purchases) < 1 {
  393. return nil, errors.New("数据不存在")
  394. }
  395. f := excelize.NewFile()
  396. index := f.NewSheet("Sheet1")
  397. sheetName := f.GetSheetName(index)
  398. f.SetActiveSheet(index)
  399. f.SetDefaultFont("宋体")
  400. border := []excelize.Border{
  401. {Type: "top", Style: 1, Color: "000000"},
  402. {Type: "left", Style: 1, Color: "000000"},
  403. {Type: "right", Style: 1, Color: "000000"},
  404. {Type: "bottom", Style: 1, Color: "000000"},
  405. }
  406. alignCenterStyle, _ := f.NewStyle(&excelize.Style{
  407. Alignment: &excelize.Alignment{Horizontal: "center", Vertical: "center"},
  408. Border: border,
  409. })
  410. companyName := getCompanyName(apictx)
  411. var budgetCount float64 = 0
  412. var realCount float64 = 0
  413. var row int = 0
  414. for _, purchase := range purchases {
  415. var reportBill *ReportPurchaseExcel
  416. if len(purchase.Paper) > 0 {
  417. reportBill = NewReportPurchaseExcel(f)
  418. }
  419. if reportBill == nil {
  420. return nil, errors.New("数据不存在")
  421. }
  422. reportBill.Row = row
  423. reportBill.Content = &purchase
  424. reportBill.Title = fmt.Sprintf("%s原材料采购单", companyName)
  425. reportBill.Draws()
  426. budgetCount += reportBill.BudgetAmount
  427. realCount += reportBill.RealAmount
  428. row = reportBill.Row + 3
  429. }
  430. row = row - 2
  431. startCell := fmt.Sprintf("%s%d", "A", row)
  432. endCell := fmt.Sprintf("%s%d", "H", row)
  433. f.MergeCell(sheetName, startCell, endCell)
  434. f.SetCellStyle(sheetName, startCell, endCell, alignCenterStyle)
  435. f.SetCellValue(sheetName, startCell, "汇总金额")
  436. // 预算金额汇总
  437. budgetCountCell := fmt.Sprintf("%s%d", "I", row)
  438. budgetCountStr := ""
  439. if realCount > 0 {
  440. budgetCountStr = fmt.Sprintf("%.3f", budgetCount)
  441. }
  442. f.SetCellValue(sheetName, budgetCountCell, budgetCountStr)
  443. f.SetCellStyle(sheetName, budgetCountCell, budgetCountCell, alignCenterStyle)
  444. // 实际金额汇总
  445. RealCountCell := fmt.Sprintf("%s%d", "J", row)
  446. realCountStr := ""
  447. if realCount > 0 {
  448. realCountStr = fmt.Sprintf("%.3f", realCount)
  449. }
  450. f.SetCellValue(sheetName, RealCountCell, realCountStr)
  451. f.SetCellStyle(sheetName, RealCountCell, RealCountCell, alignCenterStyle)
  452. f.SetRowHeight(sheetName, row, 21)
  453. c.Header("Content-Type", "application/octet-stream")
  454. c.Header("Content-Disposition", "attachment; filename="+"reportPurchase.xlsx")
  455. c.Header("Content-Transfer-Encoding", "binary")
  456. err = f.Write(c.Writer)
  457. if err != nil {
  458. return nil, err
  459. }
  460. return nil, nil
  461. }
  462. func ReportProductDownload(c *gin.Context, apictx *ApiSession) (interface{}, error) {
  463. _, _, query := UtilQueryPageSize(c)
  464. // 获取采符合条件的信息
  465. products := []*model.ProductBill{}
  466. err := repo.RepoDocsSearch(apictx.CreateRepoCtx(), &repo.PageSearchOptions{
  467. CollectName: repo.CollectionBillProduct,
  468. Query: handleReportQuery(query),
  469. }, &products)
  470. if err != nil || len(products) < 1 {
  471. return nil, errors.New("数据不存在")
  472. }
  473. f := excelize.NewFile()
  474. index := f.NewSheet("Sheet1")
  475. sheetName := f.GetSheetName(index)
  476. f.SetActiveSheet(index)
  477. f.SetDefaultFont("宋体")
  478. border := []excelize.Border{
  479. {Type: "top", Style: 1, Color: "000000"},
  480. {Type: "left", Style: 1, Color: "000000"},
  481. {Type: "right", Style: 1, Color: "000000"},
  482. {Type: "bottom", Style: 1, Color: "000000"},
  483. }
  484. alignCenterStyle, _ := f.NewStyle(&excelize.Style{
  485. Alignment: &excelize.Alignment{Horizontal: "center", Vertical: "center"},
  486. Border: border,
  487. })
  488. companyName := getCompanyName(apictx)
  489. var budgetAmount float64 = 0
  490. var realAmount float64 = 0
  491. var row int = 0
  492. for _, product := range products {
  493. productExcel := NewReportProductBill(f)
  494. productExcel.Row = row
  495. productExcel.Content = product
  496. productExcel.Title = companyName
  497. productExcel.Draws()
  498. budgetAmount += productExcel.BudgetAmount
  499. realAmount += productExcel.RealAmount
  500. row = productExcel.Row + 3
  501. }
  502. row = row - 2
  503. startCell := fmt.Sprintf("%s%d", "A", row)
  504. endCell := fmt.Sprintf("%s%d", "H", row)
  505. f.MergeCell(sheetName, startCell, endCell)
  506. f.SetCellStyle(sheetName, startCell, endCell, alignCenterStyle)
  507. f.SetCellValue(sheetName, startCell, "汇总金额")
  508. // 预算金额汇总
  509. budgetAmountCell := fmt.Sprintf("%s%d", "I", row)
  510. budgetCountStr := ""
  511. if realAmount > 0 {
  512. budgetCountStr = fmt.Sprintf("%.3f", realAmount)
  513. }
  514. f.SetCellValue(sheetName, budgetAmountCell, budgetCountStr)
  515. f.SetCellStyle(sheetName, budgetAmountCell, budgetAmountCell, alignCenterStyle)
  516. // 实际金额汇总
  517. realAmountCell := fmt.Sprintf("%s%d", "J", row)
  518. realAmountStr := ""
  519. if realAmount > 0 {
  520. realAmountStr = fmt.Sprintf("%.3f", realAmount)
  521. }
  522. f.SetCellValue(sheetName, realAmountCell, realAmountStr)
  523. f.SetCellStyle(sheetName, realAmountCell, realAmountCell, alignCenterStyle)
  524. f.SetRowHeight(sheetName, row, 21)
  525. c.Header("Content-Type", "application/octet-stream")
  526. c.Header("Content-Disposition", "attachment; filename="+"reportProduce.xlsx")
  527. c.Header("Content-Transfer-Encoding", "binary")
  528. err = f.Write(c.Writer)
  529. if err != nil {
  530. return nil, err
  531. }
  532. return nil, nil
  533. }