현재 제이쿼리 DataTable을 사용하고 있는 상태
데이터 테이블에서 값을 받아서
자바로 보내서 apache poi로 암호화된 엑셀파일을 클라이언트측에서 다운로드 되도록 하는것이 목표
$('#btnExcel').on('click', function () {
if(!password || !password.replace(/ /g, '')){
alert('비밀번호 입력은 필수입니다.');
return;
}else {
var tableData = $('#testMemberList').DataTable().data().toArray();
$.ajax({
url: '/example/test/excel',
method: 'POST',
data: UTIL.makeParam({'tableData':tableData,'passWord':password}),
xhrFields: {
responseType: "blob" // 바이너리 데이터로 응답 받기 위해 설정
},
success: function(data) {
// 다운로드 링크 생성
var downloadLink = document.createElement("a");
var url = window.URL.createObjectURL(new Blob([data]));
downloadLink.href = url;
downloadLink.download = "회원정보.xlsx";
// 다운로드 트리거
document.body.appendChild(downloadLink);
downloadLink.click();
document.body.removeChild(downloadLink);
// URL 객체 해제
window.URL.revokeObjectURL(url);
}
});
}
}
});
이렇게 진행했을 때
DataTable에서 커스텀된 값대로 들어오는게 아니라
전체 데이터가 순서도 섞여서 들어오게 된다.
순서, 지정된 타이틀, 값이 json 형태로 자바로 넘겨지도록 데이터 정제가 필요하다.
타이틀과 타이틀 순서를 list 에 담았다
var visibleColumns = table.columns({ 'visible': true }).indexes().toArray();
var columnData = table.columns().header().toArray();
var titles = [];
visibleColumns.forEach(function (index) {
var rowObject = {};
var columnTitle = columnData[index].innerText;
rowObject = { 'index': index, 'title': columnTitle };
titles.push(rowObject);
});
XSSFWorkbook workbook = new XSSFWorkbook(); //워크북 생성
workbook.getCTWorkbook().getWorkbookPr().setCodeName("UTF-8");
XSSFSheet sheet = workbook.createSheet("sheetName"); //시트 생성
Row headerRow = sheet.createRow(0); //헤더 로우 생성
//헤더 로우 셀 입력은 아래 셀 꾸미기에서 참고
for (int i = 0; i < tableData.size(); i++) {
Row dataRow = sheet.createRow(i + 1); //로우 생성
HashMap<String, String> data = tableData.get(i);
cellValueList.add(data.get("name") != null && !data.get("name").equals("null") ? data.get("name").toString() : "");
// 나머지 로우 value 기입
for (int idx = 0; idx < cellValueList.size(); idx++) {
String value = cellValueList.get(idx);
Cell cell = dataRow.createCell(idx);
cell.setCellValue(value);
cell.setCellStyle(cellStyle);
}
}
ByteArrayOutputStream file = new ByteArrayOutputStream();
workbook.write(file);
InputStream fileIn = new ByteArrayInputStream(file.toByteArray());
POIFSFileSystem fs = new POIFSFileSystem();
//비밀번호 세팅
EncryptionInfo info = new EncryptionInfo(EncryptionMode.agile);
Encryptor enc = info.getEncryptor();
enc.confirmPassword(password);
OPCPackage opc = OPCPackage.open(fileIn);
OutputStream os = enc.getDataStream(fs);
opc.save(os);
opc.close();
res.setCharacterEncoding("UTF-8");
res.setContentType("application/vnd.ms-excel");
res.setHeader("Content-Disposition", "attachment;filename=excel.xlsx");
OutputStream fileOut = res.getOutputStream();
fs.writeFilesystem(fileOut);
fileOut.close();
file.close();
CellStyle titleStyle = workbook.createCellStyle();
titleStyle.setBorderTop(BorderStyle.THIN);
titleStyle.setBorderBottom(BorderStyle.THIN);
titleStyle.setBorderLeft(BorderStyle.THIN);
titleStyle.setBorderRight(BorderStyle.THIN);
titleStyle.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex());
titleStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
titleStyle.setAlignment(HorizontalAlignment.CENTER);
셀 스타일은 이런식으로 정할 수 있다
setBorderTop ~ Right 는 테두리를 지정하는 것
FillForegroundColor 는 배경색
Fillpattern 은 배경색 타입
Alignment 는 텍스트 정렬이다 .
적용하는 법은 아래와 같다
// 각 셀에 데이터와 스타일 적용
for (HashMap<String, String> title : titles) {
int index = Integer.parseInt(title.get("index"));
String headerTitle = title.get("title");
Cell cell = headerRow.createCell(index);
cell.setCellValue(headerTitle);
cell.setCellStyle(style);
}