exprot.go 9.6 KB

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