100 lines
2.8 KiB
Go
100 lines
2.8 KiB
Go
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
|
||
}
|