시스템아 미안해
java 엑셀 업로드(json으로 변환해서 jsp로 가져오기) 본문
본인이 넘길 form값들에 name을 주고 ajax에서 formData객체로 넘긴다.
var form = $("#frm")[0];
var formData = new FormData(form);
$.ajax({
method : 'POST',
url: '../settle/xlsUploadLoad',
data : formData,
dataType : 'json',
contentType : false,
processData : false,
beforeSubmit: function(){
$('button').prop('disabled',true);
}
파일 객체도 같이 들어있기 때문에 contentType과 processData를 false로 설정,
jsonArray안의 jsonObject를 반환받을 예정이라 dataType은 json으로 설정한다.
[controller]
@PostMapping(value="/xlsUploadLoad")
@ResponseBody
public JSONArray xlsUploadLoad( @RequestParam(value="yy", required = false, defaultValue = "0000")String strYear,
@RequestParam(value="f", required = false, defaultValue = "")String strFlag,
MultipartHttpServletRequest mpReq ) throws Exception {
log.debug("=======================xlsUploadLoad=======================");
JSONArray jsonArr = FileUtil.xlsUploadLoad(strFlag, strYear, mpReq);
return jsonArr;
}
json을 반환할 controller는 @responseBody 어노테이션으로 명시해주고,
FileUtil객체에서 바로 jsonArray를 return했다.
[FileUtil]
private static final String path = ApplicationProperty.getFilePath();
public static JSONArray xlsUploadLoad(String strFlag,
String strYear,
MultipartHttpServletRequest mpReq) throws Exception {
String uploadPath = path + ApplicationProperty.getExcelFolder();
File file = new File(uploadPath);
verifyUploadPath(uploadPath);
MultipartFile mpFile = mpReq.getFile("xls");
String fileName = mpFile.getOriginalFilename();
String fileExtension = fileName.substring(fileName.lastIndexOf("."));
String storedFileName = getRandomString() + fileExtension;
file = new File(uploadPath, storedFileName);
//경로에 저장
mpFile.transferTo(file);
FileInputStream excelFile = new FileInputStream(uploadPath + storedFileName);
JSONArray jsonArr = ExcelParser.excelToJsonArr(excelFile, strFlag, fileExtension);
return jsonArr;
}
private static void verifyUploadPath(String path) {
if (!new File(path).exists()) {
try {
new File(path).mkdir();
} catch (Exception e) {
e.getStackTrace();
}
}
}
application.properties에 저장해놓은 경로값을 ApplicationProperty bean과 연결했기 때문에
해당하는 변수를 getter로 불러들이면 properties의 path를 부를 수 있다.
verifyUploadPath 메소드에서 만약 path에 해당하는 파일이 없으면 폴더를 생성하고, 파일을 저장한 후
ExcelParser객체에서 엑셀 파싱한 값을 jsonArray로 받는다.
[ExcelParser]
public class ExcelParser {
public static JSONArray excelToJsonArr(FileInputStream excelFile, String strFlag, String fileExtension) {
JSONArray jsonArray = new JSONArray();
try{
Workbook workbook = WorkbookFactory.create(excelFile);
Sheet sheet = workbook.getSheetAt(0);
//행의 개수
int rownum = sheet.getLastRowNum();
//첫 행은 컬럼명이므로 두번째 행인 index1부터 읽기
for(int rowIndex=1;rowIndex<=rownum;rowIndex++){
//현재 index의 행 읽기
Row currentRow = sheet.getRow(rowIndex);
// 열이 비어있으면 다음 행으로 넘어감
if(currentRow == null || currentRow.getCell(0).getStringCellValue().equals("")) break;
///현재 행의 cell 개수
int cellnum = currentRow.getLastCellNum();
//엑셀 데이터를 넣을 json object
JSONObject data = new JSONObject();
int idx = 1;
data.put("No", idx);
for(int cellIndex =0; cellIndex<cellnum;cellIndex++){
System.out.println(rowIndex+"행 "+cellIndex+"열의 값 : " + currentRow.getCell(cellIndex));
if("WR".equals(strFlag)) {//우리카드
switch(cellIndex){
case 0 : { //이용일자
data.put("dateUse",currentRow.getCell(cellIndex).getStringCellValue());
};break;
case 2 : { //승인번호
data.put("strApprovalNum",currentRow.getCell(cellIndex).getStringCellValue());
};break;
case 3 : { //이용카드
data.put("strUseCardNum",currentRow.getCell(cellIndex).getStringCellValue());
}break;
case 5 : { //이용가맹점명
data.put("strStore",currentRow.getCell(cellIndex).getStringCellValue());
}break;
case 9 : { //사업자번호
data.put("strCorpNum",currentRow.getCell(cellIndex).getStringCellValue());
}break;
case 16 : { //승인금액
data.put("moneySale",currentRow.getCell(cellIndex).getNumericCellValue());
}break;
}
}else if("SH".equals(strFlag)) {//신한카드
String dateUse = null;
switch(cellIndex){
case 6 : { //이용일자
dateUse = currentRow.getCell(cellIndex).getStringCellValue().replace(".", "-");
};break;
case 7 : { //이용일자 + 이용시간
String time = currentRow.getCell(cellIndex).getStringCellValue();
if(time == null || "".equals(time)) {
data.put("dateUse",dateUse + "00:00:00");
}else {
data.put("dataUse",dateUse + currentRow.getCell(cellIndex).getStringCellValue());
}
};break;
case 5 : { //승인번호
data.put("strApprovalNum",currentRow.getCell(cellIndex).getStringCellValue());
}break;
case 4 : { //이용카드
data.put("strUseCardNum",currentRow.getCell(cellIndex).getStringCellValue());
}break;
case 19 : { //이용가맹점
data.put("strStore",currentRow.getCell(cellIndex).getStringCellValue());
}break;
case 18 : { //사업자번호
data.put("strCorpNum",currentRow.getCell(cellIndex).getStringCellValue());
}break;
case 9 : { //승인금액
data.put("moneySale",currentRow.getCell(cellIndex).getNumericCellValue());
}break;
}
}
}
++idx;
jsonArray.add(data);
}
return jsonArray;
}catch(Exception e){
System.out.println("ERROR : " + e);
return jsonArray;
}
}
}
엑셀을 파싱할때 주의할 점은 XSSFWorkbook, HSSFWorkbook, workbook객체의 사용 차이이다.
XSSFWorkbook : xlsx파싱
HSSFWorkbook : xls파싱
어떤 엑셀 파일이 들어올 지 모르기 때문에 workbook객체를 사용했더니 모두 파싱이 됐다.
+ 정수는 getStringCellValue > string으로 파싱하지만
소수점이 포함된 숫자는 getNumericCellValue로 파싱해주어야 한다.
매 행마다 jsonObject에 data를 넣어주고, 가장 마지막에 jsonArray에 jsonObject를 넣은 후 return.
[jsp]
success: function(json){
$.each(json,function(e){
const row = $(this)[0];
row.dateUse
}
}
jsonArray를 each로 하나씩 읽어들이고, $(this)[0] 을 출력해보면 엑셀 한 행의 data가 담겨있는 jsonObject가 찍힌다.
jsonObject의 key값이 dateUse라면 $(this)[0].dateUse로 값을 배치할 수 있다.
'java > 문법' 카테고리의 다른 글
jsp에서 넘어온 parameter를 Object > String > Double로 (0) | 2022.12.02 |
---|---|
toString()으로 받는 변수에 null이 들어올때 (0) | 2022.11.30 |
자바 8 버전 특징 (0) | 2022.09.24 |
parseInt vs valueOf, toString vs valueOf (0) | 2022.08.28 |
HashMap - putIfAbsent vs getOrDefault (0) | 2022.08.16 |