작업순서는 다음과 같습니다.
- 사용자(클라이언트, 크롬 등 웹브라우저 이용하는 사람)는 이미지파일을 브라우저에서 업로드한다.
- 서버에서 그 이미지를 받아서 파워포인트 파일에 삽입한다.
- 만들어진 파워포인트 파일을 다시 사용자한테 반환한다. 사용자는 다운로드 받을 수 있다.
파워포인트는 org.apache.poi 라는 라이브러리를 사용해 만들 수 있으며 depency는 다음과 같습니다.
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>3.17</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>3.17</version>
</dependency>
코드는 다음과 같습니다. 이미지 업로드 과정 일부는 예전 글(링크)에서 설명하고 있으니 참고해주세요. PPT 관련 부분은 createPptx 메소드에 있습니다.
package com.example.thymeleaf;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.net.URLEncoder;
import javax.imageio.ImageIO;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.poi.sl.usermodel.PictureData.PictureType;
import org.apache.poi.xslf.usermodel.SlideLayout;
import org.apache.poi.xslf.usermodel.XMLSlideShow;
import org.apache.poi.xslf.usermodel.XSLFAutoShape;
import org.apache.poi.xslf.usermodel.XSLFPictureData;
import org.apache.poi.xslf.usermodel.XSLFPictureShape;
import org.apache.poi.xslf.usermodel.XSLFShape;
import org.apache.poi.xslf.usermodel.XSLFSlide;
import org.apache.poi.xslf.usermodel.XSLFSlideLayout;
import org.apache.poi.xslf.usermodel.XSLFSlideMaster;
import org.apache.poi.xslf.usermodel.XSLFTextShape;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
@Controller
public class OfficeController {
@RequestMapping("imgToPptx")
public String imgToPptx() {
return "imgToPptx";
}
@RequestMapping("sendImg")
@ResponseBody
public void imageHandler(MultipartFile[] imgFile,
HttpServletResponse res, HttpServletRequest req) throws Exception {
System.out.println(imgFile.length);
File f =
createPptx(imgFile[0].getOriginalFilename(), imgFile[0].getBytes(), imgFile[0].getContentType());
String downloadName = null;
String browser = req.getHeader("User-Agent");
//파일 인코딩
if(browser.contains("MSIE") || browser.contains("Trident")
|| browser.contains("Chrome")){
//브라우저 확인 파일명 encode
downloadName = URLEncoder.encode(f.getName(), "UTF-8").replaceAll("\\+", "%20");
}else{
downloadName = new String(f.getName().getBytes("UTF-8"), "ISO-8859-1");
}
res.setHeader("Content-Disposition", "attachment;filename=\"" + downloadName +"\"");
res.setContentType("application/octer-stream");
res.setHeader("Content-Transfer-Encoding", "binary;");
try(FileInputStream fis = new FileInputStream(f);
ServletOutputStream sos = res.getOutputStream(); ){
byte[] b = new byte[1024];
int data = 0;
while((data=(fis.read(b, 0, b.length))) != -1){
sos.write(b, 0, data);
}
sos.flush();
} catch(Exception e) {
throw e;
}
}
private File createPptx(String title, byte[] pictureData, String fileType)
throws Exception {
// 1. 슬라이드 파일 생성
XMLSlideShow ppt = new XMLSlideShow();
ppt.createSlide();
// 2. 슬라이드 생성
XSLFSlideMaster defaultMaster = ppt.getSlideMasters().get(0);
XSLFSlideLayout layout
= defaultMaster.getLayout(SlideLayout.TITLE_AND_CONTENT);
XSLFSlide slide = ppt.createSlide(layout);
// 3. slide에서 제목 변경
XSLFTextShape titleShape = slide.getPlaceholder(0);
titleShape.setText(title);
// 4-1. 이미지 정보 (가로세로 픽셀)
InputStream in = new ByteArrayInputStream(pictureData);
BufferedImage bi = ImageIO.read(in);
// ColorModel model = bi.getColorModel();
int height = bi.getHeight();
int width = bi.getWidth();
System.out.println(fileType);
PictureType pictureType = null;
switch(fileType) {
case "image/png":
pictureType = PictureType.PNG;
break;
case "image/jpg":
case "image/jpeg":
pictureType = PictureType.JPEG;
break;
case "image/gif":
pictureType = PictureType.GIF;
break;
case "image/bmp":
pictureType = PictureType.BMP;
}
// 4-1. 이미지 삽입
XSLFPictureData pd = ppt.addPicture(pictureData, pictureType);
XSLFPictureShape picture = slide.createPicture(pd);
System.out.println(slide.getPlaceholder(1).getAnchor());
Rectangle2D anc = slide.getPlaceholder(1).getAnchor();
anc.setRect(anc.getX(), anc.getY(), width * 356 / height , 356);
picture.setAnchor(anc);
// 5. 기타 작업
for (XSLFShape shape : slide.getShapes()) {
if (shape instanceof XSLFAutoShape) {
System.out.println(shape.getShapeId() + ": "
+ ((XSLFAutoShape) shape).getText());
if(shape.getShapeId() == 3) {
slide.removeShape(shape);
}
}
}
// 맨 첫 번째 슬라이드 삭제
ppt.removeSlide(0);
FileOutputStream out = new FileOutputStream(title + ".pptx");
ppt.write(out);
out.close();
ppt.close();
return new File(title + ".pptx");
}
}
스프링 부트에서는 프론트엔드 측에서 form의 enctype을 multipart/form-data 로 지정하고, 받는 쪽 컨트롤러에서 MultipartFile[]로 지정하면 간편하게 파일을 업로드할 수 있습니다.
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Img Upload</title>
</head>
<body>
<form method=post action=sendImg enctype=multipart/form-data>
<div>
<input type=file name=imgFile id=imgHandler>
<button>전송</button>
</div>
<div>
<img id=previewImg width=500px>
</div>
</form>
<script>
var loadFile = (ev) => {
var output = document.getElementById('previewImg')
output.src = URL.createObjectURL(ev.target.files[0])
}
document.getElementById("imgHandler").onchange = loadFile
</script>
</body>
</html>







0개의 댓글