mjon_git/src/main/java/itn/com/cmm/util/FaxUtil.java
2023-06-12 11:15:02 +09:00

499 lines
17 KiB
Java

package itn.com.cmm.util;
import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import javax.servlet.http.HttpServletResponse;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.Font;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import itn.com.cmm.JsonResult;
import itn.let.fax.user.service.FaxGroupDataVO;
import itn.let.mjo.msgdata.service.PhoneVO;
/**
*
* @author : 이호영
* @fileName : FaxUtil.java
* @date : 2023.03.20
* @description : 팩스 관련 Util
* ===========================================================
* DATE AUTHOR NOTE
* ----------------------------------------------------------- *
* 2023.03.20 이호영 최초 생성
*
*
*
*/
public final class FaxUtil {
public static HttpServletResponse getResponse() {
ServletRequestAttributes attr =
(ServletRequestAttributes)RequestContextHolder.currentRequestAttributes();
return attr.getResponse();
}
/**
* @methodName : checkHpNum
* @author : 이호영
* @date : 2023.03.20
* @description :
* @param faxConvertFilePath
* @param seq
* @return
*/
public static String makeDownloadPath(String faxConvertFilePath, String seq) {
return faxConvertFilePath + "/" + seq + ".pdf";
}
/**
* @methodName : exelFileConvertForFax
* @author : 이준호
* @date : 2023.05.08
* @description :
* @param multiRequest
* @return
*/
public static JsonResult exelFileConvertForFax(MultipartHttpServletRequest multiRequest) {
JsonResult jr = new JsonResult();
jr.setSuccess(false);
jr.setMessage("엑셀 파일만 업로드할 수 있습니다.");
//final Map<String, MultipartFile> files = multiRequest.getFileMap();
List<MultipartFile> files = (List<MultipartFile>) multiRequest.getFiles("file0");
// 파일명에 .이 있을경우 오류 => Ex) 테스트6.20.xlsx
int fileNameSplitCnt = 0;
if(!files.isEmpty()) {
fileNameSplitCnt = files.get(0).getOriginalFilename().split("[.]").length;
if (files.get(0).getSize() > 0
&& (files.get(0).getContentType().indexOf("spreadsheetml") > -1)
|| files.get(0).getContentType().indexOf("ms-excel") > -1
|| files.get(0).getOriginalFilename().split("[.]")[fileNameSplitCnt-1].indexOf("xlsx") > -1
|| files.get(0).getOriginalFilename().split("[.]")[fileNameSplitCnt-1].indexOf("xls") > -1) {
// 엑셀 파일 용량 3MB이상 시 10만건 이상으로 서버가 다운되는 증상 발생
long fileSize = multiRequest.getFile("file0").getSize();
if(fileSize > 3374653) {
jr.setMessage("엑셀 파일은 3MB를 넘을수 없습니다.");
return jr;
}
String Ext = files.get(0).getOriginalFilename().split("[.]")[1];
String errMessage = "";
String cellValue = "";
// String phoneRegExp = "^(050[234567]{1}|01[016789]{1})-?[0-9]{3,4}-?[0-9]{4}$";
int errPhoneCnt = 0;
int errNameCnt = 0;
try {
//엑셀 확장자에 따른 처리 로직 분리
if(Ext.equals("xls")) {
HSSFWorkbook workbook = new HSSFWorkbook(files.get(0).getInputStream());
HSSFSheet sheet = workbook.getSheetAt(0);
if(sheet.getLastRowNum() > 20000) { //
errMessage = "20000건 이상의 업로드는 데이터 부하로 업로드 할수 없습니다.";
jr.setSuccess(false);
jr.setMessage(errMessage);
return jr;
}
List<HashMap<String, String>> json = new ArrayList<HashMap<String, String>>();
PhoneVO pVO = new PhoneVO();
for(int i=2; i< sheet.getLastRowNum() + 2; i++){ //먼저 밸리데이션 체크(1줄은 생략)
HSSFRow row = sheet.getRow(i); //열읽기
if(null == row) {
continue;
}
HashMap<String, String> jm = new HashMap<>();
// 행의 두번째 열(이름부터 받아오기)
HSSFCell cell = null;
boolean errSts = true;
for(int j = 0 ; j < 2; j++){ //행읽기(6행까지나 2행까지만 필요)
cellValue = "";
cell = row.getCell(j); //이름/수신번호
if(null == cell || "".equals(cell.toString().trim())) { //셀에 값이 없으면
//System.out.println("Cell 데이터가 없습니다.");
if(j == 1) {
if (sheet.getLastRowNum() == i) {
continue;
}
break;
}
}
if(null != cell){
switch(cell.getCellType()){ //숫자타임을 문자로 변환
case Cell.CELL_TYPE_NUMERIC:
cell.setCellType(Cell.CELL_TYPE_STRING);
}
cellValue = StringUtil.getString(cell.getStringCellValue().trim()) ;
}
if(j == 0) {
//이름
boolean nmChk = getNameRepLenChk("name", cellValue);
if(nmChk && errSts) {
jm.put("name", cellValue);
}else {
errNameCnt++;
errSts = false;
break;
}
}
if(j == 1) {
//전화번호
if(errSts) {
jm.put("phone", cellValue);
}else {
errPhoneCnt++;
errSts = false;
break;
}
}
}
if(null != jm.get("phone") && errSts) {
json.add(jm);
}
}
int resultErrCnt = errPhoneCnt + errNameCnt;
int resultErrCntExceptPhone = errPhoneCnt + errNameCnt;
jr.setData(json);
jr.setSuccess(true);
if(resultErrCnt > 0) {
jr.setMessage("유효하지 않은 형식의 전화번호 "+ errPhoneCnt +"건,\n이름 : 20byte 제한글자수 초과 "+ resultErrCntExceptPhone +"건 있습니다.\n해당 건을 제외하고 추가됩니다.");
}else {
jr.setMessage("");
}
}else { //확장자가 xlsx
OPCPackage opcPackage = OPCPackage.open(files.get(0).getInputStream());
XSSFWorkbook workbook = new XSSFWorkbook(opcPackage);
XSSFSheet sheet = workbook.getSheetAt(0); // 첫번째 시트 불러오기
opcPackage.close();
if(sheet.getLastRowNum() > 20000) { //
errMessage = "20000건 이상의 업로드는 데이터 부하로 업로드 할수 없습니다.";
jr.setSuccess(false);
jr.setMessage(errMessage);
return jr;
}
List<HashMap<String, String>> json = new ArrayList<HashMap<String, String>>();
PhoneVO pVO = new PhoneVO();
for(int i=2; i< sheet.getLastRowNum() + 2; i++){ //먼저 밸리데이션 체크(1줄은 생략)
XSSFRow row = sheet.getRow(i); //열읽기
if(null == row) {
continue;
}
HashMap<String, String> jm = new HashMap<>();
// 행의 두번째 열(이름부터 받아오기)
XSSFCell cell = null;
boolean errSts = true;
for(int j = 0 ; j < 2; j++){ //행읽기(6행까지나 2행까지만 필요)
cellValue = "";
cell = row.getCell(j); //이름/수신번호
if(null == cell || "".equals(cell.toString().trim())) { //셀에 값이 없으면
if(j == 1) {
if (sheet.getLastRowNum() == i) {
continue;
}
break;
}
}
if(null != cell){
switch(cell.getCellType()){ //숫자타임을 문자로 변환
case Cell.CELL_TYPE_NUMERIC:
cell.setCellType(Cell.CELL_TYPE_STRING);
}
cellValue = StringUtil.getString(cell.getStringCellValue().trim()) ;
}
if(j == 0) {
//이름
boolean nmChk = getNameRepLenChk("name", cellValue);
if(nmChk && errSts) {
jm.put("name", cellValue);
}else {
errNameCnt++;
errSts = false;
break;
}
}
if(j == 1) {
//수신번호
if(errSts) {
jm.put("phone", cellValue);
}else {
errPhoneCnt++;
errSts = false;
break;
}
}
}
if(null != jm.get("phone") && errSts) {
json.add(jm);
}
}
int resultErrCnt = errPhoneCnt + errNameCnt;
int resultErrCntExceptPhone = errPhoneCnt + errNameCnt;
jr.setData(json);
jr.setSuccess(true);
if(resultErrCnt > 0) {
jr.setMessage("유효하지 않은 형식의 전화번호 "+ errPhoneCnt +"건,\n이름 : 20byte 제한글자수 초과 "+ resultErrCntExceptPhone +"건 있습니다.\n해당 건을 제외하고 추가됩니다.");
}else {
jr.setMessage("");
}
} //xlsx 처리 끝
} catch (Exception e) {
jr.setMessage("처리 중 오류가 발생했습니다. 관리자에게 문의하세요.");
}
}
}
return jr;
}
public static void getExcelForFaxSendList(List<FaxGroupDataVO> faxGroupListVO) {
HttpServletResponse response =ContextUtil.getResponse();
// 메모리에 100개의 행을 유지합니다. 행의 수가 넘으면 디스크에 적습니다.
SXSSFWorkbook wb = new SXSSFWorkbook();
String fileName ="팩스 발송 내역"; // 저장 파일명
String sheetTitle = "팩스 발송 내역" ; // 셀 제목
Sheet sheet = wb.createSheet(sheetTitle);
Cell cell = null;
Row row = null;
CellStyle style = wb.createCellStyle();
style.setBorderBottom(CellStyle.BORDER_THIN); //테두리 두껍게
style.setBorderLeft(CellStyle.BORDER_THIN);
style.setBorderRight(CellStyle.BORDER_THIN);
style.setBorderTop(CellStyle.BORDER_THIN);
// 정렬
style.setAlignment(CellStyle.ALIGN_CENTER); //가운데 정렬
style.setVerticalAlignment(CellStyle.VERTICAL_CENTER); //높이 가운데 정렬
Font font = wb.createFont();
font.setBoldweight(Font.BOLDWEIGHT_BOLD); //글씨 bold
try{
//발송 성공,실패 건수 불러오기
row = sheet.createRow(0);
sheet.setColumnWidth(1, 7000); // 발송형태 칼럼의 폭 조절
sheet.setColumnWidth(2, 5000); // 접수일자 칼럼의 폭 조절
//셀병합 처리
sheet.addMergedRegion(new CellRangeAddress(0,1,0,0)); //번호 세로 셀병합
sheet.addMergedRegion(new CellRangeAddress(0,1,1,1)); //발송상태 세로 셀병합
sheet.addMergedRegion(new CellRangeAddress(0,1,2,2)); //접수일자 세로 셀병합
sheet.addMergedRegion(new CellRangeAddress(0,1,3,3)); //예약일자 세로 셀병합
sheet.addMergedRegion(new CellRangeAddress(0,1,4,4)); //형태 세로 셀병합
cell = row.createCell(0);
cell.setCellValue("번호");
cell.setCellStyle(style);
cell = row.createCell(1);
cell.setCellValue("제목");
cell.setCellStyle(style);
cell = row.createCell(2);
cell.setCellValue("전송시간");
cell.setCellStyle(style);
cell = row.createCell(3);
cell.setCellValue("문서 매수");
cell.setCellStyle(style);
cell = row.createCell(4);
cell.setCellValue("발송 건수");
cell.setCellStyle(style);
cell = row.createCell(5);
cell.setCellValue("발송결과 건수");
sheet.addMergedRegion(new CellRangeAddress(0,0,5,6)); // 발송결과 건수 가로 셀병합
cell.setCellStyle(style);
cell = row.createCell(6);
cell.setCellStyle(style);
row = sheet.createRow(1);
cell = row.createCell(0);
cell.setCellStyle(style);
cell = row.createCell(1);
cell.setCellStyle(style);
cell = row.createCell(2);
cell.setCellStyle(style);
cell = row.createCell(3);
cell.setCellStyle(style);
cell = row.createCell(4);
cell.setCellStyle(style);
cell = row.createCell(5);
cell.setCellValue("성공");
cell.setCellStyle(style);
cell = row.createCell(6);
cell.setCellValue("실패");
cell.setCellStyle(style);
int rowNum = 2;
for(FaxGroupDataVO faxGroupDataVO : faxGroupListVO) {
row = sheet.createRow(rowNum);
cell = row.createCell(0);
cell.setCellStyle(style);
cell.setCellValue(rowNum-1);
cell = row.createCell(1);
cell.setCellStyle(style);
cell.setCellValue(faxGroupDataVO.getSubject());
cell = row.createCell(2);
cell.setCellStyle(style);
cell.setCellValue(faxGroupDataVO.getDoneDate());
cell = row.createCell(3);
cell.setCellStyle(style);
cell.setCellValue(faxGroupDataVO.getPage());
cell = row.createCell(4);
cell.setCellStyle(style);
cell.setCellValue(faxGroupDataVO.getTotalEa());
cell = row.createCell(5);
cell.setCellStyle(style);
cell.setCellValue(faxGroupDataVO.getSentEa());
cell = row.createCell(6);
cell.setCellStyle(style);
cell.setCellValue(faxGroupDataVO.getHoldEa()+faxGroupDataVO.getUnSendEa()+faxGroupDataVO.getErrorEa());
rowNum++;
}
response.setHeader("Set-Cookie", "fileDownload=true; path=/");
SimpleDateFormat mSimpleDateFormat = new SimpleDateFormat ( "yyyyMMdd_HHmmss", Locale.KOREA );
Date currentTime = new Date ();
String mTime = mSimpleDateFormat.format ( currentTime );
fileName = fileName+"("+mTime+")";
response.setHeader("Content-Disposition", String.format("attachment; filename=\""+new String((fileName).getBytes("KSC5601"),"8859_1")+".xlsx"));
wb.write(response.getOutputStream());
}catch(Exception e) {
response.setHeader("Set-Cookie", "fileDownload=false; path=/");
response.setHeader("Cache-Control", "no-cache, no-store, must-revalidate");
response.setHeader("Content-Type","text/html; charset=utf-8");
OutputStream out = null;
try {
out = response.getOutputStream();
byte[] data = new String("fail..").getBytes();
out.write(data, 0, data.length);
} catch(Exception ignore) {
ignore.printStackTrace();
} finally {
if(out != null) try { out.close(); } catch(Exception ignore) {}
}
}finally {
// 디스크 적었던 임시파일을 제거합니다.
wb.dispose();
try { wb.close(); } catch(Exception ignore) {}
}
}
/*====================================================================
= private function zone =
====================================================================*/
// 팩스 엑셀 업로드 이름 길이 체크
private static boolean getNameRepLenChk(String type, String value) {
boolean rtnValue = true;
if(type.equals("name")) {
String tmpNm = value;
int nmLen = tmpNm.length();
if(nmLen > 12) {
rtnValue = false;
}
}else if(type.equals("rep")) {
String tmpRep = value;
int repLen = tmpRep.length();
if(repLen > 20) {
rtnValue = false;
}
}
return rtnValue;
}
}