# File Type 업로드 (appendix)

> 열 또는 셀의 Type을 `File`로 설정 시 파일 업로드를 할 수 있습니다.
> Input태그가 각 셀마다 생성되며, 사이드 버튼 클릭 시 업로드 창이 열리고 파일을 선택할 수 있습니다.
> 업로드 된 파일은 저장시 서버로 전송되며, 서버에서 파일 이름과 저장 경로를 전달해주면 조회된 파일을 다운로드 할 수 있습니다.
> 파일 업로드 (추가, 편집) 후에는 해당 파일을 클릭해도 서버호출(다운로드)이 일어나지 않습니다.
> Path 속성 혹은 FilePath가 설정된 경우에만 셀에 데이터가 표시됩니다.

## 1. 조회

> 조회 데이터는 `ColName : 파일이름`, `ColName + "Path" : "파일 저장경로"`로 입력합니다.
> `Cfg.Export.FilePath` 에 파일 저장 경로 설정 시 Path 데이터를 입력하지 않아도 해당 경로에 파일이 전송 됩니다.
> `예: {"data": [{"file":"file.xlsx", "filePath":"/customer-sample/", "fileAlias":"파일.xlsx"}]}`

## 2. 저장

> 저장은 doSave()를 이용한 저장, ajax 통신을 통한 applySaveResult()를 이용한 저장이 가능합니다.

#### ajax 로 저장하기

    var url = '../jsp/samples/customer/file_save.jsp';
    var saveData = sheet.getSaveJson({saveMode:2, formData: true});

    $.ajax({
      	url: url,
          	data: saveData,
          	method: "POST",
          	enctype: 'multipart/form-data',
          	contentType: false,
          	processData: false,
          	cache: false,
          	success:function(data){
          	      var result = data.IO.Result;
          	      var fileData = data.IO.data;

         	      //결과를 시트에 반영한다.
          	      sheet.applySaveResult(result, null, null, fileData);
         	}
    });

### 저장 후 시트에서 서버로 전송하는 저장 데이터 규격

- 파일 타입 컬럼데이터는 `rowID$colName: (binary)` 형태로 업로드 된 파일이 서버로 전송되며 저장 데이터에서는 제외됩니다.

    Data: {
         "data":[
              {"id":"AR1", "STATUS":"Changed"},
              {"id":"AR2", "STATUS":"Changed"},
         ]
    }
    AR1$file1: (binary)
    AR2$file: (binary)

### 저장 작업 후 서버 응답 데이터 규격

    // 서버에서 시트로 보낼 응답 규격
    // 성공 시
    {"IO": {
        "Result": 0 ,
        "Message": "저장 되었습니다.",
        "data":[
                {"file":"file.xlsx", "filePath":"/customer-sample/", "id":"AR7"},
                {"file":"file1.xlsx", "filePath":"/customer-sample/", "id":"AR4"},
               ]
        }
    }
    // 실패 시 Result 값을 음수로 설정.
    {"IO": {"Result": -1, Meassage:"오류내용..." }}

### 서버 예제

    <%@ page language="java" contentType="application/json; charset=UTF-8"  pageEncoding="UTF-8"%>
    <%@ page import="java.util.*, javax.servlet.*, com.ibleaders.utility.ib_json.*"%>

    <%!
        // 파일 이름 가지고 오는 함수 예시
        public String getFilename(Part part) {
            for (String cd : part.getHeader("content-disposition").split(";")) {
                if (cd.trim().startsWith("filename")) {
                String filename = cd.substring(cd.indexOf('=') + 1).trim().replace("\"", "");
                return filename.substring(filename.lastIndexOf('/') + 1).substring(filename.lastIndexOf('\\') + 1);
                }
            }
            return null;
        }
    %>
    <%
        request.setCharacterEncoding("utf-8");
        response.setContentType("application/json");
        response.setStatus(200);

        boolean process = false;
        JSONArray jsonArr = new JSONArray();
        try {
            Collection<Part> parts = request.getParts();
            for(Part part : parts){
                if  (part.getHeader("Content-Disposition").contains("filename=")) {
                    //  파일에 대한 처리
                    JSONObject file = new JSONObject();
                    String fileParam = part.getName();
    	    	String id = fileParam.split("\\$", 2)[0];
    	    	String col = fileParam.split("\\$", 2)[1];

                    String filename = getFilename(part);
                    String filepath = "C:/myPath/temp/";
                    part.write(filepath + filename);

                    file.put("id", id);
                    file.put(col, filename);
                    file.put(col + "Path", filepath);
                    jsonArr.add(file);
                } else {
                    // 다른 값에 대한 처리
                    String colName = part.getName();
                    String value = request.getParameter(part.getName());
                }
            }
            process = true;
        } catch(Exception ex) {
        	System.out.println(ex.getMessage());
            process = false;
        }

        JSONObject result = new JSONObject();
        JSONObject IO = new JSONObject();
        try {
            int res = process ? 0 : -2; // -2 ~ -9까지 시트에 전달하면 오류 메시지를 띄웁니다.
            IO.put("Result", res);
            IO.put("data", jsonArr);

            // -1 브라우저 미지원 오류.
            result.put("IO", IO); // 통신 관련 객체
        } catch(Exception ex) {
            result.put("Exception", ex);
        }
        out.print(result);
    %>

### Read More

- type appendix
- doSave method
- getSaveJson method
- applySaveResult method
- Alias cell
- Path cell
- onBeforeFileDown event

### Since

product | version | desc
--- | --- | ---
core | 8.0.0.5 | 기능 추가