diff --git a/SurveyLib.Core/Tools/IDataExporter.cs b/SurveyLib.Core/Tools/IDataExporter.cs new file mode 100644 index 0000000..9de4e30 --- /dev/null +++ b/SurveyLib.Core/Tools/IDataExporter.cs @@ -0,0 +1,6 @@ +namespace SurveyLib.Core.Tools; + +public interface IDataExporter +{ + Task ExportDataBySurveyIdAsync(int surveyId); +} \ No newline at end of file diff --git a/SurveyLib.Tools/SurveyLib.Tools.csproj b/SurveyLib.Tools/SurveyLib.Tools.csproj new file mode 100644 index 0000000..ed940b2 --- /dev/null +++ b/SurveyLib.Tools/SurveyLib.Tools.csproj @@ -0,0 +1,17 @@ + + + + net8.0 + enable + enable + + + + + + + + + + + diff --git a/SurveyLib.Tools/Tools/TableExporter.cs b/SurveyLib.Tools/Tools/TableExporter.cs new file mode 100644 index 0000000..50bb56f --- /dev/null +++ b/SurveyLib.Tools/Tools/TableExporter.cs @@ -0,0 +1,73 @@ +using ClosedXML.Excel; +using SurveyLib.Core.Services; +using SurveyLib.Core.Tools; + +namespace SurveyLib.Tools.Tools; + +public class TableExporter : IDataExporter +{ + private readonly ISurveyService _surveyService; + private readonly IQuestionService _questionService; + private readonly ICompletionService _completionService; + private readonly IAnswerService _answerService; + + public TableExporter(ISurveyService surveyService, IQuestionService questionService, + ICompletionService completionService, IAnswerService answerService) + { + _surveyService = surveyService; + _questionService = questionService; + _completionService = completionService; + _answerService = answerService; + } + + public async Task ExportDataBySurveyIdAsync(int surveyId) + { + var survey = await _surveyService.GetSurveyAsync(surveyId); + var questions = await _questionService.GetQuestionsBySurveyIdAsync(surveyId); + var completions = await _completionService.GetCompletionsBySurveyIdAsync(surveyId); + + using var workbook = new XLWorkbook(); + var ws = workbook.Worksheets.Add(survey.Title); + ws.Cell(1, 1).Value = "Title"; + ws.Cell(1, 2).Value = survey.Title; + + ws.Cell(2, 1).Value = "Description"; + ws.Cell(2, 2).Value = survey.Description; + + ws.Cell(3, 1).Value = "Export issued at"; + ws.Cell(3, 2).Value = DateTime.UtcNow; + + ws.Cell(4, 1).Value = "Completed By"; + ws.Cell(4, 2).Value = "Finished At"; + + var column = 3; + foreach (var question in questions) + { + ws.Cell(4, column).Value = question.Title; + column++; + } + + var row = 5; + foreach (var completion in completions) + { + ws.Cell(row, 1).Value = completion.CompletedBy?.ToString() ?? "Unknown"; + ws.Cell(row, 2).Value = completion.FinishedAt; + column = 3; + var answers = await _answerService.GetAnswersByCompletionIdAsync(completion.Id); + var answersGroupedByQuestion = answers.GroupBy(a => a.QuestionId); + foreach (var questionAnswers in answersGroupedByQuestion) + { + ws.Cell(row, column).Value = string.Join("; ", questionAnswers.Select(a => a.AnswerText)); + column++; + } + + row++; + } + + ws.Columns().AdjustToContents(); + + using var stream = new MemoryStream(); + workbook.SaveAs(stream); + return stream.ToArray(); + } +} \ No newline at end of file diff --git a/SurveyLib.sln b/SurveyLib.sln index 46c7c02..447d250 100644 --- a/SurveyLib.sln +++ b/SurveyLib.sln @@ -6,6 +6,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SurveyLib.Infrastructure.EF EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SurveyLib.Services", "SurveyLib.Services\SurveyLib.Services.csproj", "{C57F4551-A397-45AB-8FF6-2C6400317CC6}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SurveyLib.Tools", "SurveyLib.Tools\SurveyLib.Tools.csproj", "{43E14A39-697E-4550-804F-FF937946F7E3}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -24,5 +26,9 @@ Global {C57F4551-A397-45AB-8FF6-2C6400317CC6}.Debug|Any CPU.Build.0 = Debug|Any CPU {C57F4551-A397-45AB-8FF6-2C6400317CC6}.Release|Any CPU.ActiveCfg = Release|Any CPU {C57F4551-A397-45AB-8FF6-2C6400317CC6}.Release|Any CPU.Build.0 = Release|Any CPU + {43E14A39-697E-4550-804F-FF937946F7E3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {43E14A39-697E-4550-804F-FF937946F7E3}.Debug|Any CPU.Build.0 = Debug|Any CPU + {43E14A39-697E-4550-804F-FF937946F7E3}.Release|Any CPU.ActiveCfg = Release|Any CPU + {43E14A39-697E-4550-804F-FF937946F7E3}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection EndGlobal