report-process-excel.go 8.6 KB

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