Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[SAMBAD-238]-CSV 파일 읽고 질문 답변 추가 기능 #92

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -11,19 +11,27 @@
import org.apache.poi.ooxml.util.SAXHelper;
import org.apache.poi.openxml4j.exceptions.OpenXML4JException;
import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.ss.util.CellReference;
import org.apache.poi.xssf.eventusermodel.ReadOnlySharedStringsTable;
import org.apache.poi.xssf.eventusermodel.XSSFReader;
import org.apache.poi.xssf.eventusermodel.XSSFSheetXMLHandler;
import org.apache.poi.xssf.model.StylesTable;
import org.apache.poi.xssf.usermodel.XSSFComment;
import org.depromeet.sambad.moring.question.presentation.exception.ExcelReadErrorException;
import org.xml.sax.ContentHandler;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;

import lombok.Getter;

public class ExcelSheetHandler implements XSSFSheetXMLHandler.SheetContentsHandler {
private int currentCol = -1;

private final List<List<String>> rows = new ArrayList<List<String>>();
@Getter
private List<List<String>> rows = new ArrayList<List<String>>();
private final List<String> row = new ArrayList<String>();
private List<String> header = new ArrayList<String>();

public static ExcelSheetHandler readExcel(File file) throws Exception {

Expand All @@ -45,22 +53,45 @@ public static ExcelSheetHandler readExcel(File file) throws Exception {
xmlReader.parse(inputSource);
inputStream.close();
opc.close();
} catch (SAXException | OpenXML4JException | IOException | ParserConfigurationException e) {
throw new Exception(e);
} catch (ExcelReadErrorException e) {
throw new ExcelReadErrorException();
}

return sheetHandler;

}

@Override
public void startRow(int rowNum) {
public void startRow(int arg0) {
this.currentCol = -1;
}

@Override
public void endRow(int rowNum) {
public void cell(String columnName, String value, XSSFComment var3) {
int iCol = (new CellReference(columnName)).getCol();
int emptyCol = iCol - currentCol - 1;

for (int i = 0; i < emptyCol; i++) {
row.add("");
}
currentCol = iCol;
row.add(value);
}

@Override
public void cell(String cellReference, String formattedValue, XSSFComment comment) {
public void endRow(int rowNum) {
if (rowNum == 0) {
header = new ArrayList(row);
} else {
if (row.size() < header.size()) {
for (int i = row.size(); i < header.size(); i++) {
row.add("");
}
}
rows.add(new ArrayList(row));
}
row.clear();
}

}

Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,10 @@ public FileEntity getRandomProfileImage() {
return defaultFiles.get((int) (Math.random() * defaultFiles.size()));
}

public FileEntity getById(Long fileId) {
return fileRepository.findById(fileId);
}

private boolean isNotExistFile(Long fileId) {
return !fileRepository.existsById(fileId);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,19 @@
package org.depromeet.sambad.moring.question.application;

import java.io.File;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Random;

import org.depromeet.sambad.moring.common.handler.ExcelSheetHandler;
import org.depromeet.sambad.moring.file.application.FileService;
import org.depromeet.sambad.moring.file.domain.FileEntity;
import org.depromeet.sambad.moring.meeting.meeting.domain.Meeting;
import org.depromeet.sambad.moring.meeting.member.application.MeetingMemberService;
import org.depromeet.sambad.moring.meeting.member.domain.MeetingMember;
import org.depromeet.sambad.moring.question.domain.Question;
import org.depromeet.sambad.moring.question.domain.QuestionType;
import org.depromeet.sambad.moring.question.presentation.exception.NotFoundAvailableQuestionException;
import org.depromeet.sambad.moring.question.presentation.exception.NotFoundQuestionException;
import org.depromeet.sambad.moring.question.presentation.request.QuestionRequest;
Expand Down Expand Up @@ -64,4 +69,23 @@ public void saveQuestion(QuestionRequest questionRequest) {
.build();
questionRepository.save(question);
}

@Transactional
public void csvInitQuestions() throws Exception {
String filePath = "src/main/resources/moring_question_answer_mock.xlsx";
File file = new File(filePath);
ExcelSheetHandler excelSheetHandler = ExcelSheetHandler.readExcel(file);
List<List<String>> excelDatas = excelSheetHandler.getRows();

for (List<String> dataRow : excelDatas) {
FileEntity image = fileService.getById(Long.parseLong(dataRow.get(1)));
Question question = Question.builder()
.title(dataRow.get(0))
.questionImageFile(image)
.questionType(QuestionType.valueOf(dataRow.get(2)))
.answerContents(Arrays.asList(dataRow.get(3).split(",")))
.build();
questionRepository.save(question);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
public enum QuestionType {
SINGLE_CHOICE, MULTIPLE_SHORT_CHOICE, MULTIPLE_DESCRIPTIVE_CHOICE;

private static final int MIN_ANSWER_COUNT = 1;
private static final int MIN_ANSWER_COUNT = 2;
private static final int MULTI_CHOICE_MAX_ANSWER_COUNT = 9;

public static void validateAnswerCount(QuestionType questionType, int answerCount) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,8 @@ public ResponseEntity<QuestionResponse> findRandomOne(

@Operation(summary = "질문 추가", description = "새로운 질문을 등록하는 API 입니다.")
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "질문 추가 등록성공")
@ApiResponse(responseCode = "200", description = "질문 추가 등록성공"),
@ApiResponse(responseCode = "400", description = "ANSWER_COUNT_OUT_OF_RANGE"),
})
@PostMapping("/questions")
public ResponseEntity<Void> addQuestion(
Expand All @@ -90,4 +91,16 @@ public ResponseEntity<Void> addQuestion(
return ResponseEntity.ok().build();
}

@Operation(summary = "CSV 질문 및 답변 init", description = "CSV 파일을 읽어 질문과 답변을 등록하는 운영자용 API 입니다.")
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "CSV 질문 및 답변 init 성공"),
@ApiResponse(responseCode = "400", description = "ANSWER_COUNT_OUT_OF_RANGE"),
@ApiResponse(responseCode = "404", description = "EXCEL_READ_ERROR")
})
@PostMapping("/questions/csv")
public ResponseEntity<Void> csvInitQuestions() throws Exception {
questionService.csvInitQuestions();
return ResponseEntity.ok().build();
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package org.depromeet.sambad.moring.question.presentation.exception;

import static org.depromeet.sambad.moring.question.presentation.exception.QuestionExceptionCode.EXCEL_READ_ERROR;

import org.depromeet.sambad.moring.common.exception.BusinessException;

public class ExcelReadErrorException extends BusinessException {
public ExcelReadErrorException() {
super(EXCEL_READ_ERROR);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ public enum QuestionExceptionCode implements ExceptionCode {
ANSWER_COUNT_OUT_OF_RANGE(BAD_REQUEST, "답변 개수가 범위를 벗어났습니다. 2개 이상 16개 이하로 입력해주세요."),

NOT_FOUND_QUESTION(NOT_FOUND, "릴레이 질문이 존재하지 않습니다."),
EXCEL_READ_ERROR(NOT_FOUND, "엑셀 파일을 찾을 수 없거나 읽는 중 오류가 발생했습니다."),
NOT_FOUND_AVAILABLE_QUESTION(NOT_FOUND, "사용 가능한 질문이 존재하지 않습니다."),

DUPLICATE_QUESTION(CONFLICT, "이미 등록한 질문입니다."),
Expand Down
Binary file not shown.
Loading