2024-03-13 16:57:12 +00:00
|
|
|
|
package tools
|
2024-02-19 17:48:04 +00:00
|
|
|
|
|
|
|
|
|
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
|
|
|
|
|
}
|