728x90
반응형
canvas로 이루어져 있는 차트 이미지를 엑셀 파일에 삽입해보겠습니다.
toDataURL()을 사용하여 원하는 영역을 base64 문자열로 읽어 back단에 데이터를 전달합니다.
const imageData = $("#load-graph").find("canvas")[0].toDataURL("image/png", 0.5);
만약 canvas로 그려지지 않은 영역을 이미지로 저장하고 싶다면, html2canvas.js 라이브러리를 사용하여 html 영역을 canvas로 변경하면 됩니다.
html2canvas($("#chart")[0]).then(function(canvas) {
const imageData = canvas.toDataURL("image/png");
...
엑셀에 이미지 삽입하는 부분입니다.
@Slf4j
@Service
public class ExcelServiceImpl implements ExcelService {
@Value("${download.dir}")
private String fileCommonPath;
//png 파일 base64 인코딩 pre fix 제거를 위한 변수 선언
private static final String BASE64_PNG_PRE_FIX = "data:image/png;base64,";
private int rowCount;
private int cellCount;
// (...생략...)
private void setChart(SXSSFWorkbook workBook, SXSSFSheet sheet, String imageData)
FileUtils.forceMkdir(new File(fileCommonPath)); //디렉토리 미 존재시 생성
File imageFile = new File(fileCommonPath + "/chartImg.png");
try (FileOutputStream fos = new FileOutputStream(imageFile);
InputStream in = new FileInputStream(imageFile)) {
String encodingStr = imageData.replace(BASE64_PNG_PRE_FIX, "");
byte[] decodeImg = Base64.decodeBase64(encodingStr);
fos.write(decodeImg);
byte[] bytes = IOUtils.toByteArray(in);
int pictureIdx = workBook.addPicture(bytes, SXSSFWorkbook.PICTURE_TYPE_PNG);
final CreationHelper helper = workBook.getCreationHelper();
final Drawing drawing = sheet.createDrawingPatriarch();
final ClientAnchor anchor = helper.createClientAnchor();
// 이미지를 출력할 CELL 위치 선정
cellCount = 0;
anchor.setCol1(cellCount);
anchor.setRow1(rowCount);
// 이미지 그리기
final Picture pict = drawing.createPicture(anchor, pictureIdx);
// 이미지 사이즈 비율 설정
pict.resize();
ClientAnchor preferredSize = pict.getPreferredSize();
cellCount = preferredSize.getCol2() + 1;
rowCount = preferredSize.getRow2() + 1;
} catch(Exception e) {
e.printStackTrace();
log.error(e.getMessage(), e);
} finally {
FileUtils.deleteQuietly(imageFile);
}
}
}
더보기
@Slf4j
@Service
public class ExcelServiceImpl implements ExcelService {
@Value("${download.dir}")
private String fileCommonPath;
//png 파일 base64 인코딩 pre fix 제거를 위한 변수 선언
private static final String BASE64_PNG_PRE_FIX = "data:image/png;base64,";
private int rowCount;
private int cellCount;
@Override
public void downloadExcel(ExcelReq param, HttpServletResponse response) throws Exception {
// init
SXSSFWorkbook workBook = new SXSSFWorkbook();
workBook.setCompressTempFiles(true);
SXSSFSheet sheet = workBook.createSheet(param.getFileName());
sheet.setRandomAccessWindowSize(100);
rowCount = 0;
cellCount = 0;
// data setting
this.setTitle(workBook, sheet, param);
this.setChart(workBook, sheet, param.getImageData());
this.setData(workBook, sheet, param);
// file download
String fullpath = this.getFilePath(param.getFileName());
this.write(workBook, fullpath);
this.downloadExcelFileToWeb(new File(fullpath), response);
}
// (...생략...)
private void setChart(SXSSFWorkbook workBook, SXSSFSheet sheet, String imageData)
FileUtils.forceMkdir(new File(fileCommonPath)); //디렉토리 미 존재시 생성
File imageFile = new File(fileCommonPath + "/chartImg.png");
try (FileOutputStream fos = new FileOutputStream(imageFile);
InputStream in = new FileInputStream(imageFile)) {
String encodingStr = imageData.replace(BASE64_PNG_PRE_FIX, "");
byte[] decodeImg = Base64.decodeBase64(encodingStr);
fos.write(decodeImg);
byte[] bytes = IOUtils.toByteArray(in);
int pictureIdx = workBook.addPicture(bytes, SXSSFWorkbook.PICTURE_TYPE_PNG);
final CreationHelper helper = workBook.getCreationHelper();
final Drawing drawing = sheet.createDrawingPatriarch();
final ClientAnchor anchor = helper.createClientAnchor();
// 이미지를 출력할 CELL 위치 선정
cellCount = 0;
anchor.setCol1(cellCount);
anchor.setRow1(rowCount);
// 이미지 그리기
final Picture pict = drawing.createPicture(anchor, pictureIdx);
// 이미지 사이즈 비율 설정
pict.resize();
ClientAnchor preferredSize = pict.getPreferredSize();
cellCount = preferredSize.getCol2() + 1;
rowCount = preferredSize.getRow2() + 1;
} catch(Exception e) {
e.printStackTrace();
log.error(e.getMessage(), e);
} finally {
FileUtils.deleteQuietly(imageFile);
}
}
private void write(SXSSFWorkbook workBook, String fullPath) throws Exception {
// file write
FileOutputStream fos = null;
try {
fos = new FileOutputStream(fullPath);
workBook.write(fos);
} finally {
IOUtils.closeQuietly(fos);
IOUtils.closeQuietly(workBook);
}
}
private void downloadExcelFileToWeb(File excelFile, HttpServletResponse res) {
if (excelFile == null || excelFile.exists() == false) {
throw new IllegalArgumentException("invalid excelFile path");
}
String fileNm = FilenameUtils.getName(excelFile.getAbsolutePath());
res.setContentType("applicaiton/vnd.ms-excel;charset=utf-8");
res.setHeader("Content-Disposition", "attachment;filename=\"" + fileNm + "\";");
OutputStream out = null;
FileInputStream fis = null;
try {
out = res.getOutputStream();
fis = new FileInputStream(excelFile);
FileCopyUtils.copy(fis, out); //buffer copy
out.flush();
} catch (Exception e) {
throw new RuntimeException(e.getMessage());
} finally {
IOUtils.closeQuietly(fis);
IOUtils.closeQuietly(out);
excelFile.delete();
}
}
}
아래는 결과물입니다.
+)
private void setCellStyle(SXSSFWorkbook workBook, CellStyle cell, int fontSize) {
Font fontStyle = workBook.createFont();
fontStyle.setBold(true); // 굵은 글씨
fontStyle.setFontHeight((short)(fontSize*20)); // 폰트 크기
CellStyle style = workBook.createCellStyle();
style.setFont(fontStyle); // font style setting
// cell에 테두리
style.setBorderTop(BorderStyle.THIN);
style.setBorderBottom(BorderStyle.THIN);
style.setBorderLeft(BorderStyle.THIN);
style.setBorderRight(BorderStyle.THIN);
// 가운데 정렬
style.setAlignment(HorizontalAlignment.CENTER);
// 배경색 설정
style.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex());
style.setFillPattern(FillPatternType.SOLID_FOREGROUND);
// cell에 style 설정
cell.setCellStyle(style);
}
728x90
반응형
'java' 카테고리의 다른 글
[JAVA] 파일 암호화 (Encrypt file using java) (0) | 2021.11.01 |
---|---|
[Java] LocalDateTime format to string, LocalDateTime parse string (0) | 2021.06.11 |
[java] Enum Hierarchy(계층 구조) getChildren, getParent (0) | 2021.02.02 |
[java] 쿠키 생성, 삭제와 browser's cookie max size (0) | 2021.01.08 |
[Java8] 중복 데이터 제거를 위한 Stream distinct (0) | 2020.10.31 |
댓글