exprot.go 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356
  1. package service
  2. import (
  3. "archive/zip"
  4. "fmt"
  5. "io"
  6. "log"
  7. "math/rand"
  8. "os"
  9. "path/filepath"
  10. "regexp"
  11. "strings"
  12. "time"
  13. "app.yhyue.com/moapp/jybase/common"
  14. "app.yhyue.com/moapp/jybase/mail"
  15. . "bp.jydev.jianyu360.cn/BaseService/biService/entity"
  16. "github.com/gogf/gf/v2/util/gconv"
  17. "github.com/xuri/excelize/v2"
  18. "github.com/zeromicro/go-zero/core/logx"
  19. )
  20. var (
  21. DateTime = "2006-01-02 15:04:05"
  22. )
  23. type ExportReq struct {
  24. Mail string
  25. Mapping []string
  26. PositionId int64
  27. }
  28. type ExportByDbReq struct {
  29. Token string
  30. Title string
  31. Content string
  32. Mails string
  33. Query string
  34. Stype string
  35. }
  36. // 全量项目导出
  37. func (a *ExportReq) AllProjectExport() {
  38. tableColumn := []string{}
  39. exportKey := []interface{}{}
  40. for _, value := range a.Mapping {
  41. valueArr := strings.Split(value, ":")
  42. tableColumn = append(tableColumn, valueArr[0])
  43. exportKey = append(exportKey, valueArr[1])
  44. }
  45. timeStr := time.Now().Format("20060102150405")
  46. rand.Seed(time.Now().UnixNano())
  47. randomInt := rand.Intn(10000) // 生成0到9999之间的随机整数
  48. timeStr = fmt.Sprintf("%s%s", timeStr, gconv.String(randomInt))
  49. pathArr := export("customer_data_ttzl_project", tableColumn, exportKey, timeStr)
  50. if len(pathArr) > 0 {
  51. folderPath := fmt.Sprintf("%s/%s", ExportDirectory, timeStr)
  52. compressFiles(pathArr, folderPath, timeStr)
  53. pathstr := fmt.Sprintf("%s/%s/%s.zip", ExportUrl, timeStr, timeStr)
  54. state := sendMail("项目", a.Mail, pathstr)
  55. BiService.Insert("export_record", map[string]interface{}{
  56. "positionId": a.PositionId,
  57. "type": "project",
  58. "excelPath": strings.Join(pathArr, ","),
  59. "zipPath": pathstr,
  60. "sendState": state,
  61. "createTime": time.Now().Format(DateTime),
  62. })
  63. }
  64. }
  65. // 全量资讯导出
  66. func (a *ExportReq) AllInfoExport() {
  67. tableColumn := []string{}
  68. exportKey := []interface{}{}
  69. for _, value := range a.Mapping {
  70. valueArr := strings.Split(value, ":")
  71. tableColumn = append(tableColumn, valueArr[0])
  72. exportKey = append(exportKey, valueArr[1])
  73. }
  74. timeStr := time.Now().Format("20060102150405")
  75. rand.Seed(time.Now().UnixNano())
  76. randomInt := rand.Intn(10000) // 生成0到9999之间的随机整数
  77. timeStr = fmt.Sprintf("%s%s", timeStr, gconv.String(randomInt))
  78. pathArr := export("customer_data_ttzl", tableColumn, exportKey, timeStr)
  79. if len(pathArr) > 0 {
  80. folderPath := fmt.Sprintf("%s/%s", ExportDirectory, timeStr)
  81. compressFiles(pathArr, folderPath, timeStr)
  82. pathstr := fmt.Sprintf("%s/%s/%s.zip", ExportUrl, timeStr, timeStr)
  83. state := sendMail("标讯", a.Mail, pathstr)
  84. BiService.Insert("export_record", map[string]interface{}{
  85. "positionId": a.PositionId,
  86. "type": "project",
  87. "excelPath": strings.Join(pathArr, ","),
  88. "zipPath": pathstr,
  89. "sendState": state,
  90. "createTime": time.Now().Format(DateTime),
  91. })
  92. }
  93. }
  94. // 导出开始
  95. func export(table string, tableColumn []string, key []interface{}, timeStr string) []string {
  96. pathArr := []string{}
  97. sqlStr := fmt.Sprintf("SELECT %s FROM %s", strings.Join(tableColumn, ","), table)
  98. fileCounter := 1
  99. writer, file := InirWrite(key)
  100. a := 0
  101. path := ""
  102. BiService.SelectByBath(1, func(l *[]map[string]interface{}) bool {
  103. if a%ExportCount == 0 && a > 0 {
  104. a = 0
  105. //入excel处理
  106. writer, file, path = Warehousing(writer, file, fileCounter, key, ExportDirectory, timeStr)
  107. fileCounter++
  108. pathArr = append(pathArr, path)
  109. }
  110. dataHandle(writer, l, a+1, tableColumn)
  111. a++
  112. return true
  113. }, sqlStr)
  114. if a > 0 && a != ExportCount {
  115. writer, file, path = Warehousing(writer, file, fileCounter, key, ExportDirectory, timeStr)
  116. pathArr = append(pathArr, path)
  117. }
  118. return pathArr
  119. }
  120. // 数据处理
  121. func dataHandle(writer *excelize.StreamWriter, l *[]map[string]interface{}, a int, tableColumn []string) {
  122. for _, value := range *l {
  123. valueArr := []interface{}{}
  124. for _, column := range tableColumn {
  125. valueArr = append(valueArr, gconv.String(value[column]))
  126. }
  127. cell, _ := excelize.CoordinatesToCellName(1, a+1)
  128. writer.SetRow(cell, valueArr)
  129. }
  130. }
  131. // 入excel
  132. func Warehousing(writer *excelize.StreamWriter, file *excelize.File, fileCounter int, key []interface{}, path, timeStr string) (*excelize.StreamWriter, *excelize.File, string) {
  133. logx.Info(fmt.Sprintf("开始第%d个文件数据", fileCounter))
  134. writer.Flush()
  135. folderPath := fmt.Sprintf("%s/%s", path, timeStr)
  136. _, err := os.Stat(folderPath)
  137. if os.IsNotExist(err) {
  138. //创建文件夹
  139. err := os.MkdirAll(folderPath, os.ModePerm)
  140. if err != nil {
  141. logx.Info("创建文件夹失败:", err)
  142. }
  143. }
  144. fileName := fmt.Sprintf("%s/output%d.xlsx", folderPath, fileCounter)
  145. err = file.SaveAs(fileName)
  146. if err != nil {
  147. logx.Info(err)
  148. }
  149. writer, file = InirWrite(key)
  150. return writer, file, fileName
  151. }
  152. // excel初始化
  153. func InirWrite(key []interface{}) (*excelize.StreamWriter, *excelize.File) {
  154. //文件初始化
  155. file := excelize.NewFile()
  156. //设置表名
  157. file.SetSheetName("Sheet1", "表1")
  158. //创建流式写入
  159. writer, _ := file.NewStreamWriter("表1")
  160. // 定义每个 Excel 文件的数据列数限制
  161. writer.SetRow("A1", key)
  162. return writer, file
  163. }
  164. // 发送邮箱
  165. func sendMail(title, target_mail string, path string) bool {
  166. mailStr := "<html lang=\"en\">\n<head>\n <meta charset=\"UTF-8\">\n <title>铁塔全量%s数据导出</title>\n</head>\n<body>\n<div>\n <p>铁塔全量%s数据已导出成功,导出时间:%s,请点击链接下载数据:<a href=\"%s\">%s</a></p>\n </div>\n</body>"
  167. html := fmt.Sprintf(mailStr, title, title, time.Now().Format(DateTime), path, path)
  168. fool := false
  169. for k, v := range GmailAuth {
  170. fool := mail.GSendMail("剑鱼标讯", target_mail, "", "", fmt.Sprintf("铁塔全量%s数据导出", title), html, "", "", v)
  171. if fool {
  172. logx.Info(target_mail, fmt.Sprintf("使用%s发送邮件成功", v.User))
  173. break
  174. }
  175. if k < len(GmailAuth)-1 {
  176. logx.Info(target_mail, fmt.Sprintf("使用%s发送邮件失败!3s后使用其他邮箱尝试", v.User))
  177. } else {
  178. logx.Info(target_mail, fmt.Sprintf("使用%s发送邮件失败!", v.User))
  179. }
  180. time.Sleep(time.Second * 3)
  181. }
  182. return fool
  183. }
  184. // 文件压缩
  185. func compressFiles(filePattern []string, path, timeStr string) {
  186. _, err := os.Stat(path)
  187. if os.IsNotExist(err) {
  188. //创建文件夹
  189. err := os.MkdirAll(path, os.ModePerm)
  190. if err != nil {
  191. logx.Info("创建文件夹失败:", err)
  192. }
  193. }
  194. zipFilename := fmt.Sprintf("%s/%s.zip", path, timeStr)
  195. // 创建 ZIP 文件
  196. zipFile, err := os.Create(zipFilename)
  197. if err != nil {
  198. log.Fatal(err)
  199. }
  200. defer zipFile.Close()
  201. // 创建 ZIP Writer
  202. zipWriter := zip.NewWriter(zipFile)
  203. defer zipWriter.Close()
  204. // 遍历文件列表
  205. for _, file := range filePattern {
  206. // 打开文件
  207. f, err := os.Open(file)
  208. if err != nil {
  209. log.Fatal(err)
  210. }
  211. defer f.Close()
  212. // 获取文件信息
  213. _, err = f.Stat()
  214. if err != nil {
  215. log.Fatal(err)
  216. }
  217. //文件名切割
  218. nameArr := strings.Split(file, "/")
  219. name := nameArr[len(nameArr)-1]
  220. name = fmt.Sprintf("%s/%s", timeStr, name)
  221. // 创建 ZIP 内部文件
  222. zipFile, err := zipWriter.Create(name)
  223. if err != nil {
  224. log.Fatal(err)
  225. }
  226. // 将文件内容复制到 ZIP 文件中
  227. _, err = io.Copy(zipFile, f)
  228. if err != nil {
  229. log.Fatal(err)
  230. }
  231. }
  232. // 打印压缩文件路径
  233. absPath, err := filepath.Abs(zipFilename)
  234. if err != nil {
  235. log.Fatal(err)
  236. }
  237. log.Printf("Files compressed to: %s", absPath)
  238. //return fmt.Sprintf("%s/%s/%s.zip", url, timeStr, timeStr)
  239. //return fmt.Sprintf("%s/%s/%s.zip", url, timeStr, timeStr)
  240. }
  241. // 数据导出(通用)
  242. func (e *ExportByDbReq) ExportDataByDb() []byte {
  243. key := hName(e.Query)
  244. log.Println("", key)
  245. timeStr := time.Now().Format("20060102150405")
  246. rand.Seed(time.Now().UnixNano())
  247. randomInt := rand.Intn(10000) // 生成0到9999之间的随机整数
  248. timeStr = fmt.Sprintf("%s%s", timeStr, gconv.String(randomInt))
  249. stype := e.Stype
  250. if stype == "" {
  251. stype = "public"
  252. }
  253. path1 := fmt.Sprintf("%s/%s", ComFileDir, stype)
  254. pathArr := exportA(e.Query, path1, timeStr, key)
  255. if len(pathArr) > 0 {
  256. //folderPath := fmt.Sprintf("%s/%s", path1, timeStr)
  257. //compressFiles(pathArr, folderPath, timeStr)
  258. //pathstr := fmt.Sprintf("%s/%s/%s/%s.zip", ComFileUrl, stype, timeStr, timeStr)
  259. var files []string
  260. for _, s := range pathArr {
  261. ss := strings.Split(s, "/")
  262. files = append(files, fmt.Sprintf("%s/%s/%s/%s", ComFileUrl, stype, timeStr, ss[len(ss)-1]))
  263. }
  264. state := sendMailA(e.Title, e.Mails, e.Content, strings.Join(files, ","))
  265. BiService.Insert("export_record", map[string]interface{}{
  266. "positionId": "0",
  267. "type": stype,
  268. "excelPath": strings.Join(pathArr, ","),
  269. "zipPath": "",
  270. "sendState": state,
  271. "createTime": time.Now().Format(DateTime),
  272. })
  273. return gconv.Bytes(map[string]interface{}{"status": 1, "msg": "导出数据成功"})
  274. }
  275. return gconv.Bytes(map[string]interface{}{"status": -1, "msg": "导出数据失败,未查询到数据"})
  276. }
  277. // 表头
  278. func hName(sql string) []interface{} {
  279. var key []interface{}
  280. s := strings.Split(strings.ToLower(sql), "from")
  281. keystr := strings.ReplaceAll(s[0], "select", "")
  282. keystr = strings.ReplaceAll(keystr, " ", "")
  283. for _, s1 := range strings.Split(keystr, ",") {
  284. if strings.Contains(s1, "as") {
  285. a1 := strings.Split(s1, "as")
  286. l1 := len(a1)
  287. chiReg := regexp.MustCompile("[^\u4e00-\u9fa5]")
  288. if !chiReg.MatchString(a1[l1-1]) {
  289. key = append(key, a1[l1-1])
  290. }
  291. }
  292. }
  293. return key
  294. }
  295. // 导出开始
  296. func exportA(sql, path, timeStr string, key []interface{}) []string {
  297. pathArr := []string{}
  298. fileCounter := 1
  299. writer, file := InirWrite(key)
  300. a := 0
  301. fpath := ""
  302. JyBiTidb.SelectByBath(1, func(l *[]map[string]interface{}) bool {
  303. if a%ExportCount == 0 && a > 0 {
  304. a = 0
  305. //入excel处理
  306. writer, file, fpath = Warehousing(writer, file, fileCounter, key, path, timeStr)
  307. fileCounter++
  308. pathArr = append(pathArr, fpath)
  309. }
  310. dataHandle(writer, l, a+1, common.ObjArrToStringArr(key))
  311. a++
  312. return true
  313. }, sql)
  314. if a > 0 && a != ExportCount {
  315. writer, file, fpath = Warehousing(writer, file, fileCounter, key, path, timeStr)
  316. pathArr = append(pathArr, fpath)
  317. }
  318. return pathArr
  319. }
  320. func sendMailA(title, target_mail, content string, path string) bool {
  321. html := strings.ReplaceAll(content, "#downLoadUrl#", path)
  322. fool := false
  323. for k, v := range GmailAuth {
  324. fool := mail.GSendMail("剑鱼标讯", target_mail, "", "", fmt.Sprintf("%s数据导出", title), html, "", "", v)
  325. if fool {
  326. logx.Info(target_mail, fmt.Sprintf("使用%s发送邮件成功", v.User))
  327. break
  328. }
  329. if k < len(GmailAuth)-1 {
  330. logx.Info(target_mail, fmt.Sprintf("使用%s发送邮件失败!3s后使用其他邮箱尝试", v.User))
  331. } else {
  332. logx.Info(target_mail, fmt.Sprintf("使用%s发送邮件失败!", v.User))
  333. }
  334. time.Sleep(time.Second * 3)
  335. }
  336. return fool
  337. }