티스토리 뷰

엑셀파일을 업로드 해서 안에 내용을 읽어드리는 기능을 구현하고 있다.

진짜로 너무너무너무너무 어렵다.

구글링 진짜 다했는데 내가 너무 1도몰라서 내가 쓸수있게 이해시켜주는 소스가 없었다.

다들 쉽게하는거 같은데 왜나만어려워?

http://madeinjeon.tistory.com/59

1주일동안 뻘짓하다가 진짜 이 소스 아니엇음 큰일날뻔..!!

이소스에도 할말이 많은게 아 cellref 파일이 없어서 버려야하나 cellref를 맘대로 만들어야 하나

개고민했는데 아 어케 하다보니 cellref를 올려놓은 블로그가 있었다.

http://souning.tistory.com/archive/20150428

역시 구글은 모든 정답이 나와있다는게 정말 정답.



1. POM.XML 에 poi 라이브러리 추가 

1
2
3
4
5
6
7
8
9
10
11
12
 <!-- Excel Read/Write 를 위한 Dependency 추가 -->
    <dependency>
        <groupId>org.apache.poi</groupId>
        <artifactId>poi</artifactId>
        <version>3.11</version>
    </dependency>
    <dependency>
        <groupId>org.apache.poi</groupId>
        <artifactId>poi-ooxml</artifactId>
        <version>3.11</version>
    </dependency>
 
cs


2.  util 파일로 ExcilFile을 읽어 확장자를 비교하는 java 파일을 만든다.

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
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
 
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
 
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
 
public class ExcelFileType {
    /**
     * 
     * 엑셀파일을 읽어서 Workbook 객체에 리턴한다.
     * XLS와 XLSX 확장자를 비교한다.
     * 
     * @param filePath
     * @return
     * 
     */
    public static Workbook getWorkbook(String filePath) {
        
        /*
         * FileInputStream은 파일의 경로에 있는 파일을
         * 읽어서 Byte로 가져온다.
         * 
         * 파일이 존재하지 않는다면은
         * RuntimeException이 발생된다.
         */
        FileInputStream fis = null;
        try {
            fis = new FileInputStream(filePath);
        } catch (FileNotFoundException e) {
            throw new RuntimeException(e.getMessage(), e);
        }
        
        Workbook wb = null;
        
        /*
         * 파일의 확장자를 체크해서 .XLS 라면 HSSFWorkbook에
         * .XLSX라면 XSSFWorkbook에 각각 초기화 한다.
         */
        if(filePath.toUpperCase().endsWith(".XLS")) {
            try {
                wb = new HSSFWorkbook(fis);
            } catch (IOException e) {
                throw new RuntimeException(e.getMessage(), e);
            }
        }
        else if(filePath.toUpperCase().endsWith(".XLSX")) {
            try {
                wb = new XSSFWorkbook(fis);
            } catch (IOException e) {
                throw new RuntimeException(e.getMessage(), e);
            }
        }
        
        return wb;
        
    }
}
 
cs


3. Excel 파일을 읽을 때 옵션을 설정하는 java 파일을 만들어준다.

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
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
 
import java.util.ArrayList;
import java.util.List;
 
public class ExcelReadOption {
    /**
     * 엑셀파일의 경로
     */
    private String filePath;
    
    /**
     * 추출할 컬럼 명
     */
    private List<String> outputColumns;
    
    /**
     * 추출을 시작할 행 번호
     */
    private int startRow;
    
    public String getFilePath() {
        return filePath;
    }
    public void setFilePath(String filePath) {
        this.filePath = filePath;
    }
    public List<String> getOutputColumns() {
        
        List<String> temp = new ArrayList<String>();
        temp.addAll(outputColumns);
        
        return temp;
    }
    public void setOutputColumns(List<String> outputColumns) {
        
        List<String> temp = new ArrayList<String>();
        temp.addAll(outputColumns);
        
        this.outputColumns = temp;
    }
    
    public void setOutputColumns(String ... outputColumns) {
        
        if(this.outputColumns == null) {
            this.outputColumns = new ArrayList<String>();
        }
        
        for(String ouputColumn : outputColumns) {
            this.outputColumns.add(ouputColumn);
        }
    }
    
    public int getStartRow() {
        return startRow;
    }
    public void setStartRow(int startRow) {
        this.startRow = startRow;
    }
}
 
cs



4. Cell의 이름과 값을 가져오는 java 파일을 만든다.

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
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.util.CellReference;
 
public class ExcelCellRef {
    /**
     * Cell에 해당하는 Column Name을 가젼온다(A,B,C..)
     * 만약 Cell이 Null이라면 int cellIndex의 값으로
     * Column Name을 가져온다.
     * @param cell
     * @param cellIndex
     * @return
     */
    public static String getName(Cell cell, int cellIndex) {
        int cellNum = 0;
        if(cell != null) {
            cellNum = cell.getColumnIndex();
        }
        else {
            cellNum = cellIndex;
        }
        
        return CellReference.convertNumToColString(cellNum);
    }
    
    public static String getValue(Cell cell) {
        String value = "";
        
        if(cell == null) {
            value = "";
        }
        else {
            if( cell.getCellType() == Cell.CELL_TYPE_FORMULA ) {
                value = cell.getCellFormula();
            }
            else if( cell.getCellType() == Cell.CELL_TYPE_NUMERIC ) {
                value = cell.getNumericCellValue() + "";
            }
            else if( cell.getCellType() == Cell.CELL_TYPE_STRING ) {
                value = cell.getStringCellValue();
            }
            else if( cell.getCellType() == Cell.CELL_TYPE_BOOLEAN ) {
                value = cell.getBooleanCellValue() + "";
            }
            else if( cell.getCellType() == Cell.CELL_TYPE_ERROR ) {
                value = cell.getErrorCellValue() + "";
            }
            else if( cell.getCellType() == Cell.CELL_TYPE_BLANK ) {
                value = "";
            }
            else {
                value = cell.getStringCellValue();
            }
        }
        
        return value;
    }
 
}
 
cs



5. 엑셀 파일을 읽어오는 java 파일을 만든다. service에서 이걸 호출하게 된다.

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
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
 
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
 
 
 
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
 
 
 
public class ExcelRead {
     public static List<Map<StringString>> read(ExcelReadOption excelReadOption) {
            //엑셀 파일 자체
            //엑셀파일을 읽어 들인다.
            //FileType.getWorkbook() <-- 파일의 확장자에 따라서 적절하게 가져온다.
            Workbook wb = ExcelFileType.getWorkbook(excelReadOption.getFilePath());
            /**
             * 엑셀 파일에서 첫번째 시트를 가지고 온다.
             */
            Sheet sheet = wb.getSheetAt(0);
            
            System.out.println("Sheet 이름: "+ wb.getSheetName(0)); 
            System.out.println("데이터가 있는 Sheet의 수 :" + wb.getNumberOfSheets());
            /**
             * sheet에서 유효한(데이터가 있는) 행의 개수를 가져온다.
             */
            int numOfRows = sheet.getPhysicalNumberOfRows();
            int numOfCells = 0;
            
            Row row = null;
            Cell cell = null;
            
            String cellName = "";
            /**
             * 각 row마다의 값을 저장할 맵 객체
             * 저장되는 형식은 다음과 같다.
             * put("A", "이름");
             * put("B", "게임명");
             */
            Map<StringString> map = null;
            /*
             * 각 Row를 리스트에 담는다.
             * 하나의 Row를 하나의 Map으로 표현되며
             * List에는 모든 Row가 포함될 것이다.
             */
            List<Map<StringString>> result = new ArrayList<Map<StringString>>(); 
            /**
             * 각 Row만큼 반복을 한다.
             */
            for(int rowIndex = excelReadOption.getStartRow() - 1; rowIndex < numOfRows; rowIndex++) {
                /*
                 * 워크북에서 가져온 시트에서 rowIndex에 해당하는 Row를 가져온다.
                 * 하나의 Row는 여러개의 Cell을 가진다.
                 */
                row = sheet.getRow(rowIndex);
                
                if(row != null) {
                    /*
                     * 가져온 Row의 Cell의 개수를 구한다.
                     */
                    numOfCells = row.getPhysicalNumberOfCells();
                    /*
                     * 데이터를 담을 맵 객체 초기화
                     */
                    map = new HashMap<StringString>();
                    /*
                     * cell의 수 만큼 반복한다.
                     */
                    for(int cellIndex = 0; cellIndex < numOfCells; cellIndex++) {
                        /*
                         * Row에서 CellIndex에 해당하는 Cell을 가져온다.
                         */
                        cell = row.getCell(cellIndex);
                        /*
                         * 현재 Cell의 이름을 가져온다
                         * 이름의 예 : A,B,C,D,......
                         */
                        cellName = ExcelCellRef.getName(cell, cellIndex);
                        /*
                         * 추출 대상 컬럼인지 확인한다
                         * 추출 대상 컬럼이 아니라면, 
                         * for로 다시 올라간다
                         */
                        if!excelReadOption.getOutputColumns().contains(cellName) ) {
                            continue;
                        }
                        /*
                         * map객체의 Cell의 이름을 키(Key)로 데이터를 담는다.
                         */
                        map.put(cellName, ExcelCellRef.getValue(cell));
                    }
                    /*
                     * 만들어진 Map객체를 List로 넣는다.
                     */
                    result.add(map);
                    
                }
                
            }
            
            return result;
            
        }
        
        
        
//        public static void main(String[] args) {
//            
//            ExcelReadOption ro = new ExcelReadOption();
//            ro.setFilePath("D:/game.xlsx");
//            ro.setOutputColumns("A", "B");
//            ro.setStartRow(1);
//            
//            List<Map<String, String>> result = ExcelRead.read(ro);
//            
//            for(Map<String, String> map : result) {
//                System.out.println(map.get("A"));
//            }
//        }
        
      
}
 
cs


여기까지 모두 util에 들어가야 하는 파일이다.

그러니까 나는 여태 스프링 하면 controller - service 이런것만 알고 있었으니

왜 이 java 파일들이 controller 역할도 아니고 service 역할도 아니고 왜 있는건지 이해하지 못했다.

멍청이같으니라고!!


+추가 2016-09-26 

numOfCells = row.getPhysicalNumberOfCells();

이 부분이 한개의 행마다 몇개의 cell이 있는지 체크하는 부분이라고 설명이 되어있엇는데

셀 중간에 빈값이 있을때 셀의 갯수를 정확하게 가져오지 못한다.

만약 10개의 셀이 있을 때 중간 3번째 셀이 비어있다면 9개를 가져오는 것이다.

그래서 저 함수가 아닌 getLastCellNum()을 사용하여 데이터가 있는 마지막 셀의 숫자를 가지고 오게 된다.

numOfCells = row.getPhysicalNumberOfCells(); => numOfCells = row.getLastCellNum();

으로 변경해야 한다.




아무튼

이건 기본적인 파일?이고, 진짜 화면에서 엑셀파일을 첨부하고, 읽어와보도록 하는 코드를 작성하자.


나는 화면에서 버튼을 클릭하면, 모달 페이지가 뜨고, 그곳에서 파일첨부를 하도록 구현하였다.

파일 첨부하는 모달부터 적어놓겠다.

6. 파일첨부 하는 View 페이지 jsp


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<form id="excelUploadForm" name="excelUploadForm" enctype="multipart/form-data" method="post" 
                                action"${pageContext.request.contextPath}/user/excelUploadAjax">
    <div class="contents">
        <div>첨부파일은 한개만 등록 가능합니다.</div>
 
        <dl class="vm_name">
                <dt class="down w90">첨부 파일</dt>
                <dd><input id="excelFile" type="file" name="excelFile" /></dd>
        </dl>        
    </div>
            
    <div class="bottom">
        <button type="button" id="addExcelImpoartBtn" class="btn" onclick="check()" ><span>추가</span></button
    </div>
</form
cs



7. form 을 사용했다. javascript 파일

   ajaxSubmit을 사용하였다.

   success 부분은 내가 참조한 코드에 있어서 적어놓앗는데, 나는 DB insert를 구현하지 않아서 성공까지 넘어오지는 않는다. (우선은)


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
function checkFileType(filePath) {
                var fileFormat = filePath.split(".");
                if (fileFormat.indexOf("xlsx"> -1) {
                    return true;
                } else {
                    return false;
                }
 
            }
 
            function check() {
                var file = $("#excelFile").val();
                if (file == "" || file == null) {
                    alert("파일을 선택해주세요.");
                    return false;
                } else if (!checkFileType(file)) {
                    alert("엑셀 파일만 업로드 가능합니다.");
                    return false;
                }
 
                if (confirm("업로드 하시겠습니까?")) {
                    var options = {
                        success : function(data) {
                            alert("모든 데이터가 업로드 되었습니다.");
 
                        },
                        type : "POST"
                    };
                    $("#excelUploadForm").ajaxSubmit(options);
    
                }
            }
cs



8.  script 부분에서 업로드 하면 ajaxSubmit으로 controller로 넘어간다

    controller.java 파일

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
@ResponseBody
    @RequestMapping(value = "/excelUploadAjax", method = RequestMethod.POST)
    public ModelAndView excelUploadAjax(MultipartHttpServletRequest request)  throws Exception{
        MultipartFile excelFile =request.getFile("excelFile");
        System.out.println("엑셀 파일 업로드 컨트롤러");
        if(excelFile==null || excelFile.isEmpty()){
            throw new RuntimeException("엑셀파일을 선택 해 주세요.");
        }
        
        File destFile = new File("D:\\"+excelFile.getOriginalFilename());
        try{
            excelFile.transferTo(destFile);
        }catch(IllegalStateException | IOException e){
            throw new RuntimeException(e.getMessage(),e);
        }
        
        userService.excelUpload(destFile);
        
        //FileUtils.delete(destFile.getAbsolutePath());
        
        ModelAndView view = new ModelAndView();
        view.setViewName("");
        return view;
    }
cs


스프링을 어케 쓰긴하는데 뭘 모르고 막 같다 붙이니까 진짜 멍청하단 생각 드는게

ajax 분명 제대로 보냈는데 controller에 안들어감. 왜?

왜!!!!!!!

@ResponseBody가 없기때문이었다. 아 저거 붙여주니 되네

ajax 시에는 무조건 @ResponseBody 인걸로

저기 FileUtils.delete(destFile.getAbsolutePath()); 는 적용하니 오류나서 일단 주석처리

왜안되는지는 나도몰름

[ # 추가 ]

FileUtils.delete(destFile.getAbsolutePath()); 여기 오류나서 주석처리해두었는데, 

코드 보니까 File destFile 이라고 새로운 파일객체를 생성하는데 그 경로가 D 가 되는것이다.

엑셀을 읽어오면서 첨부된 파일을 D에 임시로 저장해 놓고 마지막에 delete로 파일을 삭제한다.

근데 왜인지 저 위에 코드는 실행이 안됨

그래서 destFile.delete() 로 바꿔주었다. 



9. 어쨋건 controller로 받아서 destFile을 service로 넘겨준다. 

   destFile 은 파일의 이름을 가져오는 것인가?????(질문임)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
@Override
    public void excelUpload(File destFile) throws Exception{
        ExcelReadOption excelReadOption = new ExcelReadOption();
        excelReadOption.setFilePath(destFile.getAbsolutePath());
        excelReadOption.setOutputColumns("A","B","C","D","E","F");
        excelReadOption.setStartRow(2);
        
        
        List<Map<StringString>>excelContent =ExcelRead.read(excelReadOption);
        
        for(Map<StringString> article: excelContent){
            System.out.println(article.get("A"));
            System.out.println(article.get("B"));
            System.out.println(article.get("C"));
            System.out.println(article.get("D"));
            System.out.println(article.get("E"));
            System.out.println(article.get("F"));
            
        }
cs


어쨋거나 service단

여기에서 실제 excel 파일의 추출이 이루어진다.

for 문 안에서 원래 소스는 DB로 insert 되게 하는데 



여까지 하면, 첨부된 엑셀파일을 읽어와서 콘솔창에 출력된다. 2016-09-07



몇가지 궁굼증과 수정사항들이 생겼다.

1. 숫자를 소숫점으로 가져오는 문제

2. null값 처리

3. ExcelRead에서 시트의 수를 자동으로 가져와서 여러개의 시트를 추출

4. ExcelReadOption 에서 set으로 값을 지정해주어야 하는가? -> 자동으로 셀 수를 읽을 수 없는가


뭐 사실 더 많겠지만 , 지금 내머리 수준으로는 여기까지밖에 생각이 안난다.

할 수 있는 것 부터 수정해야지




1. ExcelCellRef.java 파일에서 cellValue 를 가져오는 for문을 switch-case 문으로 변경하면서

   숫자가 소숫점 나오는 문제 해결 value 값을 가져올 때 int 형으로 형변환 해주었다.

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
 if(cell == null) {
            value = "";
        }
        switch(cell.getCellType()) {
            case Cell.CELL_TYPE_FORMULA :
                value = cell.getCellFormula();
                break;
            
            case Cell.CELL_TYPE_NUMERIC :
                value = (int)cell.getNumericCellValue() + "";
                break;
                
            case Cell.CELL_TYPE_STRING :
                value = cell.getStringCellValue();
                break;
            
            case Cell.CELL_TYPE_BOOLEAN :
                value = cell.getBooleanCellValue() + "";
                break;
           
            case Cell.CELL_TYPE_BLANK :
                value = "";
                break;
            
            case Cell.CELL_TYPE_ERROR :
                value = cell.getErrorCellValue() + "";
                break;
            default:
                value = cell.getStringCellValue();
        }
cs



1. 숫자를 소숫점으로 가져오는 문제 해결 2016-09-08




나는 엑셀파일안에 2개의 시트를 저장해야 한다.

그래서 2개의 시트를 모두 읽어와햐 하는데.

지금 코드는 Sheet sheet = wb.getSheetAt(0); 이렇게 엑셀파일에서 첫번째 시트를 가지고 온다.


Sheet 클래스의 getNumberOfSheets() 를 이용하면 Sheet의 수를 가지고 올 수 있다.


1
2
3
for(int i =0; i<sheetNum; i++){
    System.out.println("Sheet 이름: "+ wb.getSheetName(i)); 
}
cs

for문을 이용해서 시트수를 가지고 올 수 있고, 적절히 넣으면 시트안에 있는 모든 데이터를 가지고 오게 된다.



그러면 ExcelRead.java 파일을 이렇게 수정한다.

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
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
 
 
 
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
 
 
 
public class ExcelRead {
     public static List<Map<StringString>> read(ExcelReadOption excelReadOption) {
            //엑셀 파일 자체
            //엑셀파일을 읽어 들인다.
            //FileType.getWorkbook() <-- 파일의 확장자에 따라서 적절하게 가져온다.
            Workbook wb = ExcelFileType.getWorkbook(excelReadOption.getFilePath());
          
            int sheetNum = wb.getNumberOfSheets(); //시트의 수를 가져오기 위한 변수 
            int numOfCells = 0;
            
            Row row = null;
            Cell cell = null;
            
            String cellName = "";
            
            /**
             * 각 row마다의 값을 저장할 맵 객체
             * 저장되는 형식은 다음과 같다.
             * put("A", "이름");
             * put("B", "게임명");
             */
            Map<StringString> map = null;
 
            /*
             * 각 Row를 리스트에 담는다.
             * 하나의 Row를 하나의 Map으로 표현되며
             * List에는 모든 Row가 포함될 것이다.
             */
            List<Map<StringString>> result = new ArrayList<Map<StringString>>(); 
            
            
            //이부분이 수정되었다.
            for(int i =0; i<sheetNum; i++){
                System.out.println("Sheet 이름: "+ wb.getSheetName(i));
                Sheet sheet = wb.getSheetAt(i);
            
                int numOfRows = sheet.getPhysicalNumberOfRows(); //유효한 데이터가 있는 행의 개수를 가져온다.
            
                /**
                 * 각 Row만큼 반복을 한다.
                 */
                for(int rowIndex = excelReadOption.getStartRow() - 1; rowIndex < numOfRows; rowIndex++) {
                
                    /*
                 * 워크북에서 가져온 시트에서 rowIndex에 해당하는 Row를 가져온다.
                 * 하나의 Row는 여러개의 Cell을 가진다.
                 */
                row = sheet.getRow(rowIndex);
                
                if(row != null) {
                    /*
                     * 가져온 Row의 Cell의 개수를 구한다. 
                     */
                    numOfCells = row.getPhysicalNumberOfCells(); //한개의 행마다 몇개의 cell이 있는지 체크 
                    
                    /*
                     * 데이터를 담을 맵 객체 초기화
                     */
                    map = new HashMap<StringString>();
                    
                    /*
                     * cell의 수 만큼 반복한다.
                     */
                    for(int cellIndex = 0; cellIndex < numOfCells; cellIndex++) {
                        /*
                         * Row에서 CellIndex에 해당하는 Cell을 가져온다.
                         */
                        cell = row.getCell(cellIndex);
                        /*
                         * 현재 Cell의 이름을 가져온다
                         * 이름의 예 : A,B,C,D,......
                         */
                        cellName = ExcelCellRef.getName(cell, cellIndex);
                        /*
                         * 추출 대상 컬럼인지 확인한다
                         * 추출 대상 컬럼이 아니라면, 
                         * for로 다시 올라간다
                         */
                        if!excelReadOption.getOutputColumns().contains(cellName) ) {
                            continue;
                        }
                        /*
                         * map객체의 Cell의 이름을 키(Key)로 데이터를 담는다.
                         */
                        map.put(cellName, ExcelCellRef.getValue(cell));
                    }
                    /*
                     * 만들어진 Map객체를 List로 넣는다.
                     */
                    result.add(map);   
                }
                
            }
        }
        return result;       
    }      
}
 
cs




3. ExcelRead에서 시트의 수를 자동으로 가져와서 여러개의 시트를 추출 완료 2016-09-09



한가지 더 수정할 부분이 있는데, 

지금 코드가 컨트롤러에서 파일을 가지고 와서 서비스 단에서 셀의 내용을 추출하고 있는데

나는 서비스를 다른 서비스를 호출해야하므로, 서비스부분인 excelUpload를 제거하고 그 안의 내용을 controller 부분으로 가져왔다.


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
40
41
42
    @ResponseBody
    @RequestMapping(value = "/excelUploadAjax", method = RequestMethod.POST)
    public ModelAndView excelUploadAjax(MultipartHttpServletRequest request)  throws Exception{
        MultipartFile excelFile =request.getFile("excelFile");
        System.out.println("엑셀 파일 업로드 컨트롤러");
        if(excelFile==null || excelFile.isEmpty()){
            throw new RuntimeException("엑셀파일을 선택 해 주세요.");
        }
        
        File destFile = new File("D:\\"+excelFile.getOriginalFilename());
        try{
            excelFile.transferTo(destFile);
        }catch(IllegalStateException | IOException e){
            throw new RuntimeException(e.getMessage(),e);
        }
        
        //Service 단에서 가져온 코드
        ExcelReadOption excelReadOption = new ExcelReadOption();
        excelReadOption.setFilePath(destFile.getAbsolutePath());
        excelReadOption.setOutputColumns("A","B","C","D","E","F");
        excelReadOption.setStartRow(2);
        
        
        List<Map<StringString>>excelContent =ExcelRead.read(excelReadOption);
        
        for(Map<StringString> article: excelContent){
            System.out.println(article.get("A"));
            System.out.println(article.get("B"));
            System.out.println(article.get("C"));
            System.out.println(article.get("D"));
            System.out.println(article.get("E"));
            System.out.println(article.get("F"));
        }
        
        //userService.excelUpload(destFile); //서비스 부분을 삭제한다.
        
        //FileUtils.forceDelete(destFile.getAbsolutePath());
        
        ModelAndView view = new ModelAndView();
        view.setViewName("/user/list");
        return view;
    }
cs




그럼이제 

자동으로 시트 안의 셀 갯수를 가지고 오는 문제인데 

지금 코드가 set으로 추출할 컬럼 명과 추출을 시작할 행 번호를 지정해주고 있다.

Set을 없애보았더니(잘몰라서) 안되는거 봐선 set을 꼭 해주어야하게 코드가 짜여있는거 같은데...흠(모르겠다)


저 안에 자동으로 읽을 수 있게 해주는 작업이 필요하겠지


ExcelRead 파일에 보면 

numofCells = row.getPhysicalNumberOfCells() 가 행의 cell을 가지고 오는 부분이다.

한개의 행 에 몇개의 cell이 있는지 체크하는 부분인데.

콘솔에 찍어보면, 내 엑셀 파일의 행에 대한 셀의 개수를 제대로 가지고 온다.


그런데 controller에서 set을 해주기 때문에 자동으로 가지고와봤자인듯 하다.




첨부터 다시짠다. 슈방





고민을 오전내내 하고 넘나 모르겠어서 질문하였는데...

2개의 시트가 관련성이 없어서

버튼자체를 나누어 개별파일로 업로드 하는게 좋을 것 같다고 하셨다.


그래서 일단 원복



2016-09-13





추석지나고 오니 머리 백지됨

내가 엑셀파일을 뭘하고 있었는가 부터 고민해야할 판...


일단 나는 원복을 해서 원상태이고, 2개의 버튼으로 나누기 전에

일단 하나의 시트만 import 해서 AD로 보내기로 마음을 먹었다. 오늘 AD까지 보내고 집간다.


2016-09-19 ( 결국 AD, DB에 다 넣었다 ! )





여기까지 일단(일단 엄청쓰네) 엑셀파일 import 하는 기능에 대한 설명은 자세히 해놓았다고 생각한다.

난 초초초초초보자니까 내가 하면 세상사람 다 할 수 있는거

다음과정은 나한테만 필요한거니 , 따로 포스팅해야겠다.



댓글
  • 이전 댓글 더보기
  • 프로필사진 킨글 <script src="http://malsup.github.com/jquery.form.js"></script> 없으면 ajaxSubmit 에러 나네요 2017.07.13 21:42
  • 프로필사진 비밀댓글입니다 2017.09.12 11:21
  • 프로필사진 /daydreamer 안녕하세요 !
    9번 service 부분을 보시면
    excelReadOption.setOutputColumns("A","B","C","D","E","F");
    요 부분이 있는데요,
    excel 파일을 열어보시면 셀 입력하기위해서 위에 A , B , C ... 있는거 아시죠?
    그걸 컬럼 명이라고 해서 추출할 컬럼명을 받아오는 부분입니다 ~
    감사합니다^^
    2017.09.12 13:01 신고
  • 프로필사진 hada ㅜㅜ지금따라하고 있는데요 excelUploadAjax 컨트롤러 파일에 가기전에 scrip단에서 보내주는 데이터 excelFile은 스트링 값아닌가요?
    MultipartFile excelFile = request.getFile("excelFile"); 이부분이
    제꺼에선 The method getFile(String) is undefined for the type HttpServletRequest 이런 에러가 떠요 ㅠㅠ
    2017.09.12 17:39
  • 프로필사진 /daydreamer MultipartFile excelFile = request.getFile("excelFile");
    여기에서의 excelFile은 form 안의 파일첨부하는 input box의 id로 request.getFile()을 해서 첨부한 파일을 가져오는것이에요
    <dl class="vm_name">
    <dt class="down w90">첨부 파일</dt>
    <dd><input id="excelFile" type="file" name="excelFile" /></dd>
    </dl>
    2017.09.12 17:49 신고
  • 프로필사진 hada 그리고 userservice는 소스에없다고 에러나는데 이부분은 뭔가요??ㅜㅜ저도 초보라.. 2017.09.12 17:43
  • 프로필사진 /daydreamer 안녕하세요 !
    userservice 에러가 controller에서 나시는건가요? controller에서 service 부분으로 넘어갈때 제가 생성한 파일의 이름이 userservice에요 ~~
    2017.09.12 17:53 신고
  • 프로필사진 hada 쩌러 ㅜㅜ 몇일 고생하긴했지만 이걸로 했어요 정말 감사합니다. 엑셀 다운로드는 없나여 사람의 욕심은 끝이없네여. 하하하하하 너무감사합니다 정말 넘나넘나 감사해용. 2017.09.25 16:59
  • 프로필사진 funncy ㅠㅠ 지금 열심히 따라하고 있는데
    MultipartFile excelFile =request.getFile("excelFile");
    System.out.println("엑셀 파일 업로드 컨트롤러");
    if(excelFile==null || excelFile.isEmpty()){
    throw new RuntimeException("엑셀파일을 선택 해 주세요.");
    }

    File destFile = new File("D:\\"+excelFile.getOriginalFilename());
    try{
    excelFile.transferTo(destFile);
    }catch(IllegalStateException | IOException e){
    throw new RuntimeException(e.getMessage(),e);
    }

    이부분에서
    java.io.FileNotFoundException: /Users/hjkim/graduation/D:\test.xlsx (No such file or directory)
    이런 경로가 없는다는 에러가 뜨네요ㅠㅠ 어떻게 수정해야할지...
    2018.04.04 20:00
  • 프로필사진 /daydreamer 안녕하세요! 폴더를 D에 생성하신거에요? 2018.04.04 20:02 신고
  • 프로필사진 /daydreamer 엑셀파일을 어떤 폴더에서 첨부하신건지 알려주시면 감사하겠습니다.
    /Users/hjkim/graduation/D:\test.xlsx
    이 경로가 궁금합니다.
    2018.04.04 20:09 신고
  • 프로필사진 funncy 위에 작성한거대로 작성하고 실행햇는데... 위에 코드에 보면
    File destFile = new File("D:\\"+excelFile.getOriginalFilename());
    이거 대로 D:\test.xlsx 이 경로가 지정되는것 같은데 ㅠㅠ 제가 작업 하던 경로 : /Users/hjkim/graduation/ 에 붙어서

    /Users/hjkim/graduation/D:\test.xlsx 인것 같아요 ㅠㅠ
    2018.04.05 10:00
  • 프로필사진 funncy 아 해결 했어요 ㅠㅠ
    public static String UPLOAD_DIR = "upload-dir";
    public static String UPLOAD_DIR_PATH;


    public static void main(String[] args) {

    File f = new File(UPLOAD_DIR);
    f.mkdir();
    UPLOAD_DIR_PATH = f.getAbsolutePath();

    System.out.println("UploadPath : " + UPLOAD_DIR_PATH);

    SpringApplication.run(GraduationApplication.class, args);
    }
    }

    처음 어플 시작하는 부분에서 경로 설정하고 디렉토리 만들고 넣으니 되네요 ㅠㅠ 감사합니다
    2018.04.05 10:19
  • 프로필사진 nwsy 파일타입 체크 부분에
    if(filePath.toUpperCase().endsWith(".XLS")) {
    try {
    wb = new HSSFWorkbook(fis);
    } catch (IOException e) {
    throw new RuntimeException(e.getMessage(), e);
    }
    }
    else if(filePath.toUpperCase().endsWith(".XLSX")) {
    try {
    wb = new XSSFWorkbook(fis); *************에러**************
    } catch (IOException e) {
    throw new RuntimeException(e.getMessage(), e);
    }
    }
    *******부분에서
    Could not initialize class org.openxmlformats.schemas.drawingml.x2006.main.ThemeDocument
    에러가 나는데 poi class 까지 디버깅 모드중 load(XSSFFactory.getInstance()); 다음줄에서 에러가 발생됩니다.
    도움 부탁드려요 ㅠㅠ
    2018.05.23 15:37
  • 프로필사진 /daydreamer 지금봤네요, 해결하셨나요? 2018.07.17 16:26 신고
  • 프로필사진 자자바바 안녕하세요 컬럼이 23개정도 넘어가면 못읽어오는데 어떻게하죠? 2018.07.16 14:25
  • 프로필사진 /daydreamer CellReference.convertNumToColString(cellNum);

    여기서 23개 이후에 값을 못가지고 오나요?
    2018.07.16 14:33 신고
  • 프로필사진 자자바바 아닙니다 잘나와요! 데이터값을 다불러오네요 ! 감사해요 ㅠ 근데 저대로 하면 업로드하면 엑셀데이터 값을 view로 출력이 되는건가요?? 2018.07.16 22:08
  • 프로필사진 /daydreamer 제가 올린부분은 엑셀 파일을 읽어오는것 까지 입니다. view에 출력하시는건 따로 해주셔야해요 2018.07.17 10:50 신고
  • 프로필사진 자자바바 받아온 데이터의 컬럼부분을 업로드에서 선택후 view에서 출력하고 싶은데 어뜨케할까요.. 2018.07.17 13:33
  • 프로필사진 비밀댓글입니다 2018.07.17 14:28
  • 프로필사진 자자바바 아 비밀댓글이여서 안보이네요 보는법을몰라서 ㅠ 2018.07.17 14:53
  • 프로필사진 /daydreamer 업로드시 추출한 데이터를 담아서 DB에서 데이터 가져와 뿌리듯 view로 보내시면 될것 같아요 2018.07.17 14:55 신고
  • 프로필사진 이발사 http://localhost:8088/excelUploadAjax.do 404 에러가뜨네요 2018.07.17 16:13
  • 프로필사진 /daydreamer controller에 메소드 제대로 생성하신건지 확인부탁드려요~ 2018.07.17 16:26 신고
  • 프로필사진 초보개발자 에러가뜨는데 따라가보니 잘 읽다가 ExcelRead 메소드 탈때 Workbook wb = ExcelFileType.getWorkbook(excelReadOption.getFilePath()); 선언해주는부분 에서 에러가 나는거 같아요.. 에러코드는 org.springframework.web.util.NestedServletException : 핸들러 디스패치가 실패했습니다. 중첩 예외는 java.lang.NoClassDefFoundError입니다 : org / apache / poi / ss / usermodel / Workbook // 콘솔창 에러는 = java.lang.IndexOutOfBoundsException: Index: 0, Size: 0 //이렇게 나오는데 찾기 힘드네요 ㅜㅜ 어떤문제인지 아시나요? 혹시 엑셀파일 널때 형식이 따로 존재하나요? 셀 갯수나 등등.. 2018.08.21 11:02
  • 프로필사진 /daydreamer Excelfiletype클래스를 만드신건가요?? 2018.08.21 11:19 신고
  • 프로필사진 초보개발자 네 만들었습니다. 보니깐 ExcelFileType클래스까지 접속이 안되는것보니 Workbook문제 인거 같은데.. ㅜㅜ // 해결됬습니다~~~~ 톰캣 다 날리고 메이븐 다시받구 하니깐 뜨네요!!! 감사합니당 ㅜㅜ 이제 이 읽은값으로 insert해서 db에다가 넣는 작업만 남았네용..ㅋㅋ 2018.08.21 11:31
  • 프로필사진 엑셀 안녕하세요.
    컨트롤러 부분에서 excelReadOption.setOutputColumns("A","B","C","D","E") 이런식으로 되어있는데
    저 엑셀 첫번째 행에선 DB에 들어갈 컬럼명을 입력한 상태라 ABCDE부분을 컬럼명으로 수정했는데 excelContent 에 값이 들어오지않네요.
    excelContent에서 key를 DB에 들어갈 컬럼명으로 받고 싶은데 어떻게 처리해야할까요?
    2018.09.14 13:57
  • 프로필사진 /daydreamer ABCD는 제가 임의로 입력한 문자가 아닌 엑셀 보시면 맨 상단에 위치를 알 수 있도록 표시된 알파벳이 있습니다. 그걸 의미하는것이고 그 알파벳이 있는곳의 컨텐츠를 가져오겠다는 의미입니다. 그곳은 수정이 안되는걸로 알고있어요 2018.09.14 14:05 신고
  • 프로필사진 감사합니당 덕분에 편하게 엑셀 관련 내용 구현이 되었습니다..
    추가로 int로 형변환을 주는 경우, 실제 소수점 자리가 필요한 경우에는 가져오질 못 해서 아쉽더라구요.
    그래서 추가로
    case Cell.CELL_TYPE_NUMERIC :
    value = cell.getNumericCellValue() + "";
    //소수점이 필요치 않은 경우 .0은 제거
    String rowStr = value.toString();
    if(rowStr.contains(".0")){
    rowStr = rowStr.substring(0, rowStr.length()-2);
    value = rowStr;
    }
    break;

    추가 하였네요.!!! 아무튼 정말 감사드립니다!!!
    2018.11.06 13:21
  • 프로필사진 후투투 많은 도움이 되었습니다 감사합니다 2018.11.29 14:20 신고
  • 프로필사진 초보 안녕하세요, 저도 기존 기간계시스템 소스에 해당 소스를 그대로 적용하고 있는데요...ㅠㅠ
    Controller에서 윗분이 말씀하신 것 처럼 excelService.excelUpload(destFile); 여기에서 excelService를 추가해줘야 할거 같은데
    참고할만한 소스나 내용이 있을까요?
    2019.02.26 16:42
  • 프로필사진 파알 안녕하세요ㅜㅜ 잘 따라가고 있는 줄 알았는데 이런 에러가 나서 몇시간째 고치지 못하고 있어요 매퍼파일에서 에러가 발생한 것 같은데 감도 안잡히네요ㅜㅜ

    The expression 'excelContent' evaluated to a null value.
    2020.04.20 23:48 신고
댓글쓰기 폼