export.go 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262
  1. package excel
  2. import (
  3. "encoding/csv"
  4. "encoding/json"
  5. "errors"
  6. "fmt"
  7. "io"
  8. "os"
  9. "regexp"
  10. "scd_check_tools/logger"
  11. "scd_check_tools/tools"
  12. "strconv"
  13. "strings"
  14. "github.com/astaxie/beego/orm"
  15. "github.com/tealeg/xlsx"
  16. )
  17. var CacheFilePath = "tmp"
  18. var tmpFileName = ""
  19. func InitExcel(name string, p ...string) (result error) {
  20. if name == "" {
  21. fmt.Println(tools.NowTime() + "文件名不能为空")
  22. return errors.New("文件名不能为空")
  23. }
  24. tmpFileName = name
  25. if len(p) > 0 {
  26. path := p[0]
  27. if path == "" {
  28. fmt.Println(tools.NowTime() + "文件存储路径不能为空")
  29. return errors.New("文件存储路径不能为空")
  30. }
  31. CacheFilePath = path
  32. if _, err := os.Stat(CacheFilePath); os.IsNotExist(err) {
  33. // 必须分成两步:先创建文件夹、再修改权限
  34. os.MkdirAll(CacheFilePath, 0777) //0777也可以os.ModePerm
  35. os.Chmod(CacheFilePath, 0777)
  36. }
  37. }
  38. return nil
  39. }
  40. //导出数据
  41. func ExportExcel(caption string, cols []string, colnames []string, datalist []orm.Params, autoNoCol bool) (filename string, result error) {
  42. excelFileName := CacheFilePath + string(os.PathSeparator) + tmpFileName
  43. if excelFileName == "" {
  44. fmt.Println(tools.NowTime() + "导出的文件路径或文件名不能为空")
  45. return "", errors.New("导出的文件路径或文件名不能为空")
  46. }
  47. /*
  48. xlFile, err := xlsx.OpenFile(excelFileName)
  49. if err != nil {
  50. fmt.Println(tools.NowTime() + err.Error())
  51. return "", err
  52. }
  53. */
  54. var file *xlsx.File
  55. var sheet *xlsx.Sheet
  56. var row *xlsx.Row
  57. var cell *xlsx.Cell
  58. var err error
  59. file = xlsx.NewFile()
  60. if caption != "" {
  61. if len(caption) > 31 {
  62. sheet, err = file.AddSheet(caption[0:31])
  63. } else {
  64. sheet, err = file.AddSheet(caption)
  65. }
  66. } else {
  67. sheet, err = file.AddSheet("Sheet1")
  68. }
  69. if err != nil {
  70. fmt.Printf(tools.NowTime() + err.Error())
  71. return "", err
  72. }
  73. if len(cols) == 0 {
  74. //未指定导出列时,导出所有列且中文名与列表相同
  75. if len(datalist) == 0 {
  76. return "", errors.New("没有数据可导出")
  77. }
  78. for k, _ := range datalist[0] {
  79. cols = append(cols, k)
  80. colnames = append(colnames, k)
  81. }
  82. }
  83. if caption != "" {
  84. //添加标题行
  85. row = sheet.AddRow()
  86. cell = row.AddCell()
  87. if autoNoCol {
  88. cell.HMerge = len(colnames) //合并单元格数
  89. } else {
  90. cell.HMerge = len(colnames) - 1 //合并单元格数
  91. }
  92. cell.Value = caption
  93. style := xlsx.NewStyle()
  94. style.Alignment.Horizontal = "center"
  95. cell.SetStyle(style)
  96. }
  97. //添加列头行
  98. row = sheet.AddRow()
  99. if autoNoCol {
  100. cell = row.AddCell()
  101. cell.Value = "序号"
  102. }
  103. for _, colname := range colnames {
  104. cell = row.AddCell()
  105. cell.Value = colname
  106. }
  107. //添加数据行
  108. for i, dataRow := range datalist {
  109. row = sheet.AddRow()
  110. cell = row.AddCell()
  111. cell.Value = strconv.Itoa(i + 1) // "序号"
  112. for _, datacolitem := range cols {
  113. datavalue := dataRow[datacolitem]
  114. cell = row.AddCell()
  115. if datavalue == nil {
  116. cell.Value = ""
  117. } else {
  118. cell.Value = datavalue.(string)
  119. }
  120. }
  121. }
  122. err = file.Save(excelFileName + ".xlsx")
  123. if err != nil {
  124. fmt.Printf(tools.NowTime() + err.Error())
  125. return "", err
  126. }
  127. return tmpFileName + ".xlsx", nil
  128. }
  129. func FileExist(filename string) bool {
  130. _, err := os.Lstat(filename)
  131. return !os.IsNotExist(err)
  132. }
  133. func ImportRecord(path string, title string, fieldMapping map[string]string) ([]map[string]string, error) {
  134. xlFile, err := xlsx.OpenFile(path)
  135. if err != nil {
  136. return nil, err
  137. }
  138. var sheet = xlFile.Sheets[0]
  139. var result = []map[string]string{}
  140. var fields = make(map[int]string)
  141. for i, row := range sheet.Rows {
  142. if i < 2 { //判断标题是否一致
  143. if i == 0 && title != "" {
  144. for index, cell := range row.Cells {
  145. if index == 0 && title != cell.String() {
  146. return nil, errors.New("导入文件的标题必须为[" + title + "]")
  147. }
  148. }
  149. } else if i == 1 {
  150. for index2, cell := range row.Cells {
  151. var field = strings.ReplaceAll(cell.Value, " ", "")
  152. field = strings.ReplaceAll(field, " ", "")
  153. fields[index2] = field
  154. }
  155. }
  156. continue
  157. }
  158. rowdata := map[string]string{}
  159. for j, cell := range row.Cells {
  160. var fieldName = fields[j]
  161. var val = cell.Value
  162. if val != "" {
  163. if name, ok2 := fieldMapping[fieldName]; ok2 && tools.IsEmpty(name) != "" {
  164. rowdata[name] = val
  165. }
  166. }
  167. }
  168. result = append(result, rowdata)
  169. }
  170. return result, nil
  171. }
  172. func ImpExcel(path string) (data []map[int]string, err error) {
  173. xlFile, err := xlsx.OpenFile(path)
  174. if err != nil {
  175. return nil, err
  176. }
  177. var sheet = xlFile.Sheets[0]
  178. var result = []map[int]string{}
  179. reg := regexp.MustCompile(`\r\n\t`)
  180. logger.Logger.Debug(fmt.Sprintf("当前导入文件%s数据总行数:%d", path, len(sheet.Rows)))
  181. for i, row := range sheet.Rows {
  182. if i == 0 || i == 1 {
  183. continue
  184. }
  185. rowdata := map[int]string{}
  186. //判断当前是否所有行都为空
  187. isallEmt := true
  188. for j, cell := range row.Cells {
  189. rowdata[j] = reg.ReplaceAllString(strings.Trim(cell.String(), " "), "")
  190. if rowdata[j] != "" {
  191. isallEmt = false
  192. }
  193. }
  194. if isallEmt {
  195. //空行直接跳过
  196. continue
  197. }
  198. result = append(result, rowdata)
  199. }
  200. //tools.Log(result)
  201. return result, nil
  202. }
  203. func ImpCsv(path string, opts ...map[string]string) (data []map[int]string, err error) {
  204. fileHanlder, err := os.Open(path)
  205. if err != nil {
  206. return nil, err
  207. }
  208. defer fileHanlder.Close()
  209. reader := csv.NewReader(fileHanlder)
  210. if reader == nil {
  211. return nil, errors.New("文件读取失败!")
  212. }
  213. if opts != nil {
  214. p1 := opts[0]
  215. if separator, has := p1["separator"]; has {
  216. reader.Comma = []rune(separator)[0]
  217. }
  218. }
  219. reader.TrimLeadingSpace = true
  220. rowindex := 0
  221. var csvData = []map[int]string{}
  222. errList := []string{}
  223. for {
  224. txt, readerr := reader.Read()
  225. if readerr == io.EOF {
  226. break
  227. }
  228. if readerr != nil {
  229. rowindex++
  230. tools.Log(readerr)
  231. errList = append(errList, readerr.Error())
  232. continue
  233. }
  234. reg := regexp.MustCompile(`\r\n\t`)
  235. if rowindex == 0 {
  236. rowindex++
  237. continue
  238. }
  239. rowdata := map[int]string{}
  240. for j, cell := range txt {
  241. rowdata[j] = reg.ReplaceAllString(strings.Trim(cell, " "), "")
  242. }
  243. csvData = append(csvData, rowdata)
  244. rowindex++
  245. }
  246. if len(errList) > 0 {
  247. errstr, _ := json.Marshal(errList)
  248. return nil, errors.New(string(errstr))
  249. }
  250. return csvData, nil
  251. }