update and paralele optimizated

This commit is contained in:
Pavel 2024-03-27 00:19:35 +03:00
parent 49eda08d0a
commit 3a3ef6cb48

@ -1,6 +1,7 @@
package tools package tools
import ( import (
"fmt"
"github.com/xuri/excelize/v2" "github.com/xuri/excelize/v2"
_ "image/gif" _ "image/gif"
_ "image/jpeg" _ "image/jpeg"
@ -15,6 +16,7 @@ import (
"sort" "sort"
"strconv" "strconv"
"strings" "strings"
"sync"
) )
const ( const (
@ -53,7 +55,6 @@ func WriteDataToExcel(buffer io.Writer, questions []model.Question, answers []mo
headers = append(headers, "Результат") headers = append(headers, "Результат")
// добавляем заголовки в первую строку
for col, header := range headers { for col, header := range headers {
cell := ToAlphaString(col+1) + "1" cell := ToAlphaString(col+1) + "1"
if err := file.SetCellValue(sheet, cell, header); err != nil { if err := file.SetCellValue(sheet, cell, header); err != nil {
@ -61,6 +62,10 @@ func WriteDataToExcel(buffer io.Writer, questions []model.Question, answers []mo
} }
} }
sort.Slice(answers, func(i, j int) bool {
return answers[i].QuestionId < answers[j].QuestionId
})
// мапа для хранения обычных ответов респондентов // мапа для хранения обычных ответов респондентов
standart := make(map[string][]model.Answer) standart := make(map[string][]model.Answer)
@ -76,65 +81,67 @@ func WriteDataToExcel(buffer io.Writer, questions []model.Question, answers []mo
} }
} }
// записываем данные в файл processSession := func(session string, response []model.Answer, row int) {
row := 2 defer func() {
for session, _ := range results { if r := recover(); r != nil {
response := standart[session] fmt.Println("Recovered from panic:", r)
}
}()
if err := file.SetCellValue(sheet, "A"+strconv.Itoa(row), results[session].Content); err != nil { if err := file.SetCellValue(sheet, "A"+strconv.Itoa(row), results[session].Content); err != nil {
return err fmt.Println(err.Error())
} }
count := 2 count := 2
for _, q := range questions { for _, q := range questions {
if !q.Deleted && q.Type != model.TypeResult { 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) index := binarySearch(response, q.Id)
if index != -1 { if index != -1 {
cell := ToAlphaString(count) + strconv.Itoa(row) cell := ToAlphaString(count) + strconv.Itoa(row)
typeMap := FileSearch(response[index].Content) tipe := FileSearch(response[index].Content)
noAccept := make(map[string]struct{}) noAccept := make(map[string]struct{})
todoMap := make(map[string]string) todoMap := make(map[string]string)
for _, tipe := range typeMap { if tipe != "Text" && q.Type == model.TypeImages || q.Type == model.TypeVarImages {
if tipe != "Text" && q.Type == model.TypeImages || q.Type == model.TypeVarImages { urle := ExtractImageURL(response[index].Content)
urle := ExtractImageURL(response[index].Content) urlData := strings.Split(urle, " ")
urlData := strings.Split(urle, " ") if len(urlData) == 1 {
for _, k := range urlData { u, err := url.Parse(urle)
u, err := url.Parse(k) if err == nil && u.Scheme != "" && u.Host != "" {
if err == nil && u.Scheme != "" && u.Host != "" { picture, err := downloadImage(urle)
picture, err := downloadImage(k) if err != nil {
if err != nil { fmt.Println(err.Error())
return err
}
file.SetColWidth(sheet, ToAlphaString(count), ToAlphaString(count), 50)
file.SetRowHeight(sheet, row, 150)
if err := file.AddPictureFromBytes(sheet, cell, picture); err != nil {
return err
}
noAccept[response[index].Content] = struct{}{}
} }
file.SetColWidth(sheet, ToAlphaString(count), ToAlphaString(count), 50)
file.SetRowHeight(sheet, row, 150)
if err := file.AddPictureFromBytes(sheet, cell, picture); err != nil {
fmt.Println(err.Error())
}
noAccept[response[index].Content] = struct{}{}
} else {
todoMap[response[index].Content] = cell
} }
} else if tipe != "Text" && q.Type == model.TypeFile {
urle := ExtractImageURL(response[index].Content)
display, tooltip := urle, urle
if err := file.SetCellValue(sheet, cell, response[index].Content); err != nil {
return err
}
if err := file.SetCellHyperLink(sheet, cell, urle, "External", excelize.HyperlinkOpts{
Display: &display,
Tooltip: &tooltip,
}); err != nil {
return err
}
noAccept[response[index].Content] = struct{}{}
} else { } else {
todoMap[response[index].Content] = cell todoMap[response[index].Content] = cell
} }
} else if tipe != "Text" && q.Type == model.TypeFile {
urle := ExtractImageURL(response[index].Content)
display, tooltip := urle, urle
if err := file.SetCellValue(sheet, cell, response[index].Content); err != nil {
fmt.Println(err.Error())
}
if err := file.SetCellHyperLink(sheet, cell, urle, "External", excelize.HyperlinkOpts{
Display: &display,
Tooltip: &tooltip,
}); err != nil {
fmt.Println(err.Error())
}
noAccept[response[index].Content] = struct{}{}
} else {
todoMap[response[index].Content] = cell
} }
for cnt, cel := range todoMap { for cnt, cel := range todoMap {
if _, ok := noAccept[cnt]; !ok { if _, ok := noAccept[cnt]; !ok {
if err := file.SetCellValue(sheet, cel, cnt); err != nil { if err := file.SetCellValue(sheet, cel, cnt); err != nil {
return err fmt.Println(err.Error())
} }
} }
} }
@ -142,7 +149,7 @@ func WriteDataToExcel(buffer io.Writer, questions []model.Question, answers []mo
} else { } else {
cell := ToAlphaString(count) + strconv.Itoa(row) cell := ToAlphaString(count) + strconv.Itoa(row)
if err := file.SetCellValue(sheet, cell, "-"); err != nil { if err := file.SetCellValue(sheet, cell, "-"); err != nil {
return err fmt.Println(err.Error())
} }
} }
count++ count++
@ -150,12 +157,22 @@ func WriteDataToExcel(buffer io.Writer, questions []model.Question, answers []mo
} }
cell := ToAlphaString(len(headers)) + strconv.Itoa(row) cell := ToAlphaString(len(headers)) + strconv.Itoa(row)
if err := file.SetCellValue(sheet, cell, mapQueRes[results[session].QuestionId]); err != nil { if err := file.SetCellValue(sheet, cell, mapQueRes[results[session].QuestionId]); err != nil {
return err fmt.Println(err.Error())
} }
row++
} }
// cохраняем данные в буфер row := 2
var wg sync.WaitGroup
for session, _ := range results {
wg.Add(1)
go func(session string, response []model.Answer, row int) {
defer wg.Done()
processSession(session, standart[session], row)
}(session, standart[session], row)
row++
}
wg.Wait()
if err := file.Write(buffer); err != nil { if err := file.Write(buffer); err != nil {
return err return err
} }
@ -179,27 +196,20 @@ func binarySearch(answers []model.Answer, questionID uint64) int {
return -1 return -1
} }
func FileSearch(content string) map[string]string { func FileSearch(content string) string {
types := make(map[string]string) if strings.Contains(content, bucketImages) {
return FileType(content)
words := strings.Fields(content) } else if strings.Contains(content, bucketFonts) {
for _, word := range words { return FileType(content)
if strings.Contains(word, bucketImages) { } else if strings.Contains(content, bucketScripts) {
types[word] = FileType(word) return FileType(content)
} else if strings.Contains(word, bucketFonts) { } else if strings.Contains(content, bucketStyle) {
types[word] = FileType(word) return FileType(content)
} else if strings.Contains(word, bucketScripts) { } else if strings.Contains(content, bucketAnswers) {
types[word] = FileType(word) return FileType(content)
} else if strings.Contains(word, bucketStyle) {
types[word] = FileType(word)
} else if strings.Contains(word, bucketAnswers) {
types[word] = FileType(word)
} else {
types[word] = "Text"
}
} }
return types return "Text"
} }
func FileType(filename string) string { func FileType(filename string) string {
@ -273,3 +283,141 @@ func ExtractImageURL(htmlContent string) string {
} }
return htmlContent return htmlContent
} }
//func WriteDataToExcel(buffer io.Writer, questions []model.Question, answers []model.Answer) error {
// file := excelize.NewFile()
// sheet := "Sheet1"
//
// _, err := file.NewSheet(sheet)
// 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, "Результат")
//
// // добавляем заголовки в первую строку
// for col, header := range headers {
// cell := ToAlphaString(col+1) + "1"
// if err := file.SetCellValue(sheet, cell, header); err != nil {
// return err
// }
// }
//
// // мапа для хранения обычных ответов респондентов
// 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)
// }
// }
//
// // записываем данные в файл
// row := 2
// for session, _ := range results {
// response := standart[session]
// if err := file.SetCellValue(sheet, "A"+strconv.Itoa(row), results[session].Content); err != nil {
// return err
// }
// count := 2
// 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 {
// cell := ToAlphaString(count) + strconv.Itoa(row)
// typeMap := FileSearch(response[index].Content)
// noAccept := make(map[string]struct{})
// todoMap := make(map[string]string)
// for _, tipe := range typeMap {
// if tipe != "Text" && q.Type == model.TypeImages || q.Type == model.TypeVarImages {
// urle := ExtractImageURL(response[index].Content)
// urlData := strings.Split(urle, " ")
// for _, k := range urlData {
// u, err := url.Parse(k)
// if err == nil && u.Scheme != "" && u.Host != "" {
// picture, err := downloadImage(k)
// if err != nil {
// return err
// }
// file.SetColWidth(sheet, ToAlphaString(count), ToAlphaString(count), 50)
// file.SetRowHeight(sheet, row, 150)
// if err := file.AddPictureFromBytes(sheet, cell, picture); err != nil {
// return err
// }
// noAccept[response[index].Content] = struct{}{}
// }
// }
// } else if tipe != "Text" && q.Type == model.TypeFile {
// urle := ExtractImageURL(response[index].Content)
// display, tooltip := urle, urle
// if err := file.SetCellValue(sheet, cell, response[index].Content); err != nil {
// return err
// }
// if err := file.SetCellHyperLink(sheet, cell, urle, "External", excelize.HyperlinkOpts{
// Display: &display,
// Tooltip: &tooltip,
// }); err != nil {
// return err
// }
// noAccept[response[index].Content] = struct{}{}
// } else {
// todoMap[response[index].Content] = cell
// }
// }
// for cnt, cel := range todoMap {
// if _, ok := noAccept[cnt]; !ok {
// if err := file.SetCellValue(sheet, cel, cnt); err != nil {
// return err
// }
// }
// }
//
// } else {
// cell := ToAlphaString(count) + strconv.Itoa(row)
// if err := file.SetCellValue(sheet, cell, "-"); err != nil {
// return err
// }
// }
// count++
// }
// }
// cell := ToAlphaString(len(headers)) + strconv.Itoa(row)
// if err := file.SetCellValue(sheet, cell, mapQueRes[results[session].QuestionId]); err != nil {
// return err
// }
// row++
// }
//
// // cохраняем данные в буфер
// if err := file.Write(buffer); err != nil {
// return err
// }
//
// return nil
//}