report-product-excel.go 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278
  1. package api
  2. import (
  3. "box-cost/db/model"
  4. "fmt"
  5. "regexp"
  6. _ "image/gif"
  7. _ "image/jpeg"
  8. _ "image/png"
  9. "github.com/xuri/excelize/v2"
  10. )
  11. type ReportProductExcel struct {
  12. Offset int
  13. Row int
  14. Title string //标题
  15. Excel *excelize.File
  16. SheetName string
  17. AlignCenterStyle int
  18. Content *model.ProductBill
  19. BudgetCount float64
  20. RealCount float64
  21. }
  22. func (b *ReportProductExcel) drawTitle() error {
  23. marginLeft := excelize.PageMarginLeft(0.3)
  24. b.Excel.SetPageMargins(b.SheetName, marginLeft)
  25. // tileIndex := b.Offset + 1
  26. b.Row++
  27. startCell := fmt.Sprintf("A%d", b.Row)
  28. err := b.Excel.MergeCell(b.SheetName, startCell, fmt.Sprintf("J%d", b.Row))
  29. if err != nil {
  30. return err
  31. }
  32. style, err := b.Excel.NewStyle(&excelize.Style{
  33. Alignment: &excelize.Alignment{Horizontal: "center", Vertical: "center"},
  34. Font: &excelize.Font{Bold: true, Size: 18}})
  35. if err != nil {
  36. return err
  37. }
  38. err = b.Excel.SetCellStyle(b.SheetName, startCell, startCell, style)
  39. if err != nil {
  40. return err
  41. }
  42. b.Excel.SetRowHeight(b.SheetName, b.Row, 23)
  43. b.Excel.SetCellValue(b.SheetName, startCell, b.Title)
  44. return nil
  45. }
  46. func (b *ReportProductExcel) drawSubTitles() error {
  47. // row := b.Offset + 2
  48. b.Row++
  49. styleLeft, err := b.Excel.NewStyle(&excelize.Style{
  50. Alignment: &excelize.Alignment{Horizontal: "left", Vertical: "center"},
  51. Font: &excelize.Font{Size: 11}})
  52. if err != nil {
  53. return err
  54. }
  55. styleRight, err := b.Excel.NewStyle(&excelize.Style{
  56. Alignment: &excelize.Alignment{Horizontal: "right", Vertical: "center"},
  57. Font: &excelize.Font{Size: 11}})
  58. if err != nil {
  59. return err
  60. }
  61. var drawLeft = func(rowIndex int, value string) error {
  62. //左边1
  63. left1Cell := fmt.Sprintf("A%d", rowIndex)
  64. err = b.Excel.MergeCell(b.SheetName, left1Cell, fmt.Sprintf("E%d", rowIndex))
  65. if err != nil {
  66. return err
  67. }
  68. err = b.Excel.SetCellStyle(b.SheetName, left1Cell, left1Cell, styleLeft)
  69. if err != nil {
  70. return err
  71. }
  72. b.Excel.SetCellValue(b.SheetName, left1Cell, value)
  73. return nil
  74. }
  75. var drawRight = func(rowIndex int, value string) error {
  76. right1Cell := fmt.Sprintf("F%d", rowIndex)
  77. err = b.Excel.MergeCell(b.SheetName, right1Cell, fmt.Sprintf("J%d", rowIndex))
  78. if err != nil {
  79. return err
  80. }
  81. err = b.Excel.SetCellStyle(b.SheetName, right1Cell, right1Cell, styleRight)
  82. if err != nil {
  83. return err
  84. }
  85. b.Excel.SetCellValue(b.SheetName, right1Cell, value)
  86. return nil
  87. }
  88. //第一行
  89. drawLeft(b.Row, "类别:"+b.Content.Type)
  90. drawRight(b.Row, "单号:"+b.Content.SerialNumber)
  91. b.Excel.SetRowHeight(b.SheetName, b.Row, 21)
  92. b.Row++
  93. //第二行
  94. drawLeft(b.Row, "供应商名称:"+b.Content.Supplier)
  95. timeformat := b.Content.CreateTime.Local().Format("2006年01月02号 15:04:05")
  96. drawRight(b.Row, "下单时间:"+timeformat)
  97. b.Excel.SetRowHeight(b.SheetName, b.Row, 21)
  98. b.Row++
  99. //第三行
  100. drawLeft(b.Row, "产品名称:"+b.Content.ProductName)
  101. status := ""
  102. if b.Content.Status == "complete" {
  103. status = fmt.Sprintf("已完成(%d)", b.Content.ConfirmCount)
  104. }
  105. if b.Content.Status == "created" {
  106. status = "进行中"
  107. }
  108. drawRight(b.Row, "状态:"+status)
  109. b.Excel.SetRowHeight(b.SheetName, b.Row, 21)
  110. return nil
  111. }
  112. func (b *ReportProductExcel) drawTableTitle() error {
  113. // row := b.Offset + 5
  114. b.Row++
  115. // 品名 规格 数量 单位 单价 金额
  116. var drawCol = func(prefix string, value string) error {
  117. left1Cell := fmt.Sprintf("%s%d", prefix, b.Row)
  118. left2Cell := fmt.Sprintf("%s%d", prefix, b.Row+1)
  119. err := b.Excel.MergeCell(b.SheetName, left1Cell, left2Cell)
  120. if err != nil {
  121. return err
  122. }
  123. err = b.Excel.SetCellStyle(b.SheetName, left1Cell, left2Cell, b.AlignCenterStyle)
  124. if err != nil {
  125. return err
  126. }
  127. return b.Excel.SetCellValue(b.SheetName, left1Cell, value)
  128. }
  129. // a采购项目 b规格 c下单数量 d单位 e完成数量 f单价 g预算金额 h实际金额 i交货时间 j备注
  130. drawCol("A", "采购项目")
  131. drawCol("B", "规格")
  132. drawCol("C", "下单数量")
  133. drawCol("D", "单位")
  134. drawCol("E", "完成数量")
  135. drawCol("F", "单价")
  136. drawCol("G", "预算金额")
  137. drawCol("H", "实际金额")
  138. drawCol("I", "交货时间")
  139. drawCol("J", "备注")
  140. return nil
  141. }
  142. func (b *ReportProductExcel) drawTableContent() error {
  143. // row := b.Offset + 7
  144. // b.Row = row
  145. b.Row += 2
  146. var DrawRow = func(rowIndex int, values ...string) {
  147. charas := []string{"A", "B", "C", "D", "E", "F", "G", "H", "I", "J"}
  148. for i, c := range charas {
  149. v := ""
  150. if i < len(values) {
  151. v = values[i]
  152. }
  153. b.Excel.SetCellValue(b.SheetName, fmt.Sprintf("%s%d", c, rowIndex), v)
  154. val2Cel := fmt.Sprintf("%s%d", c, rowIndex)
  155. b.Excel.SetCellStyle(b.SheetName, val2Cel, val2Cel, b.AlignCenterStyle)
  156. b.Excel.SetRowHeight(b.SheetName, rowIndex, 21)
  157. }
  158. }
  159. products := b.Content.Products
  160. if len(products) > 0 {
  161. for _, product := range products {
  162. deliveryTime := product.DeliveryTime.Local().Format("2006-01-02")
  163. realCount := "-"
  164. realPrice := "-"
  165. // 预算金额
  166. orderPrice := fmt.Sprintf("%.3f", float64(product.OrderCount)*product.Price)
  167. b.FormatToEmpty(&orderPrice)
  168. // 实际完成数
  169. realCount = fmt.Sprintf("%d", product.ConfirmCount)
  170. b.FormatToEmpty(&realCount)
  171. // 实际金额
  172. realPrice = fmt.Sprintf("%.3f", float64(product.ConfirmCount)*product.Price)
  173. b.FormatToEmpty(&realPrice)
  174. // a采购项目 b规格 c下单数量 d单位 e完成数量 f单价 g预算金额 h实际金额 i交货时间 j备注
  175. orderCount := fmt.Sprintf("%d", product.OrderCount)
  176. price := fmt.Sprintf("%.3f", product.Price)
  177. b.FormatToEmpty(&price)
  178. DrawRow(b.Row, product.Name, product.Norm, orderCount, product.Unit, realCount, price, orderPrice, realPrice, deliveryTime, product.Remark)
  179. b.Row++
  180. b.BudgetCount += float64(product.OrderCount) * product.Price
  181. b.RealCount += float64(product.ConfirmCount) * product.Price
  182. }
  183. }
  184. return nil
  185. }
  186. func (b *ReportProductExcel) drawRemark() error {
  187. // 填备注
  188. b.Row++
  189. remarkTitleCell := fmt.Sprintf("A%d", b.Row)
  190. b.Excel.SetCellValue(b.SheetName, remarkTitleCell, "备注:")
  191. b.Row++
  192. remarkContentScell := fmt.Sprintf("A%d", b.Row)
  193. // 预留五行备注内容
  194. reg := regexp.MustCompile(`\n`)
  195. remarkRowNum := len(reg.FindAllString(b.Content.Remark, -1)) + 1
  196. b.Row += remarkRowNum
  197. remarkContentEcell := fmt.Sprintf("J%d", b.Row)
  198. b.Excel.MergeCell(b.SheetName, remarkContentScell, remarkContentEcell)
  199. b.Excel.SetCellValue(b.SheetName, remarkContentScell, b.Content.Remark)
  200. return nil
  201. }
  202. func (b *ReportProductExcel) Draws() {
  203. b.drawTitle()
  204. b.drawSubTitles()
  205. b.drawTableTitle()
  206. b.drawTableContent()
  207. b.drawRemark()
  208. }
  209. func NewReportProductBill(f *excelize.File) *ReportProductExcel {
  210. border := []excelize.Border{
  211. {Type: "top", Style: 1, Color: "000000"},
  212. {Type: "left", Style: 1, Color: "000000"},
  213. {Type: "right", Style: 1, Color: "000000"},
  214. {Type: "bottom", Style: 1, Color: "000000"},
  215. }
  216. styleLeft, _ := f.NewStyle(&excelize.Style{
  217. Alignment: &excelize.Alignment{Horizontal: "center", Vertical: "center"},
  218. Border: border,
  219. Font: &excelize.Font{Size: 10},
  220. })
  221. b := &ReportProductExcel{
  222. Title: "原材料采购单",
  223. SheetName: "Sheet1",
  224. Excel: f,
  225. Offset: 0,
  226. AlignCenterStyle: styleLeft,
  227. }
  228. f.SetColWidth(b.SheetName, "A", "J", 11.5)
  229. f.SetPageMargins(b.SheetName, excelize.PageMarginTop(0), excelize.PageMarginLeft(0), excelize.PageMarginRight(0))
  230. return b
  231. }
  232. func (b *ReportProductExcel) FormatToEmpty(str *string) {
  233. if *str == "0" || *str == "0.000" {
  234. *str = ""
  235. }
  236. }