package xlsx import ( "fmt" "os" "strings" "sync" "airlines/pkg/airports" "airlines/pkg/model" "github.com/schollz/progressbar/v3" "github.com/xuri/excelize/v2" ) func UnmarshallXlsxFile(fname string) ([]Ticket, error) { var err error f, err := excelize.OpenFile(fname) if err != nil { return nil, err } defer func() { if err = f.Close(); err != nil { fmt.Println(err) } }() get := func(sheet, cell string) (string, error) { v, err := f.GetCellValue(sheet, cell) if err != nil { return "", fmt.Errorf("%s %s: %w", sheet, cell, err) } v = strings.Trim(v, " `'\"") return v, nil } sheetMap := f.GetSheetMap() tickets := make([]Ticket, 0, len(sheetMap)) for _, sheet := range sheetMap { t := Ticket{} t.Sheet = sheet t.Passenger, err = get(sheet, "B3") if err != nil { return nil, err } t.Title, err = get(sheet, "A3") if err != nil { return nil, err } t.FlightNumber, err = get(sheet, "A5") if err != nil { return nil, err } t.FromCity, err = get(sheet, "D5") if err != nil { return nil, err } t.ToCity, err = get(sheet, "H5") if err != nil { return nil, err } t.FromAirport, err = get(sheet, "D7") if err != nil { return nil, err } t.ToAirport, err = get(sheet, "H7") if err != nil { return nil, err } t.FlightDate, err = get(sheet, "A9") if err != nil { return nil, err } t.FlightTime, err = get(sheet, "C9") if err != nil { return nil, err } t.PNR, err = get(sheet, "B13") if err != nil { return nil, err } t.Card, err = get(sheet, "F3") if err != nil { return nil, err } t.TicketNumber, err = get(sheet, "E13") if err != nil { return nil, err } ap, _ := airports.LookupIATA(t.FromAirport) t.FromCountry = ap.Country t.FromCoords.Lat = ap.Latitude t.FromCoords.Long = ap.Longitude ap, _ = airports.LookupIATA(t.ToAirport) t.ToCountry = ap.Country t.ToCoords.Lat = ap.Latitude t.ToCoords.Long = ap.Longitude tickets = append(tickets, t) } return tickets, nil } func UnmarshallXlsxFiles(baseDir string) ([]Ticket, error) { tickets := make([]Ticket, 0) items, err := os.ReadDir(baseDir) if err != nil { panic(err) } bar := progressbar.Default(int64(len(items)), "unmarshalling xlsx") var mu sync.Mutex var wg sync.WaitGroup sem := make(chan struct{}, 8) for _, item := range items { if !item.IsDir() { wg.Add(1) sem <- struct{}{} go func(name string) { defer func() { <-sem }() defer wg.Done() // fmt.Println("Processing file:", name) parsedTickets, err := UnmarshallXlsxFile(baseDir + name) if err != nil { panic(err) } mu.Lock() defer mu.Unlock() tickets = append(tickets, parsedTickets...) bar.Add(1) }(item.Name()) } } wg.Wait() return tickets, nil } func DumpToDb(store model.Store, tickets []Ticket) { var err error bar := progressbar.Default(int64(len(tickets)), "dumping xlsx") for _, ticket := range tickets { bar.Add(1) dbUser, _ := ticket.ToUser() dbUser, err = store.SaveUser(dbUser) if err != nil { panic(err) } dbCard, err := ticket.ToCard() if err != nil { goto processflight } dbCard.UserID = dbUser.ID _, err = store.SaveCard(dbCard) // данные говно if err != nil { fmt.Println(err) } processflight: dbFlight, _ := ticket.ToFlight() dbFlight.UserID = dbUser.ID _, err = store.SaveFlight(dbFlight) if err != nil { fmt.Println(err) } } }