exprot.go 9.6 KB

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