parsxlsx.go 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488
  1. package util
  2. import (
  3. "app.yhyue.com/moapp/jybase/common"
  4. "app.yhyue.com/moapp/jybase/date"
  5. "app.yhyue.com/moapp/jybase/encrypt"
  6. "app.yhyue.com/moapp/jybase/log"
  7. "app.yhyue.com/moapp/jybase/mongodb"
  8. "fmt"
  9. "github.com/tealeg/xlsx"
  10. "go.mongodb.org/mongo-driver/bson"
  11. "go.uber.org/zap"
  12. "strings"
  13. "time"
  14. )
  15. const (
  16. Matchkey = "s_matchkey" //关键词
  17. Addkey = "s_addkey" //附加词
  18. Notkey = "s_notkey" //排除词
  19. Buyerclass = "s_buyerclass" //采购单位行业
  20. Topscopeclass = "s_topscopeclass" //行业-一级
  21. Subscopeclass = "s_subscopeclass" //行业-二级
  22. Globaladdkey = "s_globaladdkey" // 全局附加词
  23. Globalnotkey = "s_globalnotkey" //全局排除词
  24. Globalclearkey = "s_globalclearkey" //全局排除词
  25. Tagname = "s_name" //标签的关键词规则名称
  26. )
  27. var SES = encrypt.SimpleEncrypt{Key: "topJYBX2019"}
  28. // 通用标签相关字段
  29. var export_fields = []string{"s_userid", "s_name", "", "s_area", "s_city", "s_district", "s_toptype", "s_subtype", "i_starttime", "i_endtime", "s_budgetlimit", "s_bidamountlimit", "s_globaltopscopeclass", "s_globalsubscopeclass", "s_globalbuyerclass", "s_globaladdkey", "s_globaladdkeymatch", "s_globalnotkey", "s_globalnotkeymatch", "s_globalclearkey", "s_globalclearkeymatch", "s_existfields", "i_extfieldstype"}
  30. // 关键词标签相关字段
  31. var export_o_rules = []string{"s_matchkey", "s_keymatch", "s_addkey", "s_addkeymatch", "s_notkey", "s_notkeymatch", "s_buyerclass"}
  32. // 定义值为数字的多个匹配方式map
  33. var export_numfield = map[string]bool{
  34. "s_globaladdkeymatch": true,
  35. "s_globalnotkeymatch": true,
  36. "s_globalclearkeymatch": true,
  37. "s_keymatch": true,
  38. "s_addkeymatch": true,
  39. "s_notkeymatch": true,
  40. }
  41. // 匹配方式map
  42. var export_matchtype = map[string]interface{}{
  43. "1": "标题匹配",
  44. "2": "全文匹配",
  45. "3": "标的物匹配",
  46. "4": "附件匹配",
  47. "5": "项目名称匹配",
  48. "6": "采购单位匹配",
  49. "7": "中标单位匹配",
  50. "8": "采购单位匹配(正则)",
  51. "9": "中标单位匹配(正则)",
  52. }
  53. // 字段包类型
  54. var export_extfieldstype = map[string]interface{}{
  55. "1": "标准字段包",
  56. "2": "高级字段包",
  57. }
  58. /**
  59. * 导入关键词表格
  60. */
  61. func Parsxlsx(filebyte []byte) (map[string]interface{}, error) {
  62. rdata := make(map[string]interface{})
  63. tmps := make([]map[string]string, 0)
  64. file, err := xlsx.OpenBinary(filebyte)
  65. if err != nil {
  66. return rdata, err
  67. }
  68. gaddkeyArr := []string{}
  69. gnotkeyArr := []string{}
  70. clearkeyArr := []string{}
  71. for _, v := range file.Sheets {
  72. for ii, vv := range v.Rows {
  73. rule := make(map[string]string)
  74. if ii == 0 {
  75. //第一行跳过
  76. continue
  77. }
  78. for iii, vvv := range vv.Cells {
  79. gaddkeyArr, gnotkeyArr, clearkeyArr = writeMap(rule, iii, vvv.Value, gaddkeyArr, gnotkeyArr, clearkeyArr)
  80. }
  81. tmps = append(tmps, rule)
  82. }
  83. }
  84. rdata["o_rules"] = tmps
  85. if len(gaddkeyArr) >= 1 {
  86. rdata[Globaladdkey] = strings.Join(gaddkeyArr, ",")
  87. }
  88. if len(gnotkeyArr) >= 1 {
  89. rdata[Globalnotkey] = strings.Join(gnotkeyArr, ",")
  90. }
  91. if len(clearkeyArr) >= 1 {
  92. rdata[Globalclearkey] = strings.Join(clearkeyArr, ",")
  93. }
  94. return rdata, nil
  95. }
  96. /**
  97. * 导入关键词表格
  98. */
  99. func Parsxlsx1(filebyte []byte) (map[string]interface{}, error) {
  100. rdata := make(map[string]interface{})
  101. tmps := make([]map[string]string, 0)
  102. file, err := xlsx.OpenBinary(filebyte)
  103. if err != nil {
  104. return rdata, err
  105. }
  106. for _, v := range file.Sheets {
  107. for ii, vv := range v.Rows {
  108. rule := make(map[string]string)
  109. if ii == 0 {
  110. //第一行跳过
  111. continue
  112. }
  113. for iii, vvv := range vv.Cells {
  114. writeMap1(rule, iii, vvv.Value)
  115. }
  116. tmps = append(tmps, rule)
  117. }
  118. }
  119. rdata["o_rules"] = tmps
  120. return rdata, nil
  121. }
  122. func writeMap(tmp map[string]string, i int, v string, addArr, notArr, clearkeyArr []string) ([]string, []string, []string) {
  123. switch i {
  124. case 0:
  125. if v != "" {
  126. //空格
  127. v = strings.TrimSpace(v)
  128. //中文逗号
  129. v = strings.ReplaceAll(v, ",", ",")
  130. tmp[Matchkey] = v
  131. }
  132. break
  133. case 1:
  134. if v != "" {
  135. v = strings.TrimSpace(v)
  136. v = strings.ReplaceAll(v, ",", ",")
  137. tmp[Addkey] = v
  138. }
  139. break
  140. case 2:
  141. if v != "" {
  142. v = strings.TrimSpace(v)
  143. v = strings.ReplaceAll(v, ",", ",")
  144. tmp[Notkey] = v
  145. }
  146. break
  147. case 3:
  148. if v != "" {
  149. v = strings.TrimSpace(v)
  150. v = strings.ReplaceAll(v, ",", ",")
  151. tmp[Buyerclass] = v
  152. }
  153. break
  154. case 4:
  155. if v != "" {
  156. v = strings.TrimSpace(v)
  157. v = strings.ReplaceAll(v, ",", ",")
  158. tmp[Topscopeclass] = v
  159. }
  160. break
  161. case 5:
  162. if v != "" {
  163. v = strings.TrimSpace(v)
  164. v = strings.ReplaceAll(v, ",", ",")
  165. tmp[Subscopeclass] = v
  166. }
  167. break
  168. case 6:
  169. if v != "" {
  170. v = strings.TrimSpace(v)
  171. v = strings.ReplaceAll(v, ",", ",")
  172. addArr = append(addArr, v)
  173. }
  174. break
  175. case 7:
  176. if v != "" {
  177. v = strings.TrimSpace(v)
  178. v = strings.ReplaceAll(v, ",", ",")
  179. notArr = append(notArr, v)
  180. }
  181. break
  182. case 8:
  183. if v != "" {
  184. v = strings.TrimSpace(v)
  185. v = strings.ReplaceAll(v, ",", ",")
  186. clearkeyArr = append(clearkeyArr, v)
  187. }
  188. break
  189. case 9:
  190. if v != "" {
  191. v = strings.TrimSpace(v)
  192. v = strings.ReplaceAll(v, ",", ",")
  193. tmp["s_group"] = v
  194. }
  195. break
  196. }
  197. return addArr, notArr, clearkeyArr
  198. }
  199. func writeMap1(tmp map[string]string, i int, v string) {
  200. switch i {
  201. case 0:
  202. if v != "" {
  203. //空格
  204. v = strings.TrimSpace(v)
  205. //中文逗号
  206. v = strings.ReplaceAll(v, ",", ",")
  207. tmp[Matchkey] = v
  208. }
  209. break
  210. case 1:
  211. if v != "" {
  212. v = strings.TrimSpace(v)
  213. v = strings.ReplaceAll(v, ",", ",")
  214. tmp[Addkey] = v
  215. }
  216. break
  217. case 2:
  218. if v != "" {
  219. v = strings.TrimSpace(v)
  220. v = strings.ReplaceAll(v, ",", ",")
  221. tmp[Notkey] = v
  222. }
  223. break
  224. case 3:
  225. if v != "" {
  226. v = strings.TrimSpace(v)
  227. v = strings.ReplaceAll(v, ",", ",")
  228. tmp[Tagname] = v
  229. }
  230. }
  231. }
  232. var bzpath, gjpath, rpath string = "web/res/%s_数据_%s_%s.xlsx", "web/res/%s_数据_%s_%s.xlsx", "web/res/%s_规则_%s_%s.xlsx"
  233. func ResponseXlsx_Data(id string) string {
  234. if id != "" {
  235. query := bson.M{
  236. "_id": mongodb.StringTOBsonId(id),
  237. }
  238. data, _ := Mgo.FindOne("cuserdepartrule", query)
  239. ruleName := (*data)["s_name"]
  240. if (*data) != nil && len(*data) > 0 {
  241. isStandard := true
  242. if common.Int64All((*data)["i_extfieldstype"]) == Advanced {
  243. isStandard = false
  244. }
  245. data, _ := Mgo.Find("tagsdata", bson.M{"s_dataid": common.ObjToString((*data)["s_dataid"])}, nil, nil, false, -1, -1)
  246. if (*data) == nil || len(*data) == 0 {
  247. return ""
  248. }
  249. xf, err := xlsx.OpenFile("web/res/fields.xlsx")
  250. if err != nil {
  251. log.Error("fields file not foud", zap.Error(err))
  252. return ""
  253. }
  254. if isStandard {
  255. sh := xf.Sheets[0]
  256. for i, v := range *data {
  257. row := sh.AddRow()
  258. row.AddCell().SetInt(i + 1)
  259. row.AddCell().SetValue(v["s_matchkey"])
  260. row.AddCell().SetValue(v["area"])
  261. row.AddCell().SetValue(v["city"])
  262. row.AddCell().SetValue(v["title"])
  263. row.AddCell().SetValue(v["subtype"])
  264. if v["publishtime"] != nil {
  265. row.AddCell().SetValue(time.Unix(common.Int64All(v["publishtime"]), 0).Format("2006-01-02"))
  266. } else {
  267. row.AddCell()
  268. }
  269. row.AddCell().SetValue(v["buyer"])
  270. row.AddCell().SetValue(v["winner"])
  271. if v["bidamount"] != nil {
  272. row.AddCell().SetFloat(common.Float64All(v["bidamount"]))
  273. } else {
  274. row.AddCell()
  275. }
  276. row.AddCell().SetValue(v["projectname"])
  277. row.AddCell().SetValue(v["detail"])
  278. row.AddCell().SetValue(v["s_jyhref"])
  279. }
  280. xf.Sheets = xf.Sheets[:1]
  281. xf.Sheets[0].Name = "详细数据"
  282. t := time.Now().Format("20060102")
  283. fname := fmt.Sprintf(bzpath, ruleName, t, common.GetRandom(4))
  284. err := xf.Save(fname)
  285. if err != nil {
  286. log.Error("", zap.Error(err))
  287. return ""
  288. }
  289. return fname
  290. } else {
  291. sh := xf.Sheets[1]
  292. for _, v := range *data {
  293. row := sh.AddRow()
  294. // row.AddCell().SetInt(i + 1)
  295. row.AddCell().SetValue(v["s_matchkey"])
  296. row.AddCell().SetValue(v["area"])
  297. row.AddCell().SetValue(v["city"])
  298. row.AddCell().SetValue(v["title"])
  299. row.AddCell().SetValue(v["subtype"])
  300. row.AddCell().SetValue(v["detail"])
  301. if v["publishtime"] != nil {
  302. row.AddCell().SetValue(time.Unix(common.Int64All(v["publishtime"]), 0).Format("2006-01-02"))
  303. } else {
  304. row.AddCell()
  305. }
  306. row.AddCell().SetValue(v["href"])
  307. row.AddCell().SetValue(v["s_jyhref"])
  308. row.AddCell().SetValue(v["projectname"])
  309. row.AddCell().SetValue(v["projectcode"])
  310. row.AddCell().SetValue(v["projectscope"])
  311. if v["budget"] != nil {
  312. row.AddCell().SetFloat(common.Float64All(v["budget"]))
  313. } else {
  314. row.AddCell()
  315. }
  316. if v["bidamount"] != nil {
  317. row.AddCell().SetFloat(common.Float64All(v["bidamount"]))
  318. } else {
  319. row.AddCell()
  320. }
  321. if v["bidopentime"] != nil {
  322. row.AddCell().SetValue(time.Unix(common.Int64All(v["bidopentime"]), 0).Format("2006-01-02"))
  323. } else {
  324. row.AddCell()
  325. }
  326. row.AddCell().SetValue(v["buyer"])
  327. row.AddCell().SetValue(v["buyerperson"])
  328. row.AddCell().SetValue(v["buyertel"])
  329. row.AddCell().SetValue(v["agency"])
  330. row.AddCell().SetValue(v["s_winner"])
  331. row.AddCell().SetValue(v["winnerperson"])
  332. row.AddCell().SetValue(v["winnertel"])
  333. row.AddCell().SetValue(v["legal_person"])
  334. row.AddCell().SetValue(v["company_phone"])
  335. row.AddCell().SetValue(v["company_email"])
  336. ids := SES.EncodeString(common.ObjToString(v["info_id"]))
  337. row.AddCell().SetValue(ids)
  338. }
  339. xf.Sheets = xf.Sheets[1:2]
  340. xf.Sheets[0].Name = "详细数据"
  341. t := time.Now().Format("20060102")
  342. fname := fmt.Sprintf(gjpath, ruleName, t, common.GetRandom(4))
  343. err := xf.Save(fname)
  344. if err != nil {
  345. log.Error("", zap.Error(err))
  346. return ""
  347. }
  348. return fname
  349. }
  350. }
  351. }
  352. return ""
  353. }
  354. func ResponseXlsx_Rule(id string) string {
  355. defer common.Catch()
  356. var data *map[string]interface{}
  357. data, _ = Mgo.FindById("cuserdepartrule", id, `{}`)
  358. if len(*data) == 0 {
  359. return ""
  360. }
  361. exact := 0
  362. xf, err := xlsx.OpenFile("web/res/export_rule.xlsx") //读取导出标签模板表
  363. if err != nil {
  364. log.Error("export_rule file not foud", zap.Error(err))
  365. return ""
  366. }
  367. sh := xf.Sheets[0]
  368. fields_len := len(export_fields)
  369. //
  370. for i, r := range sh.Rows {
  371. if i == fields_len {
  372. break
  373. }
  374. field := export_fields[i] //export_fields值的顺序与模板表一致
  375. if field == "i_extfieldstype" {
  376. r.AddCell().SetValue(export_extfieldstype[fmt.Sprint((*data)[field])])
  377. continue
  378. }
  379. if field == "s_userid" {
  380. userName, _ := Mgo.FindById("cuser", (*data)[field].(string), `{}`)
  381. if common.IntAll((*userName)["i_exact"]) == 1 {
  382. exact = 1
  383. }
  384. r.AddCell().SetValue((*userName)["s_name"])
  385. continue
  386. }
  387. field_val := ""
  388. if strings.HasPrefix(field, "s_") {
  389. field_val = common.ObjToString((*data)[field])
  390. if export_numfield[field] { //找出值为数字的匹配方式,转换成中文
  391. field_val = numValToWord(field_val)
  392. }
  393. } else if strings.HasPrefix(field, "i_") { //i_startime i_endtime
  394. t := common.Int64All((*data)[field])
  395. if t > 0 {
  396. field_val = date.FormatDateByInt64(&t, date.Date_Full_Layout)
  397. }
  398. }
  399. r.AddCell().SetValue(field_val)
  400. }
  401. o_rules := (*data)["o_rules"].([]interface{})
  402. for _, o_rule := range o_rules {
  403. new_row := sh.AddRow()
  404. o_tmp := o_rule.(map[string]interface{})
  405. for _, match := range export_o_rules {
  406. cell_val := common.ObjToString(o_tmp[match])
  407. if export_numfield[match] { //找出值为数字的匹配方式,转换成中文
  408. cell_val = numValToWord(cell_val)
  409. }
  410. new_row.AddCell().SetValue(cell_val)
  411. }
  412. if s_topscopeclass := o_tmp["s_topscopeclass"]; s_topscopeclass != "" {
  413. new_row.AddCell().SetValue(s_topscopeclass)
  414. } else if s_subscopeclass := o_tmp["s_subscopeclass"]; s_subscopeclass != "" {
  415. new_row.AddCell().SetValue(s_subscopeclass)
  416. }
  417. if exact == 1 {
  418. new_row.AddCell().SetValue(o_tmp["s_group"])
  419. }
  420. }
  421. ruleName := (*data)["s_name"]
  422. t := time.Now().Format("20060102")
  423. fname := fmt.Sprintf(rpath, ruleName, t, common.GetRandom(4))
  424. xf.Save(fname)
  425. return fname
  426. }
  427. // 匹配方式的数字值,转为对应的汉字
  428. func numValToWord(numval string) (word string) {
  429. field_arr := strings.Split(numval, ",")
  430. for i, val := range field_arr {
  431. if i == 0 {
  432. word = common.ObjToString(export_matchtype[val])
  433. continue
  434. }
  435. word = word + "," + common.ObjToString(export_matchtype[val])
  436. }
  437. return
  438. }
  439. /**
  440. * 导入剑鱼批量修改数据
  441. */
  442. func ParsJyData(filebyte []byte) ([]map[string]interface{}, error) {
  443. var jyData []map[string]interface{}
  444. var keyName []string
  445. file, err := xlsx.OpenBinary(filebyte)
  446. if err != nil {
  447. return jyData, err
  448. }
  449. for i, v := range file.Sheets[0].Rows {
  450. data := make(map[string]interface{})
  451. for ii, vv := range v.Cells {
  452. if i == 0 {
  453. keyName = append(keyName, vv.Value)
  454. } else {
  455. if vv.Value != "" {
  456. data[keyName[ii]] = vv.Value
  457. }
  458. }
  459. }
  460. if len(data) > 0 {
  461. jyData = append(jyData, data)
  462. }
  463. }
  464. return jyData, nil
  465. }