add excel upload

This commit is contained in:
Kana
2024-01-15 18:00:19 +09:00
parent f21300a991
commit b069e1d1be
10 changed files with 496 additions and 99 deletions

View File

@@ -1,23 +1,32 @@
package com.no1.wms.category;
import java.util.List;
import java.io.IOException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
import com.no1.wms.excel.ExcelUtils;
import com.no1.wms.excel.ExcelRequestManager;
import com.no1.wms.excel.ExcelDownlodeUtils;
@@ -28,16 +37,15 @@ public class CategoryController {
CategoryService categoryService;
@Autowired
ExcelUtils excelUtils;
ExcelDownlodeUtils excelDownlodeUtils;
//테스트
@GetMapping("/category/test")
public String testPage(Model m) {
List<CategoryDto> dto = categoryService.selectAllCategory();
m.addAttribute("dto", dto);
public String testPage(Model m, HttpServletRequest request) {
return "category/test";
}
};
// 카테고리 리스트 출력
@GetMapping("/category/list")
@@ -77,7 +85,7 @@ public class CategoryController {
//List<CategoryDto> dto = categoryService.categoryList(page);
//m.addAttribute("list", dto);
return "category/list";
}
};
// 상세페이지
@PostMapping("/category/read")
@@ -86,13 +94,13 @@ public class CategoryController {
CategoryDto dto = categoryService.selectByKanCode(kan_code);
m.addAttribute("dto", dto);
return "category/read";
}
};
// 생성 - 폼
@PostMapping("/category/create")
public String create() {
return "category/create";
}
};
// 생성 - Ajax
@@ -105,7 +113,7 @@ public class CategoryController {
} else {
return false;
}
}
};
// 수정 - 폼
@PostMapping("/category/update")
@@ -113,7 +121,7 @@ public class CategoryController {
CategoryDto dto = categoryService.selectByKanCode(kan_code);
m.addAttribute("dto", dto);
return "category/update";
}
};
// 수정 - Ajax
@PutMapping("/category/update_process")
@@ -126,7 +134,7 @@ public class CategoryController {
} else {
return false;
}
}
};
// 삭제
@DeleteMapping("/category/delete")
@@ -138,18 +146,18 @@ public class CategoryController {
} else {
return false;
}
}
};
// 엑셀다운로드테스트
@GetMapping("/category/download")
public void downloadExcel(HttpServletResponse response) {
@GetMapping("/category/downloadTest")
public void downloadExcelTest(HttpServletResponse response) {
List<CategoryDto> dto = categoryService.selectAllCategory();
String excelFileName = "카테고리 테스트 파일";
String sheetName = "카테고리";
String[] columnName = {"KAN_CODE","대분류","중분류","소분류","세분류"};
excelUtils.downloadCategoryExcelFile(excelFileName, response, sheetName, columnName, dto);
excelDownlodeUtils.downloadCategoryExcelFile(excelFileName, response, sheetName, columnName, dto);
}
};
// KAN코드 중복확인 메서드
@PostMapping("/category/checkKancode")
@@ -157,7 +165,7 @@ public class CategoryController {
public String chackKancode(String kan_code) {
String checkkan = categoryService.kanCheck(kan_code);
return checkkan;
}
};
//카테고리 검색 모달
@GetMapping("/category/categorysearch")
@@ -192,9 +200,67 @@ public class CategoryController {
m.addAttribute("p" , page);
return "modal/categorysearch";
}
};
@GetMapping("/category/downlodeCategoryForm")
public void downlodeCategoryForm (HttpServletResponse response) throws IOException{
String categoryFormName = "카테고리 데이터 입력 서식.xlsx";
excelDownlodeUtils.downlodeExcelForm(response, categoryFormName);
};
@PostMapping("/category/uplodeExcel")
public String uploadExcel(@ModelAttribute("dto") CategoryDto dto , RedirectAttributes redirectAttributes,final MultipartHttpServletRequest multiRequest,
HttpServletRequest request,ModelMap model) {
Map<String, Object> resMap = new HashMap<>();
try {
ExcelRequestManager em = new ExcelRequestManager();
// 멀티파트 요청 객체에서 파일 맵을 가져옴
final Map<String, MultipartFile> files = multiRequest.getFileMap();
//초기화
List<HashMap<String,String>> apply =null;
//엑셀파일 가져와서 저장 및 읽기
//변수는 멀티파트 요청 객체의 파일맵, 저장할 엑셀파일명 이름에 추가할 숫자(그냥 0으로 해도 됨)
//마찬가지로 엑셀파일 명 이름에 추가할 문자열, uplode폴더에 들어갈 폴더명(카테고리같은 파트 이름으로 해주세요)
//폴더가 없으면 자동생성되게 해뒀습니다.
//마지막으로 HttpServletRequest
apply = em.parseExcelSpringMultiPart(files, "테스트파일", 0, "", "category", request);
for (int i = 0; i < apply.size(); i++) {
dto.setKan_code(apply.get(i).get("cell_0"));
dto.setCls_nm_1(apply.get(i).get("cell_1"));
dto.setCls_nm_2(apply.get(i).get("cell_2"));
dto.setCls_nm_3(apply.get(i).get("cell_3"));
dto.setCls_nm_4(apply.get(i).get("cell_4"));
dto.setActivation(true);
categoryService.createProcess(dto);
}
resMap.put("res", "ok");
resMap.put("msg", "업로드 성공");
} catch (Exception e) {
System.out.println(e.toString());
resMap.put("res", "error");
resMap.put("msg", "업로드 실패");
}
redirectAttributes.addFlashAttribute("resMap", resMap);
return "redirect:/category/list";
};

View File

@@ -3,6 +3,7 @@ package com.no1.wms.category;
import org.apache.ibatis.type.Alias;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@@ -16,5 +17,6 @@ public class CategoryDto {
private String cls_nm_2;
private String cls_nm_3;
private String cls_nm_4;
private boolean activation;
@Builder.Default
private Boolean activation = true;
}

View File

@@ -0,0 +1,17 @@
package com.no1.wms.excel;
//../을 통해 부모디렉토리로 이동하는 방법을 막기 위한 보안
public class EgovWebUtil {
public static String filePathBlackList(String value) {
String returnValue = value;
if (returnValue == null || returnValue.trim().equals("")) {
return "";
}
returnValue = returnValue.replaceAll("\\.\\./", "");
returnValue = returnValue.replaceAll("\\.\\.\\\\", "");
return returnValue;
}
}

View File

@@ -1,16 +1,21 @@
package com.no1.wms.excel;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.List;
import javax.servlet.http.HttpServletResponse;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
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;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.stereotype.Service;
import com.no1.wms.category.CategoryDto;
@@ -19,8 +24,12 @@ import com.no1.wms.category.CategoryDto;
@Service
public class ExcelUtils {
public class ExcelDownlodeUtils {
//마지막 List<CategoryDto> dto 이부분을 수정해서 만들어야함.
public void downloadCategoryExcelFile(String excelFileName, HttpServletResponse response,
String sheetName, String[] columnName, List<CategoryDto> dto) {
String fileName = "";
@@ -32,7 +41,7 @@ public class ExcelUtils {
response.setContentType("ms-vnd/excel");
response.setHeader("Content-Disposition", "attachment; filename=\"" + fileName + "\";");
Workbook workbook = new HSSFWorkbook();
Workbook workbook = new XSSFWorkbook();
Sheet sheet = workbook.createSheet(sheetName);
Row row = null;
@@ -45,6 +54,7 @@ public class ExcelUtils {
cell.setCellValue(columnName[i]);
}
rowNum += 1;
//수정부분
makeCategoryBody(dto,row,sheet,cell,rowNum);
@@ -77,5 +87,43 @@ public class ExcelUtils {
}
}
//엑셀 파일 다운로드
//엑셀 폼은 직접 만들어서 src/main/webapp/excelfiles/excelform 경로의 폴더안에 넣으면 됩니다.
//확장자는 .xlsx로 해주세요.
//매개변수는 HttpServletResponse response와 파일명 String을 넣으면 되고 파일명은 한글도 가능합니다.
public void downlodeExcelForm(HttpServletResponse response, String formName) throws IOException {
String excelfilesDirectory = "src/main/webapp/excelfiles/excelform/";
File file = new File(excelfilesDirectory+formName);
try( FileInputStream fis = new FileInputStream(file);
BufferedInputStream bis = new BufferedInputStream(fis);
OutputStream out = response.getOutputStream()){
String encodedFilename = URLEncoder.encode(formName, "UTF-8").replaceAll("\\+", "%20");
response.addHeader("Content-Disposition", "attachment;filename=\""+encodedFilename+"\"");
response.setContentType("application/vnd.ms-excel");
// 응답 크기 명시
response.setContentLength((int)file.length());
int read = 0;
while((read = bis.read()) != -1) {
out.write(read);
}
}catch(IOException e) {
e.printStackTrace();
}
}
}

View File

@@ -0,0 +1,110 @@
package com.no1.wms.excel;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellType;
import org.apache.poi.ss.usermodel.DateUtil;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
public class ExcelManagerXlsx {
private static ExcelManagerXlsx excelXlsxMng;
public ExcelManagerXlsx() {
}
public static ExcelManagerXlsx getInstance() {
if (excelXlsxMng == null) {
excelXlsxMng = new ExcelManagerXlsx();
}
return excelXlsxMng;
}
public List<HashMap<String, String>> getListXlsxRead(String excel) throws Exception {
List<HashMap<String, String>> list = new ArrayList<HashMap<String,String>>();
File file = new File( excel );
if( !file.exists() || !file.isFile() || !file.canRead() ) {
throw new IOException( excel );
}
XSSFWorkbook wb = new XSSFWorkbook( new FileInputStream(file) );
//xls시 이용
//HSSFWorkbook wb = new HSSFWorkbook ( new FileInputStream(file) );
int sheetIndex = 0;
try {
// 모든 시트 순회
for( int i=0; i<1; i++ ) {
XSSFSheet sheet = wb.getSheetAt(sheetIndex);
for( Row row : sheet ) {
// 첫 번째 시트만 사용
if(row.getRowNum() == 0) {
continue;
}
HashMap<String, String> hMap = new HashMap<String, String>();
String valueStr = "";
int cellLength = (int) row.getLastCellNum();///
for (int j = 0; j < row.getLastCellNum(); j++) {
Cell cell = row.getCell(j);
if (cell == null || cell.getCellType() == CellType.BLANK) {
valueStr = "";
}else{
switch(cell.getCellType()){
case STRING :
valueStr = cell.getStringCellValue();
break;
case NUMERIC : // 날짜 형식이든 숫자 형식이든 다 CELL_TYPE_NUMERIC으로 인식함.
if(DateUtil.isCellDateFormatted(cell)){ // 날짜 유형의 데이터일 경우,
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd", Locale.KOREA);
String formattedStr = dateFormat.format(cell.getDateCellValue());
valueStr = formattedStr;
break;
}else{ //숫자 데이터일 경우,
Double numericCellValue = cell.getNumericCellValue();
if(Math.floor(numericCellValue) == numericCellValue){ // 소수점 이하를 버린 값이 원래의 값과 같다면,,
valueStr = numericCellValue.intValue() + ""; // int형으로 소수점 이하 버리고 String으로 데이터 담는다.
}else{
valueStr = numericCellValue + "";
}
break;
}
case BOOLEAN :
valueStr = cell.getBooleanCellValue() + "";
break;
}
}
// 엑셀의 열 인덱스와 함께 값 매핑
hMap.put("cell_"+j ,valueStr);
}
// 결과 리스트에 추가
list.add(hMap);
}
sheetIndex++;
}
}catch(Exception ex){
ex.printStackTrace();
}
return list;
}
}

View File

@@ -0,0 +1,86 @@
package com.no1.wms.excel;
import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import javax.servlet.http.HttpServletRequest;
import org.springframework.web.multipart.MultipartFile;
public class ExcelRequestManager {
public List<HashMap<String, String>> parseExcelSpringMultiPart
(Map<String, MultipartFile> files , String KeyStr, int fileKeyParam,String atchFileId ,String storePath,HttpServletRequest request) throws Exception{
List<HashMap<String, String>> list = null;
int fileKey = fileKeyParam;
String storePathString = "";
String atchFileIdString = "";
String folder = request.getServletContext().getRealPath("/");
if ("".equals(storePath) || storePath == null) {
storePathString = folder+"/excelfiles/upload/";
} else {
storePathString = folder+"/excelfiles/upload/"+storePath;
}
if (!"".equals(atchFileId) || atchFileId != null) {
atchFileIdString = atchFileId;
}
File saveFolder = new File(EgovWebUtil.filePathBlackList(storePathString));
//폴더 없으면 생성
if (!saveFolder.exists() || saveFolder.isFile()) {
saveFolder.mkdirs();
}
Iterator<Entry<String, MultipartFile>> itr = files.entrySet().iterator();
MultipartFile file;
String filePath = "";
while (itr.hasNext()) {
//파일 이름을 가져오는데 파일이 여러개일 경우
Entry<String, MultipartFile> entry = itr.next();
file = entry.getValue();
String orginFileName = file.getOriginalFilename();
if ("".equals(orginFileName)) {
continue;
}
//파일의 확장자
int index = orginFileName.lastIndexOf(".");
String fileExt = orginFileName.substring(index + 1);
//파일의 이름 정하기 지정한 KeyStr값과 시간 값과 fileKey를 넣어서 만듬
String newName = KeyStr + getTimeStamp() + fileKey;
if (!"".equals(orginFileName)) {
filePath = storePathString + File.separator + newName+"."+fileExt;
file.transferTo(new File(EgovWebUtil.filePathBlackList(filePath)));
}
list = ExcelManagerXlsx.getInstance().getListXlsxRead(filePath);
fileKey++;
}
return list;
}
private static String getTimeStamp() {
long currentTimeMillis = System.currentTimeMillis();
Date currentDate = new Date(currentTimeMillis);
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd_HHmmss");
String formattedTimeStamp = dateFormat.format(currentDate);
return formattedTimeStamp;
}
}