Excel to Elasticsearch(1)

P_Sangsu·2021년 7월 8일
0

입사 첫 과제
Maven Project (elasticsearch와 Local data (Excel) 연동시키기)

Develop Environment Setting

  • JDK 1.8
  • Eclipse 201912
  • Tomcat v8.0
  • maven
  • mySQL
  • elasticsearch v6.8.6

Project Step

Step 1. Spring Maven 개발환경 설정

여기서 생긴 질문

"왜 Maven Project로 하라고 했는가?"
=> elasticsearch library를 pom.xml을 이용해 편하게 다운로드 하기 위함

	<dependency>
		<groupId>org.elasticsearch.client</groupId>
		<artifactId>elasticsearch-rest-high-level-client</artifactId>
		<version>6.8.6</version>
	</dependency>

첫 단계에서는 pom.xml에 이 dependency만 추가해 사용하면 됨

Step 2. Excel Data를 JAVA로 갖고오는 방법 생각하기

여기서 공부해야 할 점
1. Excel을 읽어올 때 어떤식으로 읽어 오는가
2. 어떻게 변형이 가능한가
3. 어떻게 담을 수 있는가

  1. Excel을 읽어올 때 어떤식으로 읽어 오는가
    => Apache POI 라이브러리 사용 (4.1.1)
    Excel data를 자바로 읽고 쓸 때 사용하는 라이브러리 라고 한다.
	<dependency>
		<groupId>org.apache.poi</groupId>
		<artifactId>poi</artifactId>
		<version>4.1.1</version>
	</dependency>

	<dependency>
		<groupId>org.apache.poi</groupId>
		<artifactId>poi-ooxml</artifactId>
		<version>4.1.1</version>
	</dependency>

	<dependency>
		<groupId>org.apache.poi</groupId>
		<artifactId>poi-ooxml-schemas</artifactId>
		<version>4.1.1</version>
	</dependency>

	<dependency>
		<groupId>org.apache.xmlbeans</groupId>
		<artifactId>xmlbeans</artifactId>
		<version>3.1.0</version>
	</dependency>
    
    
  1. 어떻게 변형이 가능한가
    => 엑셀 Sheet, Column, Row 개수에 따라 For loop가 돌며 Cell 하나 하나 Map 형태로 변형된다.
  • Row가 1개일 경우
    ({column1=cell[0][0], column2=cell[0][1], ..})

  • Row가 2개 이상일 경우
    ({column1=cell[0][0], column2=cell[0][1], ..},{column1=cell[1][0], column2=cell[1][1]}, ..)

와 비슷한 형태로 변형된다.

  1. 어떻게 담을 수 있는가
    => Excel data를 POI 라이브러리를 사용해 Java로 갖고 오면 Map 형식으로 담게 된다.
    1 row 당 1 Map 이 형성되고, 2 row 이상일 경우 ArrayList를 만들어 List에 Map을 연결해서 담아두어 사용한다.
    => Map<K, V> 에 담기는 Key와 Value는 elasticsearch에 JSON 형식으로 Field : Value 로 Mapping 되어 인덱싱한다.
try {
		FileInputStream file = new FileInputStream(
				"C:/Users/PARKSANGSU/Desktop/신입 파일/데이터 색인 연습/20210621_신입샘플데이터.xlsx");

		XSSFWorkbook workbook = new XSSFWorkbook(file); // Stream을 통해 넘어온 Excel file을 Excel Workbook에 읽어서 파싱

		int rowindex = 0;
		int columnindex = 0;

		List<String> key = new ArrayList<String>();

		List<HashMap<String, Object>> excelList = new ArrayList<HashMap<String, Object>>(); // List 형식 변수설정
		HashMap<String, Object> excelMap = new HashMap<String, Object>(); // map 형식 변수 설정, LinkedHashMap은 순서가 보장
		XSSFSheet sheet = workbook.getSheetAt(0); // 0 번째 시트를 가져온다. 만약 시트가 여러 개인 경우 for문 활용

		int rows = sheet.getPhysicalNumberOfRows(); // 행 개수 (elasticsearch 기준 document)
		for (rowindex = 0; rowindex < rows; rowindex++) {
			XSSFRow row = sheet.getRow(rowindex); // 행 read

			if (row != null) {
				int cells = row.getPhysicalNumberOfCells(); // 열 개수
				excelMap = new HashMap<String, Object>();
				for (columnindex = 0; columnindex <= cells; columnindex++) { // (elasticsearch 기준 field)
					XSSFCell cell = row.getCell(columnindex); // 열 read
					String value = ""; // 해당 셀이 공백일경우 null check
					if (cell == null)
						continue;
					else {
						switch (cell.getCellType()) { // type 별 내용 읽기
						case FORMULA:
							value = cell.getCellFormula();
							break;
						case NUMERIC:
							value = cell.getNumericCellValue() + "";
							break;
						case STRING:
							value = cell.getStringCellValue() + "";
							break;
						case BLANK:
							value = cell.getBooleanCellValue() + "";
							break;
						case ERROR:
							value = cell.getErrorCellValue() + "";
							break;
						}
					}

					// excel 첫 줄은 key 값으로 가져가고 그 이후 문서들을 담기 위함
					if (rowindex == 0) {
						key.add(value);
					} else {
						excelMap.put(key.get(columnindex), value); // 첫번 째 열 삽입
					}
				}
			}
			if (rowindex > 0) {
				excelList.add(excelMap);
			}
		}

	} catch (Exception e) {
		e.printStackTrace();
	}
}

[ERROR 발생 및 해결]

[ERROR]

  • Excel을 읽어오는 라이브러리 중 poi를 4.1.1 버전으로 사용하려면 xmlbeans는 3.1.0을 사용해야 한다. 만약 다른 버전을 사용하게 된다면 아래와 같은 오류가 발생한다.

    Apache POI 4.1.1을 사용하여 Excel 파일에서 값을 읽을 때 오류
    org.apache.poi.ooxml.POIXMLException: org.apache.logging.log4j.Logger.atTrace()Lorg/apache/logging/log4j/LogBuilder;

따라서 poi 버전와 xmlbeans의 버전을 잘 확인해야 한다.

=> excel 파일을 읽어 내용을 보여주는 소스를 코딩할 때 poi 4.0 이전 버전까지는 타입별로 내용을 읽을 때

와 같이 작성했지만 poi 4.0.X 이 후 버전부턴

와 같이 작성해줘야 한다. (XSSFCell.CELL_TYPE 삭제)
참고: https://www.python2.net/questions-674309.htm

[ERROR]

get 함수를 사용할 때 아래와 같은 오류 발생

LambdaConversionException: Invalid receiver type interface org.apache.http.Header; not a subtype of implementation type interface org.apache.http.NameValuePair

=> 해결방법

    <dependency>
        <groupId>org.apache.httpcomponents</groupId>
    	<artifactId>httpclient</artifactId>
        <version>4.5.6</version>
    </dependency>
    
    <dependency>
        <groupId>org.apache.httpcomponents</groupId>
        <artifactId>httpcore</artifactId>
        <version>4.4.10</version>
    </dependency>
    

추가 하니 정상 작동

[ERROR]

  • ERROR StatusLogger Log4j2 could not find a logging implementation
<dependencies>
	<dependency>
		<groupId>org.apache.logging.log4j</groupId>
		<artifactId>log4j-core</artifactId>
		<version>2.11.1</version>
	</dependency>


	<dependency>
		<groupId>org.apache.logging.log4j</groupId>
		<artifactId>log4j-to-slf4j</artifactId>
		<version>2.8.2</version>
	</dependency>
</dependencies>

추가하여 오류해결

profile
Wannabe Sexy Developer

0개의 댓글