reports.go 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976
  1. package controllers
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. "math"
  6. "strings"
  7. "time"
  8. "dashoo.cn/base_common/labsop"
  9. "dashoo.cn/base_common/utils"
  10. "dashoo.cn/mcs_api/business/company"
  11. "dashoo.cn/mcs_api/business/device"
  12. "dashoo.cn/mcs_common/business/equipment"
  13. "github.com/signintech/gopdf"
  14. "github.com/tealeg/xlsx"
  15. )
  16. type ReportsController struct {
  17. BaseController
  18. }
  19. const (
  20. ReportDefaultTimearea = "1h"
  21. ReportDefaultTimearr = "0,4,8,12,16,20"
  22. )
  23. type Reportinfo struct {
  24. Name string
  25. DataItem int
  26. DataT []string
  27. DataH []string
  28. DataO2 []string
  29. DataCO2 []string
  30. DataDoorlock []string
  31. DataDisplacement []string
  32. DataWindspeed []string
  33. DataPressure []string
  34. DataClO2 []string
  35. DataC2H4 []string
  36. DataC2H2 []string
  37. DataCl2 []string
  38. DataO3 []string
  39. DataTVOC []string
  40. DataH2O []string
  41. DataSO2 []string
  42. Datapower []string //功率
  43. Datasupply []string //电量
  44. DataLiquidLevel []string //液位
  45. }
  46. type TriggerHourData struct {
  47. ChannelCode string `json:"ccode"`
  48. EventFiled string `json:"eventfiled"`
  49. Value float32 `json:"value"`
  50. ReportData string `json:"reportdata"`
  51. ReportHour int `json:"reporthour"`
  52. }
  53. type TriggerHourDataRequest struct {
  54. CurrentItemCount int64 `json:"currentItemCount,omitempty"` //结果集中的条目数目
  55. ItemsPerPage int64 `json:"itemsPerPage,omitempty"` //每页记录数目
  56. PageIndex int64 `json:"pageIndex,omitempty"` //条目的当前页索引
  57. Items []TriggerHourData `json:"items"` //数据列表
  58. }
  59. type ShowColsModel struct {
  60. ColsName string `json:"colsname"`
  61. }
  62. // @Title 日报报表列表
  63. // @Description 日报报表列表
  64. // @Success 200 {object} DataInfo
  65. // @router /list [get]
  66. func (this *ReportsController) List() {
  67. page := this.GetPageInfoForm()
  68. var showcols []string
  69. var timearea string
  70. //分页
  71. svc := device.GetDeviceService(utils.DBE)
  72. // svccompany := company.GetCompanyService(utils.DBE)
  73. // companyname := svccompany.GetFullnameByAccode(this.GetAccode())
  74. u, p := this.GetuAndp()
  75. client := labsop.GetLabSopClient(this.GetupdbAndHost())
  76. fmt.Println(this.GetupdbAndHost())
  77. timerq, _ := this.GetInt64("timerq")
  78. cols := this.GetString("cols")
  79. timestr := time.Unix(timerq/1000, 0).Format("2006-01-02")
  80. t1, _ := utils.TimeParse(timestr+" 23:59:59", "2006-1-2 15:4:5")
  81. t2, _ := utils.TimeParse(timestr+" 00:00:00", "2006-1-2 15:4:5")
  82. end := t1.Unix()
  83. begin := t2.Unix()
  84. var reports = make([]Reportinfo, 0)
  85. svceq := equipment.GetEquipmentService(utils.DBE)
  86. eids := svceq.GetEquipmentidsByUid(this.User.Id)
  87. Uid := this.User.Id
  88. where := " (a.CreateUserId=" + utils.ToStr(this.User.Id) + " or a.EquipMentId in (" + eids + ")) and a.DataItem in (" + ChannelItem_Report + ") "
  89. total, channel := svc.GetChannelsList(page.CurrentPage, page.Size, where, Uid)
  90. fmt.Println("--------channel---------", channel)
  91. if cols == "" {
  92. timearea = ReportDefaultTimearea
  93. showcols = strings.Split(ReportDefaultTimearr, ",")
  94. // showxlscols = strings.Split(strings.Replace(ReportDefaultTimearr, ",", ":00,", -1)+":00", ",")
  95. } else {
  96. timearea = "1h"
  97. showcolsstr := cols
  98. showcols = strings.Split(showcolsstr, ",")
  99. // showxlscols = strings.Split(strings.Replace(showcolsstr, ",", ":00,", -1)+":00", ",")
  100. }
  101. //报警数据
  102. apiurl := utils.Cfg.MustValue("server", "apiurl") + "/triggerhistorys/hourdata/?u=" + u + "&p=" + p + "&source=coldchain&account=" + this.GetAccode() + "&start=" + utils.ToStr(begin) + "&end=" + utils.ToStr(end)
  103. //取报警数据
  104. var datalist TriggerHourDataRequest
  105. strUrl := apiurl + "&ccode=" + svc.GetCIds(where)
  106. json.Unmarshal(Apiget(strUrl), &datalist)
  107. trihourmap := make(map[string][]TriggerHourData)
  108. for _, v := range datalist.Items {
  109. trihourmap[v.ChannelCode] = append(trihourmap[v.ChannelCode], v)
  110. }
  111. for _, v := range channel {
  112. data := new(labsop.DatapointLabSop)
  113. queryCommand := fmt.Sprintf("select MEDIAN(temperature) as temperature,MEDIAN(humidity) as humidity,MEDIAN(voltage) as voltage,MEDIAN(rssi) as rssi,MEDIAN(o2) as o2,MEDIAN(co2) as co2,MEDIAN(h2o) as h2o,MEDIAN(so2) as so2,MEDIAN(windspeed) as windspeed ,MEDIAN(pressure) as pressure,MEDIAN(clo2) as clo2,MEDIAN(tvoc) as tvoc,MEDIAN(c2h4) as c2h4,MEDIAN(c2h2) as c2h2,MEDIAN(doorlock) as doorlock,MEDIAN(cl2) as cl2,MEDIAN(o3) as o3 from %v where time > %vs and time < %vs group by time(%v) fill(none)", v.Code, begin, end, timearea)
  114. if DeviceItemContainint(ChannelItem_Power, v.DataItem) {
  115. queryCommand = fmt.Sprintf("select MEDIAN(temperature) as temperature,MEDIAN(humidity) as humidity,MEDIAN(voltage) as voltage,MEDIAN(rssi) as rssi,MEDIAN(o2) as o2,MEDIAN(co2) as co2,MEDIAN(h2o) as h2o,MEDIAN(so2) as so2,MEDIAN(windspeed) as windspeed ,MEDIAN(pressure) as pressure,MEDIAN(clo2) as clo2,MEDIAN(c2h2) as c2h2,MEDIAN(tvoc) as tvoc,MEDIAN(c2h4) as c2h4,MEDIAN(cl2) as cl2,MEDIAN(doorlock) as doorlock,MEDIAN(o3) as o3 ,MEDIAN(electricalsupply) as electricalsupply,MEDIAN(electricalpower) as electricalpower from %v where time > %vs and time < %vs group by time(%v) fill(none)", v.Code, begin, end, timearea)
  116. }
  117. result := client.QueryLabSop(queryCommand, data)
  118. fmt.Println("&&&result:", result)
  119. titlename := v.Title
  120. if v.DeviceState == 2 || v.DeviceState == 3 || v.DeviceState == 4 {
  121. statename := ""
  122. if v.DeviceState == 2 {
  123. statename = "维修"
  124. } else if v.DeviceState == 3 {
  125. statename = "停用"
  126. } else {
  127. statename = "除霜"
  128. }
  129. titlename = titlename + " (" + statename + ")"
  130. }
  131. reportdata := GetReportData(titlename, v.DataItem, showcols, result, trihourmap[v.Code])
  132. reports = append(reports, reportdata)
  133. }
  134. var datainfo DataInfo
  135. datainfo.Items = reports
  136. datainfo.CurrentItemCount = total
  137. this.Data["json"] = &datainfo
  138. this.ServeJSON()
  139. }
  140. func GetReportData(name string, dataitem int, showcols []string, data []labsop.DatapointLabSop, hourdata []TriggerHourData) Reportinfo {
  141. datat := make([]string, 0)
  142. datah := make([]string, 0)
  143. datao2 := make([]string, 0)
  144. dataco2 := make([]string, 0)
  145. dataots := make([]string, 0)
  146. datadisplacement := make([]string, 0)
  147. datah2o := make([]string, 0)
  148. dataso2 := make([]string, 0)
  149. datawindspeed := make([]string, 0)
  150. datapressure := make([]string, 0)
  151. dataclo2 := make([]string, 0)
  152. datac2h4 := make([]string, 0)
  153. datac2h2 := make([]string, 0)
  154. datacl2 := make([]string, 0)
  155. datatvoc := make([]string, 0)
  156. datao3 := make([]string, 0)
  157. datapower := make([]string, 0)
  158. datasupply := make([]string, 0)
  159. dataliquidlevel := make([]string, 0)
  160. if DeviceItemContainint(ChannelItem_HaveT, dataitem) {
  161. datat = append(datat, "温度(℃)")
  162. }
  163. if DeviceItemContainint(ChannelItem_HaveH, dataitem) {
  164. datah = append(datah, "湿度(RH%)")
  165. }
  166. if DeviceItemContainint(ChannelItem_HaveO2, dataitem) {
  167. datao2 = append(datao2, "氧气(%)")
  168. }
  169. if DeviceItemContainint(ChannelItem_Co2, dataitem) {
  170. dataco2 = append(dataco2, "二氧化碳(%)")
  171. }
  172. if DeviceItemContainint(ChannelItem_H2O, dataitem) {
  173. datah2o = append(datah2o, "电导率(us/cm)")
  174. }
  175. if DeviceItemContainint(ChannelItem_SO2, dataitem) {
  176. dataso2 = append(dataso2, "二氧化硫(ppm)")
  177. }
  178. if DeviceItemContainint(ChannelItem_WindSpeed, dataitem) {
  179. datawindspeed = append(datawindspeed, "风速(m/s)")
  180. }
  181. if DeviceItemContainint(ChannelItem_Pressure, dataitem) {
  182. datapressure = append(datapressure, "气压(hpa)")
  183. }
  184. if DeviceItemContainint(ChannelItem_ClO2, dataitem) {
  185. dataclo2 = append(dataclo2, "二氧化氯(PPM)")
  186. }
  187. if DeviceItemContainint(ChannelItem_C2H4, dataitem) {
  188. datac2h4 = append(datac2h4, "乙烯(PPM)")
  189. }
  190. if DeviceItemContainint(ChannelItem_C2H2, dataitem) {
  191. datac2h2 = append(datac2h2, "乙炔(PPM)")
  192. }
  193. if DeviceItemContainint(ChannelItem_Cl2, dataitem) {
  194. datacl2 = append(datacl2, "氯气(PPM)")
  195. }
  196. if DeviceItemContainint(ChannelItem_O3, dataitem) {
  197. datao3 = append(datao3, "臭氧(PPM)")
  198. }
  199. if DeviceItemContainint(ChannelItem_Power, dataitem) {
  200. datapower = append(datapower, "功率(W)")
  201. datasupply = append(datasupply, "电量(V)")
  202. }
  203. if DeviceItemContainint(ChannelItem_HaveLiquidLevel, dataitem) {
  204. dataliquidlevel = append(dataliquidlevel, "液位(mm)")
  205. }
  206. if DeviceItemContainint(ChannelItem_TVOC, dataitem) {
  207. datatvoc = append(datatvoc, "TVOC(ppb)")
  208. }
  209. if DeviceItemContainint(ChannelItem_MicroPressure, dataitem) {
  210. datapressure = append(dataots, "微压差(Pa)")
  211. }
  212. for i, n := 0, len(data); i < 24; i++ {
  213. if utils.SliceContains(showcols, utils.ToStr(i)) {
  214. t, h, o2, co2, doorlock, displacement, h2o, so2, windspeed, pressure, clo2, c2h4, c2h2, cl2, tvoc, o3, power, supply, liquidlevel := "----", "----", "----", "----", "----", "----", "----", "----", "----", "----", "----", "----", "----", "----", "----", "----", "----", "----", "----"
  215. for m := 0; m < n; m++ {
  216. if data[m].Time.Hour() == i {
  217. t = Get2point(data[m].Temperature)
  218. if data[m].DeviceState == 2 {
  219. t = t + " (维修)"
  220. } else if data[m].DeviceState == 3 {
  221. t = t + " (停用)"
  222. } else if data[m].DeviceState == 4 {
  223. t = t + " (除霜)"
  224. }
  225. h = Get2point(data[m].Humidity)
  226. o2 = Get2point(data[m].O2)
  227. co2 = Get2point(data[m].Co2)
  228. h2o = Get2point(data[m].H2O)
  229. so2 = Get2point(data[m].SO2)
  230. windspeed = Get2point(data[m].WindSpeed)
  231. pressure = Get2point(data[m].Pressure)
  232. clo2 = Get2point(data[m].ClO2)
  233. c2h4 = Get2point(data[m].C2H4)
  234. c2h2 = Get2point(data[m].C2H2)
  235. cl2 = Get2point(data[m].Cl2)
  236. o3 = Get2point(data[m].O3)
  237. doorlock = Get2point(data[m].Doorlock)
  238. displacement = Get2point(data[m].Displacement)
  239. tvoc = Get2point(data[m].TVOC)
  240. power = utils.ToStr(data[m].ElectricalPower)
  241. supply = utils.ToStr(data[m].ElectricalSupply)
  242. liquidlevel = utils.ToStr(data[m].LiquidLevel)
  243. //在报警数据后加符号 *
  244. for x, y := 0, len(hourdata); x < y; x++ {
  245. if hourdata[x].ReportHour == i {
  246. switch hourdata[x].EventFiled {
  247. case "temperature":
  248. t = utils.ToStr(hourdata[x].Value) + " *"
  249. case "humidity":
  250. h = utils.ToStr(hourdata[x].Value) + " *"
  251. case "o2":
  252. o2 = utils.ToStr(hourdata[x].Value) + " *"
  253. case "co2":
  254. co2 = utils.ToStr(hourdata[x].Value) + " *"
  255. case "h2o":
  256. h2o = utils.ToStr(hourdata[x].Value) + " *"
  257. case "so2":
  258. so2 = utils.ToStr(hourdata[x].Value) + " *"
  259. case "windspeed":
  260. windspeed = utils.ToStr(hourdata[x].Value) + " *"
  261. case "pressure":
  262. pressure = utils.ToStr(hourdata[x].Value) + " *"
  263. case "clo2":
  264. clo2 = utils.ToStr(hourdata[x].Value) + " *"
  265. case "c2h4":
  266. c2h4 = utils.ToStr(hourdata[x].Value) + " *"
  267. case "c2h2":
  268. c2h2 = utils.ToStr(hourdata[x].Value) + " *"
  269. case "cl2":
  270. cl2 = utils.ToStr(hourdata[x].Value) + " *"
  271. case "o3":
  272. o3 = utils.ToStr(hourdata[x].Value) + " *"
  273. case "tvoc":
  274. tvoc = utils.ToStr(hourdata[x].Value) + " *"
  275. case "doorlock":
  276. doorlock = utils.ToStr(hourdata[x].Value) + " *"
  277. case "displacement":
  278. displacement = utils.ToStr(hourdata[x].Value) + " *"
  279. case "electricalsupply":
  280. supply = utils.ToStr(hourdata[x].Value) + " *"
  281. case "electricalpower":
  282. power = utils.ToStr(hourdata[x].Value) + " *"
  283. case "liquidlevel":
  284. liquidlevel = utils.ToStr(hourdata[x].Value) + " *"
  285. }
  286. break
  287. }
  288. }
  289. break
  290. }
  291. }
  292. if DeviceItemContainint(ChannelItem_HaveT, dataitem) {
  293. datat = append(datat, t)
  294. }
  295. if DeviceItemContainint(ChannelItem_HaveH, dataitem) {
  296. datah = append(datah, h)
  297. }
  298. if DeviceItemContainint(ChannelItem_HaveO2, dataitem) {
  299. datao2 = append(datao2, o2)
  300. }
  301. if DeviceItemContainint(ChannelItem_HaveCO2, dataitem) {
  302. dataco2 = append(dataco2, co2)
  303. }
  304. if DeviceItemContainint(ChannelItem_Doorlock, dataitem) {
  305. dataots = append(dataots, doorlock)
  306. }
  307. if DeviceItemContainint(ChannelItem_Displacement, dataitem) {
  308. datadisplacement = append(datadisplacement, displacement)
  309. }
  310. if DeviceItemContainint(ChannelItem_H2O, dataitem) {
  311. datah2o = append(datah2o, h2o)
  312. }
  313. if DeviceItemContainint(ChannelItem_SO2, dataitem) {
  314. dataso2 = append(dataso2, so2)
  315. }
  316. if DeviceItemContainint(ChannelItem_WindSpeed, dataitem) {
  317. datawindspeed = append(datawindspeed, windspeed)
  318. }
  319. if DeviceItemContainint(ChannelItem_Pressure, dataitem) {
  320. datapressure = append(datapressure, pressure)
  321. }
  322. if DeviceItemContainint(ChannelItem_MicroPressure, dataitem) {
  323. datapressure = append(datapressure, pressure)
  324. }
  325. if DeviceItemContainint(ChannelItem_ClO2, dataitem) {
  326. dataclo2 = append(dataclo2, clo2)
  327. }
  328. if DeviceItemContainint(ChannelItem_C2H4, dataitem) {
  329. datac2h4 = append(datac2h4, c2h4)
  330. }
  331. if DeviceItemContainint(ChannelItem_C2H2, dataitem) {
  332. datac2h2 = append(datac2h2, c2h2)
  333. }
  334. if DeviceItemContainint(ChannelItem_Cl2, dataitem) {
  335. datacl2 = append(datacl2, cl2)
  336. }
  337. if DeviceItemContainint(ChannelItem_O3, dataitem) {
  338. datao3 = append(datao3, o3)
  339. }
  340. if DeviceItemContainint(ChannelItem_TVOC, dataitem) {
  341. datatvoc = append(datatvoc, tvoc)
  342. }
  343. if DeviceItemContainint(ChannelItem_MicroPressure, dataitem) {
  344. datapressure = append(datapressure, pressure)
  345. }
  346. if DeviceItemContainint(ChannelItem_Power, dataitem) {
  347. datapower = append(datapower, power)
  348. datasupply = append(datasupply, supply)
  349. }
  350. if DeviceItemContainint(ChannelItem_HaveLiquidLevel, dataitem) {
  351. dataliquidlevel = append(dataliquidlevel, liquidlevel)
  352. }
  353. }
  354. }
  355. return Reportinfo{name, dataitem, datat, datah, datao2, dataco2, dataots, datadisplacement, datawindspeed, datapressure, dataclo2, datac2h4, datac2h2, datacl2, datao3, datatvoc, datah2o, dataso2, datapower, datasupply, dataliquidlevel}
  356. }
  357. // @Title 报表导出excel
  358. // @Description 报表导出excel
  359. // @Success 200 {object} business.device.DeviceChannels
  360. // @router /excel [get]
  361. func (this *ReportsController) GetExcel() {
  362. var showcols []string
  363. var showxlscols []string
  364. var timearea string
  365. svc := device.GetDeviceService(utils.DBE)
  366. u, p := this.GetuAndp()
  367. client := labsop.GetLabSopClient(this.GetupdbAndHost())
  368. timerq, _ := this.GetInt64("timerq")
  369. cols := this.GetString("cols")
  370. timestr := time.Unix(timerq/1000, 0).Format("2006-01-02")
  371. t1, _ := utils.TimeParse(timestr+" 23:59:59", "2006-1-2 15:4:5")
  372. t2, _ := utils.TimeParse(timestr+" 00:00:00", "2006-1-2 15:4:5")
  373. end := t1.Unix()
  374. begin := t2.Unix()
  375. var reports = make([]Reportinfo, 0)
  376. svceq := equipment.GetEquipmentService(utils.DBE)
  377. eids := svceq.GetEquipmentidsByUid(this.User.Id)
  378. Uid := this.User.Id
  379. where := " (a.CreateUserId=" + utils.ToStr(this.User.Id) + " or a.EquipMentId in (" + eids + ")) and a.DataItem in (" + ChannelItem_Report + ") "
  380. _, channel := svc.GetChannelsList(-1, 8, where, Uid)
  381. if cols == "" {
  382. timearea = ReportDefaultTimearea
  383. showcols = strings.Split(ReportDefaultTimearr, ",")
  384. showxlscols = strings.Split(strings.Replace(ReportDefaultTimearr, ",", ":00,", -1)+":00", ",")
  385. } else {
  386. timearea = "1h"
  387. showcolsstr := cols
  388. showcols = strings.Split(showcolsstr, ",")
  389. showxlscols = strings.Split(strings.Replace(showcolsstr, ",", ":00,", -1)+":00", ",")
  390. }
  391. //报警数据
  392. apiurl := utils.Cfg.MustValue("server", "apiurl") + "/triggerhistorys/hourdata/?u=" + u + "&p=" + p + "&source=coldchain&account=" + this.GetAccode() + "&start=" + utils.ToStr(begin) + "&end=" + utils.ToStr(end)
  393. //取报警数据
  394. var datalist TriggerHourDataRequest
  395. strUrl := apiurl + "&ccode=" + svc.GetCIds(where)
  396. json.Unmarshal(Apiget(strUrl), &datalist)
  397. trihourmap := make(map[string][]TriggerHourData)
  398. for _, v := range datalist.Items {
  399. trihourmap[v.ChannelCode] = append(trihourmap[v.ChannelCode], v)
  400. }
  401. for _, v := range channel {
  402. data := new(labsop.DatapointLabSop)
  403. queryCommand := fmt.Sprintf("select MEDIAN(temperature) as temperature,MEDIAN(humidity) as humidity,MEDIAN(voltage) as voltage,MEDIAN(rssi) as rssi,MEDIAN(o2) as o2,MEDIAN(co2) as co2,MEDIAN(doorlock) as doorlock,MEDIAN(doorlock) as h2o,MEDIAN(so2) as so2,MEDIAN(windspeed) as windspeed ,MEDIAN(pressure) as pressure,MEDIAN(clo2) as clo2,MEDIAN(tvoc) as tvoc,MEDIAN(c2h4) as c2h4,MEDIAN(c2h2) as c2h2,MEDIAN(cl2) as cl2,MEDIAN(o3) as o3 from %v where time > %vs and time < %vs group by time(%v) fill(none)", v.Code, begin, end, timearea)
  404. if DeviceItemContainint(ChannelItem_Power, v.DataItem) {
  405. queryCommand = fmt.Sprintf("select MEDIAN(temperature) as temperature,MEDIAN(humidity) as humidity,MEDIAN(voltage) as voltage,MEDIAN(rssi) as rssi,MEDIAN(o2) as o2,MEDIAN(co2) as co2,MEDIAN(doorlock) as doorlock, MEDIAN(h2o) as h2o,MEDIAN(so2) as so2,MEDIAN(windspeed) as windspeed ,MEDIAN(pressure) as pressure,MEDIAN(clo2) as clo2,MEDIAN(tvoc) as tvoc,MEDIAN(c2h4) as c2h4,MEDIAN(c2h2) as c2h2,MEDIAN(cl2) as cl2,MEDIAN(o3) as o3 ,MEDIAN(electricalsupply) as electricalsupply,MEDIAN(electricalpower) as electricalpower from %v where time > %vs and time < %vs group by time(%v) fill(none)", v.Code, begin, end, timearea)
  406. }
  407. result := client.QueryLabSop(queryCommand, data)
  408. titlename := v.Title
  409. if v.DeviceState == 2 || v.DeviceState == 3 || v.DeviceState == 4 {
  410. statename := ""
  411. if v.DeviceState == 2 {
  412. statename = "维修"
  413. } else if v.DeviceState == 3 {
  414. statename = "停用"
  415. } else {
  416. statename = "除霜"
  417. }
  418. titlename = titlename + " (" + statename + ")"
  419. }
  420. reportdata := GetReportData(titlename, v.DataItem, showcols, result, trihourmap[v.Code])
  421. reports = append(reports, reportdata)
  422. }
  423. xlsx.PagePrintfooterContant = "第 &P 页 值班人员签字:"
  424. svccompany := company.GetCompanyService(utils.DBE)
  425. companyname := svccompany.GetFullnameByAccode(this.GetAccode())
  426. xlsx.PagePrintheadContant = companyname + " (" + timestr + ")"
  427. f := xlsx.NewFile()
  428. DaySaveXlsx("传感器", "数据日报", this.User.Realname, timestr, showxlscols, reports, f)
  429. SaveDirectory("static/file/excel/report/" + this.GetAccode())
  430. f.Save("static/file/excel/report/" + this.GetAccode() + "/daydevicedata.xlsx")
  431. var errinfo ErrorInfo
  432. errinfo.Message = this.Ctx.Request.Host + "/static/file/excel/report/" + this.GetAccode() + "/daydevicedata.xlsx"
  433. errinfo.Code = 0
  434. this.Data["json"] = &errinfo
  435. this.ServeJSON()
  436. }
  437. func DaySaveXlsx(cell1name, name, username, time string, showcols []string, report []Reportinfo, f *xlsx.File) {
  438. sheet, _ := f.AddSheet(name)
  439. rowname := sheet.AddRow()
  440. celln := rowname.AddCell()
  441. celln.Value = "名称:" + username
  442. rowhead := sheet.AddRow()
  443. cell := rowhead.AddCell()
  444. cell.Value = cell1name
  445. cell = rowhead.AddCell()
  446. cell.Value = time
  447. rowhead.WriteSlice(&showcols, -1)
  448. for _, v := range report {
  449. if len(v.DataT) > 0 {
  450. row := sheet.AddRow()
  451. cell = row.AddCell()
  452. cell.Value = v.Name
  453. row.WriteSlice(&v.DataT, -1)
  454. }
  455. if len(v.DataH) > 0 {
  456. row := sheet.AddRow()
  457. cell = row.AddCell()
  458. cell.Value = v.Name
  459. row.WriteSlice(&v.DataH, -1)
  460. }
  461. if len(v.DataO2) > 0 {
  462. row := sheet.AddRow()
  463. cell = row.AddCell()
  464. cell.Value = v.Name
  465. row.WriteSlice(&v.DataO2, -1)
  466. }
  467. if len(v.DataCO2) > 0 {
  468. row := sheet.AddRow()
  469. cell = row.AddCell()
  470. cell.Value = v.Name
  471. row.WriteSlice(&v.DataCO2, -1)
  472. }
  473. if len(v.DataDisplacement) > 0 { //DataDisplacement
  474. row := sheet.AddRow()
  475. cell = row.AddCell()
  476. cell.Value = v.Name
  477. row.WriteSlice(&v.DataDisplacement, -1)
  478. }
  479. if len(v.DataDoorlock) > 0 {
  480. row := sheet.AddRow()
  481. cell = row.AddCell()
  482. cell.Value = v.Name
  483. row.WriteSlice(&v.DataDoorlock, -1)
  484. }
  485. if len(v.DataH2O) > 0 {
  486. row := sheet.AddRow()
  487. cell = row.AddCell()
  488. cell.Value = v.Name
  489. row.WriteSlice(&v.DataH2O, -1)
  490. }
  491. if len(v.DataSO2) > 0 {
  492. row := sheet.AddRow()
  493. cell = row.AddCell()
  494. cell.Value = v.Name
  495. row.WriteSlice(&v.DataSO2, -1)
  496. }
  497. if len(v.DataWindspeed) > 0 {
  498. row := sheet.AddRow()
  499. cell = row.AddCell()
  500. cell.Value = v.Name
  501. row.WriteSlice(&v.DataWindspeed, -1)
  502. }
  503. if len(v.DataPressure) > 0 {
  504. row := sheet.AddRow()
  505. cell = row.AddCell()
  506. cell.Value = v.Name
  507. row.WriteSlice(&v.DataPressure, -1)
  508. }
  509. if len(v.DataClO2) > 0 {
  510. row := sheet.AddRow()
  511. cell = row.AddCell()
  512. cell.Value = v.Name
  513. row.WriteSlice(&v.DataClO2, -1)
  514. }
  515. if len(v.DataC2H4) > 0 {
  516. row := sheet.AddRow()
  517. cell = row.AddCell()
  518. cell.Value = v.Name
  519. row.WriteSlice(&v.DataC2H4, -1)
  520. }
  521. if len(v.DataC2H2) > 0 {
  522. row := sheet.AddRow()
  523. cell = row.AddCell()
  524. cell.Value = v.Name
  525. row.WriteSlice(&v.DataC2H2, -1)
  526. }
  527. if len(v.DataCl2) > 0 {
  528. row := sheet.AddRow()
  529. cell = row.AddCell()
  530. cell.Value = v.Name
  531. row.WriteSlice(&v.DataCl2, -1)
  532. }
  533. if len(v.DataO3) > 0 {
  534. row := sheet.AddRow()
  535. cell = row.AddCell()
  536. cell.Value = v.Name
  537. row.WriteSlice(&v.DataO3, -1)
  538. }
  539. if len(v.DataTVOC) > 0 {
  540. row := sheet.AddRow()
  541. cell = row.AddCell()
  542. cell.Value = v.Name
  543. row.WriteSlice(&v.DataTVOC, -1)
  544. }
  545. if len(v.Datapower) > 0 {
  546. row := sheet.AddRow()
  547. cell = row.AddCell()
  548. cell.Value = v.Name
  549. row.WriteSlice(&v.Datapower, -1)
  550. }
  551. if len(v.Datasupply) > 0 {
  552. row := sheet.AddRow()
  553. cell = row.AddCell()
  554. cell.Value = v.Name
  555. row.WriteSlice(&v.Datasupply, -1)
  556. }
  557. if len(v.DataLiquidLevel) > 0 {
  558. row := sheet.AddRow()
  559. cell = row.AddCell()
  560. cell.Value = v.Name
  561. row.WriteSlice(&v.DataLiquidLevel, -1)
  562. }
  563. }
  564. for i, j := 0, len(showcols); i < j; i++ {
  565. sheet.Cols[i+2].Width = 10
  566. }
  567. sheet.Cols[0].Width = 17 //设置时间单元格的宽度
  568. sheet.Cols[1].Width = 11 //设置时间单元格的宽度
  569. }
  570. // @Title 报表导出pdf
  571. // @Description 报表导出pdf
  572. // @Success 200 {object} business.device.DeviceChannels
  573. // @router /pdf [get]
  574. func (this *ReportsController) GetPDF() {
  575. var showcols []string
  576. var timearea string
  577. svc := device.GetDeviceService(utils.DBE)
  578. client := labsop.GetLabSopClient(this.GetupdbAndHost())
  579. timerq, _ := this.GetInt64("timerq")
  580. cols := this.GetString("cols")
  581. timestr := time.Unix(timerq/1000, 0).Format("2006-01-02")
  582. t1, _ := utils.TimeParse(timestr+" 23:59:59", "2006-1-2 15:4:5")
  583. t2, _ := utils.TimeParse(timestr+" 00:00:00", "2006-1-2 15:4:5")
  584. end := t1.Unix()
  585. begin := t2.Unix()
  586. var reports = make([]Reportinfo, 0)
  587. svceq := equipment.GetEquipmentService(utils.DBE)
  588. eids := svceq.GetEquipmentidsByUid(this.User.Id)
  589. Uid := this.User.Id
  590. where := " (a.CreateUserId=" + utils.ToStr(this.User.Id) + " or a.EquipMentId in (" + eids + ")) and a.DataItem in (" + ChannelItem_Report + ") "
  591. _, channel := svc.GetChannelsList(-1, 8, where, Uid)
  592. if cols == "" {
  593. timearea = ReportDefaultTimearea
  594. showcols = strings.Split(ReportDefaultTimearr, ",")
  595. } else {
  596. timearea = "1h"
  597. showcolsstr := cols
  598. showcols = strings.Split(showcolsstr, ",")
  599. }
  600. for _, v := range channel {
  601. data := new(labsop.DatapointLabSop)
  602. queryCommand := fmt.Sprintf("select MEDIAN(temperature) as temperature,MEDIAN(humidity) as humidity,MEDIAN(voltage) as voltage,MEDIAN(rssi) as rssi,MEDIAN(o2) as o2,MEDIAN(co2) as co2,MEDIAN(h2o) as h2o,MEDIAN(so2) as so2 from %v where time > %vs and time < %vs group by time(%v) fill(none)", v.Code, begin, end, timearea)
  603. if DeviceItemContainint(ChannelItem_Power, v.DataItem) {
  604. queryCommand = fmt.Sprintf("select MEDIAN(temperature) as temperature,MEDIAN(humidity) as humidity,MEDIAN(voltage) as voltage,MEDIAN(rssi) as rssi,MEDIAN(o2) as o2,MEDIAN(co2) as co2,MEDIAN(h2o) as h2o,,MEDIAN(so2) as so2 MEDIAN(electricalsupply) as electricalsupply,MEDIAN(electricalpower) as electricalpower from %v where time > %vs and time < %vs group by time(%v) fill(none)", v.Code, begin, end, timearea)
  605. }
  606. result := client.QueryLabSop(queryCommand, data)
  607. reportdata := GetReportData(v.Title, v.DataItem, showcols, result, []TriggerHourData{})
  608. reports = append(reports, reportdata)
  609. }
  610. this.Data["reports"] = reports
  611. this.Data["timestr"] = timestr
  612. this.Data["showcols"] = showcols
  613. var times float64
  614. var report float64
  615. var i float64
  616. report = float64(len(reports))
  617. times = float64(len(showcols))
  618. pdf := gopdf.GoPdf{}
  619. //pdf.Start(gopdf.Config{Unit: "pt", PageSize: gopdf.Rect{W: 595.28, H: 841.89}}) //595.28, 841.89 = A4
  620. // pdf.Start(gopdf.Config{Unit: "pt", PageSize: gopdf.Rect{W: (200*times + 600), H: (100*report + 250)}}) //595.28, 841.89 = A4
  621. pdf.Start(gopdf.Config{Unit: "pt", PageSize: gopdf.Rect{W: (200*times + 600), H: 2550}}) //595.28, 841.89 = A4
  622. pdf.AddTTFFont("HDZB_5", "static/fonts/msyh.ttf")
  623. pdf.AddPage()
  624. pdf.Line(100, 100, 200*times+500, 100) //横线
  625. pdf.Line(100, 150, 200*times+500, 150) //横线
  626. pdf.Line(100, 100, 100, 150) //竖线
  627. for i = 0; i <= times; i++ {
  628. pdf.Line(200*i+500, 100, 200*i+500, 150) //竖线
  629. }
  630. pdf.SetFont("HDZB_5", "", 24) //字体
  631. pdf.Curr.X = 280
  632. pdf.Curr.Y = 120
  633. pdf.Cell(nil, "Sensor")
  634. pdf.Curr.X = (200*times+600)/2 - 200
  635. pdf.Curr.Y = 70
  636. pdf.Cell(nil, "名称:"+this.User.Realname+" ( "+timestr+" )")
  637. var yyy float64
  638. yyy = 120
  639. var r float64
  640. var t float64
  641. y := 0
  642. for i = 0; i < report; i++ {
  643. var hang int
  644. contants := GetpdfContaintext(reports[int(i)].Name)
  645. pdf.Curr.Y = yyy + 20
  646. for _, v := range contants {
  647. pdf.Br(26)
  648. pdf.Curr.X = 105
  649. pdf.Cell(nil, v)
  650. }
  651. if yyy == 120 {
  652. for r = 0; r < times; r++ {
  653. pdf.Curr.X = 200*r + 510
  654. pdf.Curr.Y = 120
  655. pdf.Cell(nil, (showcols[int(r)] + ":00"))
  656. }
  657. }
  658. if len(reports[int(i)].DataT) != 0 {
  659. hang++
  660. for k, temp := range reports[int(i)].DataT {
  661. pdf.Curr.X = 310 + float64(k*200)
  662. pdf.Curr.Y = 50 + yyy
  663. pdf.Cell(nil, temp)
  664. }
  665. yyy = yyy + 50
  666. pdf.Line(300, yyy+30, 200*times+500, yyy+30) //横线
  667. }
  668. if len(reports[int(i)].DataH) != 0 {
  669. hang++
  670. for k, temp := range reports[int(i)].DataH {
  671. pdf.Curr.X = 310 + float64(k*200)
  672. pdf.Curr.Y = 50 + yyy
  673. pdf.Cell(nil, temp)
  674. }
  675. yyy = yyy + 50
  676. pdf.Line(300, yyy+30, 200*times+500, yyy+30) //横线
  677. }
  678. if len(reports[int(i)].DataO2) != 0 {
  679. hang++
  680. for k, temp := range reports[int(i)].DataO2 {
  681. pdf.Curr.X = 310 + float64(k*200)
  682. pdf.Curr.Y = 50 + yyy
  683. pdf.Cell(nil, temp)
  684. }
  685. yyy = yyy + 50
  686. pdf.Line(300, yyy+30, 200*times+500, yyy+30) //横线
  687. }
  688. if len(reports[int(i)].DataCO2) != 0 {
  689. hang++
  690. for k, temp := range reports[int(i)].DataCO2 {
  691. pdf.Curr.X = 310 + float64(k*200)
  692. pdf.Curr.Y = 50 + yyy
  693. pdf.Cell(nil, temp)
  694. }
  695. yyy = yyy + 50
  696. pdf.Line(300, yyy+30, 200*times+500, yyy+30) //横线
  697. }
  698. if len(reports[int(i)].DataDisplacement) != 0 {
  699. hang++
  700. for k, temp := range reports[int(i)].DataDisplacement {
  701. pdf.Curr.X = 310 + float64(k*200)
  702. pdf.Curr.Y = 50 + yyy
  703. pdf.Cell(nil, temp)
  704. }
  705. yyy = yyy + 50
  706. pdf.Line(300, yyy+30, 200*times+500, yyy+30) //横线
  707. }
  708. if len(reports[int(i)].DataDoorlock) != 0 {
  709. hang++
  710. for k, temp := range reports[int(i)].DataDoorlock {
  711. pdf.Curr.X = 310 + float64(k*200)
  712. pdf.Curr.Y = 50 + yyy
  713. pdf.Cell(nil, temp)
  714. }
  715. yyy = yyy + 50
  716. pdf.Line(300, yyy+30, 200*times+500, yyy+30) //横线
  717. }
  718. if len(reports[int(i)].DataH2O) != 0 {
  719. hang++
  720. for k, temp := range reports[int(i)].DataH2O {
  721. pdf.Curr.X = 310 + float64(k*200)
  722. pdf.Curr.Y = 50 + yyy
  723. pdf.Cell(nil, temp)
  724. }
  725. yyy = yyy + 50
  726. pdf.Line(300, yyy+30, 200*times+500, yyy+30) //横线
  727. }
  728. if len(reports[int(i)].DataSO2) != 0 {
  729. hang++
  730. for k, temp := range reports[int(i)].DataSO2 {
  731. pdf.Curr.X = 310 + float64(k*200)
  732. pdf.Curr.Y = 50 + yyy
  733. pdf.Cell(nil, temp)
  734. }
  735. yyy = yyy + 50
  736. pdf.Line(300, yyy+30, 200*times+500, yyy+30) //横线
  737. }
  738. if len(reports[int(i)].DataWindspeed) != 0 {
  739. hang++
  740. for k, temp := range reports[int(i)].DataWindspeed {
  741. pdf.Curr.X = 310 + float64(k*200)
  742. pdf.Curr.Y = 50 + yyy
  743. pdf.Cell(nil, temp)
  744. }
  745. yyy = yyy + 50
  746. pdf.Line(300, yyy+30, 200*times+500, yyy+30) //横线
  747. }
  748. if len(reports[int(i)].DataPressure) != 0 {
  749. hang++
  750. for k, temp := range reports[int(i)].DataPressure {
  751. pdf.Curr.X = 310 + float64(k*200)
  752. pdf.Curr.Y = 50 + yyy
  753. pdf.Cell(nil, temp)
  754. }
  755. yyy = yyy + 50
  756. pdf.Line(300, yyy+30, 200*times+500, yyy+30) //横线
  757. }
  758. if len(reports[int(i)].DataClO2) != 0 {
  759. hang++
  760. for k, temp := range reports[int(i)].DataClO2 {
  761. pdf.Curr.X = 310 + float64(k*200)
  762. pdf.Curr.Y = 50 + yyy
  763. pdf.Cell(nil, temp)
  764. }
  765. yyy = yyy + 50
  766. pdf.Line(300, yyy+30, 200*times+500, yyy+30) //横线
  767. }
  768. if len(reports[int(i)].DataC2H4) != 0 {
  769. hang++
  770. for k, temp := range reports[int(i)].DataC2H4 {
  771. pdf.Curr.X = 310 + float64(k*200)
  772. pdf.Curr.Y = 50 + yyy
  773. pdf.Cell(nil, temp)
  774. }
  775. yyy = yyy + 50
  776. pdf.Line(300, yyy+30, 200*times+500, yyy+30) //横线
  777. }
  778. if len(reports[int(i)].DataC2H2) != 0 {
  779. hang++
  780. for k, temp := range reports[int(i)].DataC2H2 {
  781. pdf.Curr.X = 310 + float64(k*200)
  782. pdf.Curr.Y = 50 + yyy
  783. pdf.Cell(nil, temp)
  784. }
  785. yyy = yyy + 50
  786. pdf.Line(300, yyy+30, 200*times+500, yyy+30) //横线
  787. }
  788. if len(reports[int(i)].DataCl2) != 0 {
  789. hang++
  790. for k, temp := range reports[int(i)].DataCl2 {
  791. pdf.Curr.X = 310 + float64(k*200)
  792. pdf.Curr.Y = 50 + yyy
  793. pdf.Cell(nil, temp)
  794. }
  795. yyy = yyy + 50
  796. pdf.Line(300, yyy+30, 200*times+500, yyy+30) //横线
  797. }
  798. if len(reports[int(i)].DataO3) != 0 {
  799. hang++
  800. for k, temp := range reports[int(i)].DataO3 {
  801. pdf.Curr.X = 310 + float64(k*200)
  802. pdf.Curr.Y = 50 + yyy
  803. pdf.Cell(nil, temp)
  804. }
  805. yyy = yyy + 50
  806. pdf.Line(300, yyy+30, 200*times+500, yyy+30) //横线
  807. }
  808. if len(reports[int(i)].DataTVOC) != 0 {
  809. hang++
  810. for k, temp := range reports[int(i)].DataTVOC {
  811. pdf.Curr.X = 310 + float64(k*200)
  812. pdf.Curr.Y = 50 + yyy
  813. pdf.Cell(nil, temp)
  814. }
  815. yyy = yyy + 50
  816. pdf.Line(300, yyy+30, 200*times+500, yyy+30) //横线
  817. }
  818. if len(reports[int(i)].Datapower) != 0 {
  819. hang++
  820. for k, temp := range reports[int(i)].Datapower {
  821. pdf.Curr.X = 310 + float64(k*200)
  822. pdf.Curr.Y = 50 + yyy
  823. pdf.Cell(nil, temp)
  824. }
  825. yyy = yyy + 50
  826. pdf.Line(300, yyy+30, 200*times+500, yyy+30) //横线
  827. }
  828. if len(reports[int(i)].Datasupply) != 0 {
  829. hang++
  830. for k, temp := range reports[int(i)].Datasupply {
  831. pdf.Curr.X = 310 + float64(k*200)
  832. pdf.Curr.Y = 50 + yyy
  833. pdf.Cell(nil, temp)
  834. }
  835. yyy = yyy + 50
  836. pdf.Line(300, yyy+30, 200*times+500, yyy+30) //横线
  837. }
  838. if len(reports[int(i)].DataLiquidLevel) != 0 {
  839. hang++
  840. for k, temp := range reports[int(i)].DataLiquidLevel {
  841. pdf.Curr.X = 310 + float64(k*200)
  842. pdf.Curr.Y = 50 + yyy
  843. pdf.Cell(nil, temp)
  844. }
  845. yyy = yyy + 50
  846. pdf.Line(300, yyy+30, 200*times+500, yyy+30) //横线
  847. }
  848. if yyy > 2350 || i == report-1 {
  849. for r = 0; r <= (times + 2); r++ {
  850. pdf.Line(200*r+100, 150, 200*r+100, yyy+30) //竖线
  851. }
  852. y = y + 1
  853. yy := utils.ToStr(y)
  854. pdf.Curr.X = (200*times+600)/2 - 300
  855. pdf.Curr.Y = 2500
  856. pdf.Cell(nil, "第 "+yy+" 页")
  857. pdf.Curr.X = (200*times+600)/2 + 100
  858. pdf.Curr.Y = 2500
  859. pdf.Cell(nil, "值班人员签字:")
  860. }
  861. if yyy > 2350 && i != report-1 {
  862. pdf.AddPage()
  863. yyy = 120
  864. pdf.Line(100, 100, 200*times+500, 100) //横线
  865. pdf.Line(100, 150, 200*times+500, 150) //横线
  866. pdf.Line(100, 100, 100, 150) //竖线
  867. for t = 0; t <= times; t++ {
  868. pdf.Line(200*t+500, 100, 200*t+500, 150) //竖线
  869. }
  870. pdf.SetFont("HDZB_5", "B", 24) //字体
  871. pdf.Curr.X = 105
  872. pdf.Curr.Y = 120
  873. pdf.Cell(nil, channel[0].Title)
  874. pdf.Curr.X = (200*times+600)/2 - 100
  875. pdf.Curr.Y = 70
  876. pdf.Cell(nil, "名称:"+this.User.Realname)
  877. for t = 0; t < times; t++ {
  878. pdf.Curr.X = 200*t + 510
  879. pdf.Curr.Y = 120
  880. pdf.Cell(nil, (showcols[int(t)] + ":00"))
  881. }
  882. }
  883. if len(contants)*26 > hang*50 {
  884. for i := 0; i < int(math.Ceil((float64(len(contants)*26-(hang*50))+20)/50)); i++ {
  885. yyy = yyy + 50
  886. pdf.Line(300, yyy+30, 200*times+500, yyy+30) //横线
  887. }
  888. }
  889. pdf.Line(100, yyy+30, 200*times+500, yyy+30) //横线
  890. }
  891. SaveDirectory("static/file/pdf/report/" + this.GetAccode())
  892. pdf.WritePdf("static/file/pdf/report/" + this.GetAccode() + "/devicedata.pdf")
  893. var errinfo ErrorInfo
  894. errinfo.Message = this.Ctx.Request.Host + "/static/file/pdf/report/" + this.GetAccode() + "/devicedata.pdf"
  895. errinfo.Code = 0
  896. this.Data["json"] = &errinfo
  897. this.ServeJSON()
  898. }
  899. func show_strlen(s string) int {
  900. sl := 0
  901. rs := []rune(s)
  902. for _, r := range rs {
  903. rint := int(r)
  904. if rint < 128 {
  905. sl++
  906. } else {
  907. sl += 2
  908. }
  909. }
  910. return sl
  911. }
  912. func GetpdfContaintext(str string) (texts []string) {
  913. strs := strings.Split(str, "")
  914. fnum, start := 1, 0
  915. for k, _ := range strs {
  916. fnum++
  917. if fnum > 7 {
  918. strfont := strings.Join(strs[start:k+1], "")
  919. pwidth := show_strlen(strfont)
  920. if pwidth >= 12 {
  921. texts = append(texts, strfont)
  922. start = k + 1
  923. }
  924. }
  925. }
  926. if start < len(strs) {
  927. texts = append(texts, strings.Join(strs[start:len(strs)], ""))
  928. }
  929. return texts
  930. }