package pkg import ( "github.com/tealeg/xlsx" "io" "penahub.gitlab.yandexcloud.net/backend/quiz/common.git/model" "sort" ) func WriteDataToExcel(buffer io.Writer, questions []model.Question, answers []model.Answer) error { file := xlsx.NewFile() sheet, err := file.AddSheet("Results") if err != nil { return err } headers := []string{"Данные респондента"} mapQueRes := make(map[uint64]string) for _, q := range questions { if !q.Deleted { if q.Type == model.TypeResult { mapQueRes[q.Id] = q.Title + "\n" + q.Description } else { headers = append(headers, q.Title) } } } headers = append(headers, "Результат") // добавляем заголовки в первую строку row := sheet.AddRow() for _, header := range headers { cell := row.AddCell() cell.Value = header } // мапа для хранения обычных ответов респондентов standart := make(map[string][]model.Answer) // мапа для хранения данных респондентов results := make(map[string]model.Answer) // заполняем мапу ответами и данными респондентов for _, answer := range answers { if answer.Result { // если это результат то данные респондента берутся из контента ответа по сессии results[answer.Session] = answer } else { // если это обычный ответ то добавляем его в соответствующий список ответов респондента standart[answer.Session] = append(standart[answer.Session], answer) } } // записываем данные в файл for session, _ := range results { response := standart[session] row := sheet.AddRow() row.AddCell().Value = results[session].Content // данные респондента for _, q := range questions { if !q.Deleted && q.Type != model.TypeResult { sort.Slice(response, func(i, j int) bool { return response[i].QuestionId < response[j].QuestionId }) index := binarySearch(response, q.Id) if index != -1 { row.AddCell().Value = response[index].Content } else { row.AddCell().Value = "-" } } } row.AddCell().Value = mapQueRes[results[session].QuestionId] } // cохраняем данные в буфер err = file.Write(buffer) if err != nil { return err } return nil } func binarySearch(answers []model.Answer, questionID uint64) int { left := 0 right := len(answers) - 1 for left <= right { mid := left + (right-left)/2 if answers[mid].QuestionId == questionID { return mid } else if answers[mid].QuestionId < questionID { left = mid + 1 } else { right = mid - 1 } } return -1 }