파일 업로드 및 대용량 엑셀 다운로드
파일 업로드
2
3
Component를 사용한 유효성 검증 예시
export default function Upload() {
const { setValue } = useFormContext();
const validator = <T extends File>(file: T) => {
const fileType = file.type;
const fileSize = file.size;
const validTypes = Object.keys(UPLOAD_IMAGE_ACCEPT);
if (!validTypes.includes(fileType)) {
return { message: '확장자가 올바르지 않습니다.', code: 'ERR_TYPE' };
}
if (GOODS_UPLOAD.MAX_IMAGE_SIZE < fileSize) {
return { message: '최대 용량을 초과하였습니다.', code: 'ERR_SIZE' };
}
return null;
};
const onUpload = (files: File[]) => {
setValue('File', files);
};
const onDelete = () => {
setValue('File', null);
};
return (
<Field.Upload
name="fileUpload"
accept={UPLOAD_IMAGE_ACCEPT}
validator={validator}
onDelete={onDelete}
onDrop={onUpload}
/>
);
}4
업로드 관련 상수 예시
export const UPLOAD_IMAGE_ACCEPT = {
'image/png': [],
'image/jpg': [],
'image/jpeg': [],
'image/gif': []
};
export const UPLOAD_VIDEO_ACCEPT = {
'video/mp4': [],
'video/avi': [],
'video/mov': []
};
// 전시
export const DISPLAY_UPLOAD = {
MAX_IMAGE_SIZE: 10485760,
MAX_VIDEO_SIZE: 104857600
};
// 상품
export const GOODS_UPLOAD = {
MAX_IMAGE_SIZE: 10485760,
MAX_VIDEO_SIZE: 104857600
};5
API 저장소 설정 (Spring Boot applcation.yml 예시)
upload:
type: s3 # file : WAS / NAS, ftp : FTP, s3 : AWS S3, azure : Azure Blob Storage
root-path: files/ # 파일업로드 시 저장될 경로를 설정합니다.
file:
base-path: /data/ # was의 기본 업로드 경로 또는 mount 되는 nas의 기본 경로를 설정합니다.
base-path-video: /data/video
ftp:
host: 192.168.2.247
user: test
password: test
azure:
connection: DefaultEndpointsProtocol=https;AccountName=testblob;AccountKey=....
container: test
# aws의 경우에는 스프링에서 정한 설정 변수를 사용함.
cloud:
aws:
s3:
bucket: x2bee-stg-pri-attachment-s3
s3-video-origin:
bucket: x2bee-stg-pri-attachment-s3
region:
static: ap-northeast-2
stack:
auto: false6
Spring Uploader Bean 설정 예시 (UploaderConfig.java)
package com.x2bee.api.common.base.config;
import com.x2bee.common.base.upload.UploaderCommonImpl;
import com.x2bee.common.base.upload.Uploader;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
@Configuration
public class UploaderConfig {
@Autowired
private Environment env;
@Value("${upload.file.base-path:#{null}}")
private String basePath;
@Value("${upload.file.base-path-video:#{null}}")
private String videoBasePath;
@Value("${upload.ftp.host:}")
private String ftpHost;
@Value("${upload.ftp.user:}")
private String ftpUser;
@Value("${upload.ftp.password:}")
private String ftpPassword;
@Value("${cloud.aws.region.static:#{null}}")
private String awsRegion;
@Value("${cloud.aws.s3.bucket:#{null}}")
private String bucket;
@Value("${cloud.aws.s3-video-origin.bucket:#{null}}")
private String videoBucket;
@Value("${upload.azure.connection:#{null}}")
private String azureConnection;
@Value("${upload.azure.container:#{null}}")
private String azureContainer;
@Bean(name = "uploader")
// apllication.yml 설정값으로 bean 모듈을 생성하여 파일업로드를 합니다.
public Uploader uploader() {
return new UploaderCommonImpl.Builder(env)
.basePath(basePath)
.ftpHost(ftpHost)
.ftpUser(ftpUser)
.ftpPassword(ftpPassword)
.awsRegion(awsRegion)
.bucket(bucket)
.azureConnection(azureConnection)
.azureContainer(azureContainer)
.build();
}
@Bean(name = "videoUploader")
public Uploader videoUploader() {
return new UploaderCommonImpl.Builder(env)
.basePath(videoBasePath)
.ftpHost(ftpHost)
.ftpUser(ftpUser)
.ftpPassword(ftpPassword)
.awsRegion(awsRegion)
.bucket(videoBucket)
.build();
}
}7
SampleServiceImpl.java 예시 (서버 업로드 처리)
@Service
@Slf4j
@RequiredArgsConstructor
public class SampleServiceImpl implements SampleService {
@Qualifier("uploader")
private final Uploader uploader;
@Qualifier("videoUploader")
private final Uploader videoUploader;
@Qualifier("fileuUploader")
private final Uploader fileuUploader;
@Override
public String fileUpload(HttpServletRequest httpServletRequest) throws Exception {
AtomicReference<String> result = new AtomicReference<>("");
MultipartHelper.handle(httpServletRequest, (fieldName, fileName, fileSize, inputStream, multipartFile) -> {
UploadReqDto uploadReqDto = new UploadReqDto();
uploadReqDto.setAttacheFileKind(AttacheFileKind.SYSTEM);
uploadReqDto.setTempPathYn(false);
uploadReqDto.setCustomPath("");
uploadReqDto.setTypeCd("10");
// 기존 AWS에 업로드
Map<String, Object> retMap = uploader.upload(multipartFile, uploadReqDto); // UploaderConfig Bean 모듈 호출
log.debug("fileUpload : {}", retMap);
UploadResDto uploadResDto = (UploadResDto)((Map<String, Object>)retMap.get("data")).get("data");
result.set(uploadResDto.getUrl());
log.debug("url : {}", uploadResDto.getUrl());
// 기존 AWS 비디오 공간에 업로드
videoUploader.upload(multipartFile, uploadReqDto);
// 파일 시스템에 업로드
fileUploader.upload(multipartFile, uploadReqDto);
});
return result.get();
}
}대용량 엑셀 다운로드
1
2
MyBatis XML 쿼리 예시 (Sample.xml)
<!--Dto, Xml 예제-->
<select id="getZipNoList" parameterType="SampleZipNoMgmtRequest" resultType="SampleZipNoMgmtResponse" >
WITH TMP1 AS (
SELECT ZIP_NO_SEQ, ZIP_NO, CTP_NM, SIG_NM, HEMD_NM, LNBR_MNNM, LNBR_SLNO, ROAD_NM
FROM ST_ZIP_NO
WHERE USE_YN = 'Y'
<if test="ctpNmParam != null and ctpNmParam != ''">
AND CTP_NM = #{ctpNmParam}
</if>
<if test="sigNmParam != null and sigNmParam != ''">
AND SIG_NM LIKE '%' || #{sigNmParam}
</if>
)
SELECT ZIP_NO_SEQ, ZIP_NO, CTP_NM, SIG_NM, HEMD_NM, LNBR_MNNM, LNBR_SLNO, ROAD_NM
FROM TMP1
ORDER BY 1
LIMIT 1000000
</select>3
4
Service 구현 예시 (ExcelUtil.createCursorExcel)
/* SampleServiceImpl.java */
@ExcelDownLoad
public void exceldown(SampleZipNoMgmtRequest sampleZipNoMgmtRequest) {
// sample 1
ExcelUtil.createCursorExcel(() -> sampleMapper.getZipNoList(sampleZipNoMgmtRequest));
// sample 2 (추가 옵션)
ExcelUtil.createCursorExcel(
() -> sampleMapper.getZipNoList(zipNoMgmtRequest),
ExcelEntity.builder()
.fileName("TRGMN_LIST")
.sheetName("SHEET1")
.build()
);
}downloadStaticFile({
method: 'get',
fileUrl: '/api/bo/v1/sample/exceldown',
downloadedFileName: '파일명'
});Attachments
마지막 업데이트