From d750fbf236f0c59edd50167d3559d5231f7d766c Mon Sep 17 00:00:00 2001 From: Pavel Date: Tue, 23 Jul 2024 12:01:50 +0300 Subject: [PATCH] added refactored gen excel files --- tools/tools.go | 376 +++++++++++++++++-------------------------------- 1 file changed, 126 insertions(+), 250 deletions(-) diff --git a/tools/tools.go b/tools/tools.go index d921857..9628027 100644 --- a/tools/tools.go +++ b/tools/tools.go @@ -41,6 +41,36 @@ func WriteDataToExcel(buffer io.Writer, questions []model.Question, answers []mo return questions[i].Page < questions[j].Page }) + headers, mapQueRes := prepareHeaders(questions) + for col, header := range headers { + cell := ToAlphaString(col+1) + "1" + if err := file.SetCellValue(sheet, cell, header); err != nil { + return err + } + } + + sort.Slice(answers, func(i, j int) bool { + return answers[i].QuestionId < answers[j].QuestionId + }) + + standart, results := categorizeAnswers(answers) + + var wg sync.WaitGroup + row := 2 + for session := range results { + wg.Add(1) + go func(session string, response []model.Answer, row int) { + defer wg.Done() + processSession(file, sheet, session, s3Prefix, response, results, questions, mapQueRes, headers, row) + }(session, standart[session], row) + row++ + } + wg.Wait() + + return file.Write(buffer) +} + +func prepareHeaders(questions []model.Question) ([]string, map[uint64]string) { headers := []string{"Данные респондента"} mapQueRes := make(map[uint64]string) @@ -53,27 +83,14 @@ func WriteDataToExcel(buffer io.Writer, questions []model.Question, answers []mo } } } - headers = append(headers, "Результат") + return headers, mapQueRes +} - for col, header := range headers { - cell := ToAlphaString(col+1) + "1" - if err := file.SetCellValue(sheet, cell, header); err != nil { - return err - } - } - - sort.Slice(answers, func(i, j int) bool { - return answers[i].QuestionId < answers[j].QuestionId - }) - - // мапа для хранения обычных ответов респондентов +func categorizeAnswers(answers []model.Answer) (map[string][]model.Answer, map[string]model.Answer) { standart := make(map[string][]model.Answer) - - // мапа для хранения данных респондентов results := make(map[string]model.Answer) - // заполняем мапу ответами и данными респондентов for _, answer := range answers { if answer.Result { results[answer.Session] = answer @@ -81,113 +98,110 @@ func WriteDataToExcel(buffer io.Writer, questions []model.Question, answers []mo standart[answer.Session] = append(standart[answer.Session], answer) } } + return standart, results +} - processSession := func(session string, response []model.Answer, row int) { - defer func() { - if r := recover(); r != nil { - fmt.Println("Recovered from panic:", r) - } - }() - - if err := file.SetCellValue(sheet, "A"+strconv.Itoa(row), results[session].Content); err != nil { - fmt.Println(err.Error()) +func processSession(file *excelize.File, sheet, session, s3Prefix string, response []model.Answer, results map[string]model.Answer, questions []model.Question, mapQueRes map[uint64]string, headers []string, row int) { + defer func() { + if r := recover(); r != nil { + fmt.Println("Recovered from panic:", r) } - count := 2 - for _, q := range questions { - if !q.Deleted && q.Type != model.TypeResult { - index := binarySearch(response, q.Id) - if index != -1 { - cell := ToAlphaString(count) + strconv.Itoa(row) - tipe := FileSearch(response[index].Content) - noAccept := make(map[string]struct{}) - todoMap := make(map[string]string) - if tipe != "Text" && q.Type == model.TypeImages || q.Type == model.TypeVarImages { - var res model.ImageContent - err := json.Unmarshal([]byte(response[index].Content), &res) - if err != nil { - res.Image = response[index].Content - } - urle := ExtractImageURL(res.Image) - urlData := strings.Split(urle, " ") - if len(urlData) == 1 { - u, err := url.Parse(urle) - if err == nil && u.Scheme != "" && u.Host != "" { - picture, err := downloadImage(urle) - if err != nil { - fmt.Println(err.Error()) - } - 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 { - todoMap[response[index].Content] = cell - } - } else if q.Type == model.TypeFile { - urle := response[index].Content - if urle != "" && !strings.HasPrefix(urle, "https") { - urle = s3Prefix + urle - } - fmt.Println("ORRRRR", urle, s3Prefix) - display, tooltip := urle, urle - if err := file.SetCellValue(sheet, cell, urle); 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 { - if _, ok := noAccept[cnt]; !ok { - if err := file.SetCellValue(sheet, cel, cnt); err != nil { - fmt.Println(err.Error()) - } - } - } + }() - } else { - cell := ToAlphaString(count) + strconv.Itoa(row) - if err := file.SetCellValue(sheet, cell, "-"); err != nil { - fmt.Println(err.Error()) - } + if err := file.SetCellValue(sheet, "A"+strconv.Itoa(row), results[session].Content); err != nil { + fmt.Println(err.Error()) + } + count := 2 + for _, q := range questions { + if !q.Deleted && q.Type != model.TypeResult { + cell := ToAlphaString(count) + strconv.Itoa(row) + index := binarySearch(response, q.Id) + if index != -1 { + handleAnswer(file, sheet, cell, s3Prefix, response[index], q, count, row) + } else { + if err := file.SetCellValue(sheet, cell, "-"); err != nil { + fmt.Println(err.Error()) } - count++ + } + count++ + } + } + cell := ToAlphaString(len(headers)) + strconv.Itoa(row) + if err := file.SetCellValue(sheet, cell, mapQueRes[results[session].QuestionId]); err != nil { + fmt.Println(err.Error()) + } +} + +func handleAnswer(file *excelize.File, sheet, cell, s3Prefix string, answer model.Answer, question model.Question, count, row int) { + tipe := FileSearch(answer.Content) + noAccept := make(map[string]struct{}) + todoMap := make(map[string]string) + + if tipe != "Text" && question.Type == model.TypeImages || question.Type == model.TypeVarImages { + handleImage(file, sheet, cell, answer.Content, count, row, noAccept, todoMap) + } else if question.Type == model.TypeFile { + handleFile(file, sheet, cell, answer.Content, s3Prefix, noAccept) + } else { + todoMap[answer.Content] = cell + } + + for cnt, cel := range todoMap { + if _, ok := noAccept[cnt]; !ok { + if err := file.SetCellValue(sheet, cel, cnt); err != nil { + fmt.Println(err.Error()) } } - cell := ToAlphaString(len(headers)) + strconv.Itoa(row) - if err := file.SetCellValue(sheet, cell, mapQueRes[results[session].QuestionId]); err != nil { - fmt.Println(err.Error()) + } +} + +func handleImage(file *excelize.File, sheet, cell, content string, count, row int, noAccept map[string]struct{}, todoMap map[string]string) { + var res model.ImageContent + err := json.Unmarshal([]byte(content), &res) + if err != nil { + res.Image = content + } + urle := ExtractImageURL(res.Image) + urlData := strings.Split(urle, " ") + if len(urlData) == 1 { + u, err := url.Parse(urle) + if err == nil && u.Scheme != "" && u.Host != "" { + picture, err := downloadImage(urle) + if err != nil { + fmt.Println(err.Error()) + } + 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[content] = struct{}{} + } else { + todoMap[content] = cell } + } else { + todoMap[content] = cell + } +} + +func handleFile(file *excelize.File, sheet, cell, content, s3Prefix string, noAccept map[string]struct{}) { + urle := content + if urle != "" && !strings.HasPrefix(urle, "https") { + urle = s3Prefix + urle } - 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() + fmt.Println("ORRRRR", urle, s3Prefix) + display, tooltip := urle, urle - if err := file.Write(buffer); err != nil { - return err + if err := file.SetCellValue(sheet, cell, urle); err != nil { + fmt.Println(err.Error()) } - - return nil + if err := file.SetCellHyperLink(sheet, cell, urle, "External", excelize.HyperlinkOpts{ + Display: &display, + Tooltip: &tooltip, + }); err != nil { + fmt.Println(err.Error()) + } + noAccept[content] = struct{}{} } func binarySearch(answers []model.Answer, questionID uint64) int { @@ -293,141 +307,3 @@ func ExtractImageURL(htmlContent string) string { } 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 -//}