본문 바로가기
Spring

엑셀 업로드

by e-pd 2020. 5. 31.
icon : www.flaticon.com/kr/authors/pixel-perfect

 

 

필요한 의존성 주입 (버젼은 maven centeral에서 적절하게)

나는 타임리프를 추가적으로 사용했다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
 <dependency>
    <groupId>commons-fileupload</groupId>
    <artifactId>commons-fileupload</artifactId>
    <version>1.3.1</version>
</dependency>
<dependency>
    <groupId>commons-io</groupId>
    <artifactId>commons-io</artifactId>
    <version>2.4</version>
</dependency>
<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi-ooxml</artifactId>
    <version>3.17</version>
</dependency>
cs

 

화면에서는 jquery를 사용했다. 단순 업로드만 할꺼면 필요없다.

화면에서는 input 태그에 file 타입으로 두고

submit 처리를 한다. 하지만 버튼만으로 업로드를 해야한다면?

1
2
3
4
5
<form action="" th:action="@{'/upload'}" id="upload" method="post"
                          enctype=multipart/form-data>
    <input type="hidden" th:name="${_csrf.parameterName}" th:value="${_csrf.token}">
    <input id='file' type='file' th:name="file" hidden/>
</form>
cs

3번 라인의 spring security csrf때문에 넣은거라 필요없다면 생략한다.

 

1
 <button type="button" id="excelUpload">upload</button>
cs

 

이제 스크립트에서 작업을 해준다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
<script>
    
    $(function() {
       // 엑셀 업로드 버튼을 클릭하면
// hidden으로 숨겨둔 input file을 클릭
        $("#excelUpload").click(function(e) {
           e.preventDefault();
            $("#file").click();
        });    
 
       // form의 값이 변경 되었으면 excel전송
        $("#upload").change(function(e) {
            e.preventDefault();
            excelSubmit();
        });            
    });
 
};
 
var excelSubmit = function () {
    var form = $('#upload')[0];
    var formData = new FormData(form);

// 파일을 비동기로 전송한다.
    $.ajax({
        url: '/upload.do',
        method: 'POST',
        enctype: 'multipart/form-data',
        data:formData,
        processData: false,
        contentType: false,
        cache: false,
 
        success: function (resp) {
           alert("upload ok");
        }
    });
}
 
    
</script>
cs
 
 
 

 

1
2
3
4
5
@PostMapping(value="/upload")
    public String uploadFile(@RequestParam("file") MultipartFile multipartFiles) {
  save(multipartFiles);
....
..
 
 
cs

컨트롤러에서 multipartfile을 받으면 된다.

 

1
2
3
4
5
6
7
8
9
10
public void save(MultipartFile multipartFiles) {
        String extension = FilenameUtils.getExtension(multipartFiles.getOriginalFilename());
 
        if (extension.equalsIgnoreCase("xls"||
                extension.equalsIgnoreCase("xlsx")) {
            return readData(multipartFiles);
        } else {
            throw new IllegalArgumentException("엑셀이 아닙니다.");
        }
}
cs

업로드 파일이 엑셀 파일인지 파일명 체크를 한다. 파일 이름만 바꾼건지 체크는 생략.

1
2
3
4
5
6
7
8
9
10
  private void readData(MultipartFile file) {
        Workbook workBook = getWorkBook(file);
        Sheet sheet = workBook.getSheetAt(0);
        Iterator<Row> rows = sheet.iterator();
        rows.next();
 
        while (rows.hasNext()) {
            Row row = rows.next();
 
            if (row.getCell(0).getCellTypeEnum() == CellType.STRING) {
cs

2번 라인에서 엑셀 시트로 변환을 해서 읽어와야한다.

5번 라인의 rows.next를 한번 해준이유는 엑셀에 첫줄이 컬럼명이라는 가정하에 작성했다.


엑셀 처리를 하기전 파일을 읽을때
1
2
3
4
5
6
7
8
9
private Workbook getWorkBook(MultipartFile file) {
        Workbook workbook = null;
        try {
            workbook = WorkbookFactory.create(file.getInputStream());
        } catch (Exception e) {
            throw new IllegalArgumentException();
        }
        return workbook;
}
cs

WorkbookFactory를 사용한다. 안그러면 xlsx, xls 구분해서 XSSFWorkbook, HSSFWorkbook개발을

해야하는데 비추하고싶다.

 

읽는 엑셀의 값이 숫자라면 

CellType.NUMERIC를 쓰면된다.

 

 

엑셀을 읽고나서 db저장을 하든 뭔가 하고싶은 로직을 쓰면된다.

 

'Spring' 카테고리의 다른 글

Parameterized Test를 이용해서 여러 값 검증하기  (0) 2021.01.16
Component Scan  (0) 2020.08.15
Tiles 설정  (0) 2019.12.11
초기설정 pom.xml  (0) 2019.12.11
Swagger  (0) 2019.10.06