文档:https://xuri.me/excelize/zh-hans/cell.html?q=
读取本地文件与文件流:https://blog.csdn.net/qq_41119959/article/details/122128547

excel文件流批量插入实例

  1. const (
  2. ExcelTitle_Phone = "手机号"
  3. ExcelTitle_Name = "姓名"
  4. ExcelTitle_Place = "位置"
  5. )
  6. func CreateInBatches(devId int, file *multipart.FileHeader) error {
  7. var (
  8. wg sync.WaitGroup
  9. )
  10. // 1.处理参数
  11. // 2.为文件提供阅读器(将保存在内存中)
  12. excelFile, err := file.Open()
  13. if err != nil {
  14. return err
  15. }
  16. // 3.流式读取(默认读取第一个sheet),返回所有的单元格内容
  17. rows, err := utils.ReadExcelFile(excelFile)
  18. if err != nil {
  19. return err
  20. }
  21. // 4.初始化一个map
  22. // 存放excel的对应内容及其索引,例如 手机号:0,代表第一列为手机号
  23. excelMap := make(map[string]int)
  24. // 从excel中取出所有的标题及其索引
  25. for i, key := range rows[0] {
  26. excelMap[key] = i
  27. }
  28. // 判断标题除外的数据有多少行
  29. valuelen := len(rows[1:])
  30. // 每一千行为一批次,向上取整
  31. batch := int(math.Ceil(float64(valuelen) / float64(1000)))
  32. // 初始化一个map,记录每个批次的索引及其数据量
  33. batchMap := make(map[int]int)
  34. for i := 0; i < batch; i++ {
  35. // 记录每一个批次对应的数据界限,例如 batchMap[0] = 1000 batchMap[1] = 2000
  36. // 如果不足1000条就以具体的行数valuelen为底线
  37. if batch == 1 || i == batch-1 {
  38. // <= 1000 行数据 || 例如 5290 中的 290
  39. batchMap[i] = valuelen
  40. } else {
  41. // > 1000 行数据
  42. batchMap[i] = (i + 1) * 1000
  43. }
  44. wg.Add(1)
  45. go func(i int, batchMap map[int]int) {
  46. defer wg.Done()
  47. var userScheduleList []schedule.UserSchedule
  48. // 5.从excel中取出指定范围的所有的值
  49. // 每次循环起点也需要变化,第一次为0,后面就是上一次的界限batchMap[i-1]
  50. // 因为go没有三元表达式,用这个代替
  51. startIndex := map[bool]int{true: 0, false: batchMap[i-1]}[i == 0]
  52. // 因为切片[1:n]只能取到[1,n),所以需要给 batchMap[i]+1
  53. for _, row := range rows[1+startIndex : batchMap[i]+1] {
  54. user := schedule.UserSchedule{
  55. // 从索引中取到各个标题对应的值
  56. PhoneNum: row[excelMap[ExcelTitle_Phone]],
  57. Name: row[excelMap[ExcelTitle_Name]],
  58. Place: row[excelMap[ExcelTitle_Place]],
  59. DevId: &devId,
  60. }
  61. userScheduleList = append(userScheduleList, user)
  62. }
  63. // 6.做数据库的批量插入操作
  64. // 创建db
  65. db := global.GVA_DB.Model(&schedule.UserSchedule{})
  66. // 每次限制批量插入1000条
  67. if err = db.CreateInBatches(userScheduleList, 1000).Error; err != nil {
  68. // handle log
  69. return
  70. }
  71. }(i,batchMap)
  72. }
  73. wg.Wait()
  74. if err != nil {
  75. return err
  76. }
  77. return nil
  78. }

ReadExcelFile

  1. func ReadExcelFile(file File, tableName ...string) ([][]string, error) {
  2. f, err := excelize.OpenReader(file)
  3. if err != nil {
  4. return nil, err
  5. }
  6. //默认读取第一个
  7. firstSheet := ""
  8. if len(tableName) > 0 {
  9. firstSheet = tableName[0]
  10. } else {
  11. firstSheet = f.GetSheetName(0)
  12. }
  13. rows, err := f.GetRows(firstSheet)
  14. return rows, err
  15. }