core/tools/tools.go

104 lines
2.9 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package tools
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
}
sort.Slice(questions, func(i, j int) bool {
return questions[i].Page > questions[j].Page
})
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
}