文档:https://xuri.me/excelize/zh-hans/cell.html?q=
读取本地文件与文件流:https://blog.csdn.net/qq_41119959/article/details/122128547
excel文件流批量插入实例
const (ExcelTitle_Phone = "手机号"ExcelTitle_Name = "姓名"ExcelTitle_Place = "位置")func CreateInBatches(devId int, file *multipart.FileHeader) error {var (wg sync.WaitGroup)// 1.处理参数// 2.为文件提供阅读器(将保存在内存中)excelFile, err := file.Open()if err != nil {return err}// 3.流式读取(默认读取第一个sheet),返回所有的单元格内容rows, err := utils.ReadExcelFile(excelFile)if err != nil {return err}// 4.初始化一个map// 存放excel的对应内容及其索引,例如 手机号:0,代表第一列为手机号excelMap := make(map[string]int)// 从excel中取出所有的标题及其索引for i, key := range rows[0] {excelMap[key] = i}// 判断标题除外的数据有多少行valuelen := len(rows[1:])// 每一千行为一批次,向上取整batch := int(math.Ceil(float64(valuelen) / float64(1000)))// 初始化一个map,记录每个批次的索引及其数据量batchMap := make(map[int]int)for i := 0; i < batch; i++ {// 记录每一个批次对应的数据界限,例如 batchMap[0] = 1000 batchMap[1] = 2000// 如果不足1000条就以具体的行数valuelen为底线if batch == 1 || i == batch-1 {// <= 1000 行数据 || 例如 5290 中的 290batchMap[i] = valuelen} else {// > 1000 行数据batchMap[i] = (i + 1) * 1000}wg.Add(1)go func(i int, batchMap map[int]int) {defer wg.Done()var userScheduleList []schedule.UserSchedule// 5.从excel中取出指定范围的所有的值// 每次循环起点也需要变化,第一次为0,后面就是上一次的界限batchMap[i-1]// 因为go没有三元表达式,用这个代替startIndex := map[bool]int{true: 0, false: batchMap[i-1]}[i == 0]// 因为切片[1:n]只能取到[1,n),所以需要给 batchMap[i]+1for _, row := range rows[1+startIndex : batchMap[i]+1] {user := schedule.UserSchedule{// 从索引中取到各个标题对应的值PhoneNum: row[excelMap[ExcelTitle_Phone]],Name: row[excelMap[ExcelTitle_Name]],Place: row[excelMap[ExcelTitle_Place]],DevId: &devId,}userScheduleList = append(userScheduleList, user)}// 6.做数据库的批量插入操作// 创建dbdb := global.GVA_DB.Model(&schedule.UserSchedule{})// 每次限制批量插入1000条if err = db.CreateInBatches(userScheduleList, 1000).Error; err != nil {// handle logreturn}}(i,batchMap)}wg.Wait()if err != nil {return err}return nil}
ReadExcelFile
func ReadExcelFile(file File, tableName ...string) ([][]string, error) {f, err := excelize.OpenReader(file)if err != nil {return nil, err}//默认读取第一个firstSheet := ""if len(tableName) > 0 {firstSheet = tableName[0]} else {firstSheet = f.GetSheetName(0)}rows, err := f.GetRows(firstSheet)return rows, err}
