안녕하세요.
저번 포스팅에서 POI를 사용하여 엑셀 파일을 읽어오는 방법을 알아보았습니다.
이번 포스팅에서는 엑셀 파일 내의 이미지를 추출하는 방법을 알아보겠습니다.
전체 코드는 https://github.com/DevDotUng/Excel-Read 에서 확인할 수 있습니다.
기대 결과
- 엑셀 파일 내의 이미지를 원하는 경로에 저장
- 이미지 이름을 DB에 저장
- 저장한 이미지를 화면에 출력
결과 화면


1. Controller 작성
- ExcelImageController.java
package com.excel.domain.image.controller;
import com.excel.domain.image.service.ExcelImageService;
import org.apache.poi.ss.usermodel.PictureData;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.ServletContext;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
@Controller
@RequestMapping("/image")
public class ExcelImageController {
@Autowired
ServletContext ctx;
@Autowired
ExcelImageService excelImageService;
@GetMapping("")
public String getImages(Model model) {
List<String> images = excelImageService.getImages();
model.addAttribute("images", images);
return "images";
}
@PostMapping("")
public String readExcelImages(@RequestParam("excelFile") MultipartFile excelFile, Model model) throws IOException {
Workbook workbook = new XSSFWorkbook(excelFile.getInputStream());
List pictures = workbook.getAllPictures();
List<String> images = new ArrayList<>();
for (int i = 0; i < pictures.size(); i++) {
PictureData picture = (PictureData) pictures.get(i);
String ext = picture.suggestFileExtension();
byte[] data = picture.getData();
images.add(saveImage(ext, data));
}
excelImageService.saveImages(images);
model.addAttribute("images", excelImageService.getImages());
return "images";
}
String saveImage(String extension, byte[] data) throws IOException {
String uuid = UUID.randomUUID().toString();
String fileName = uuid + "." + extension;
String webPath = "/upload/dog";
String realPath = ctx.getRealPath(webPath);
File savePath = new File(realPath);
if (!savePath.exists())
savePath.mkdirs();
realPath += File.separator + fileName;
File saveFile = new File(realPath);
FileOutputStream out = new FileOutputStream(saveFile);
out.write(data);
out.close();
return fileName;
}
}
Workbook workbook = new XSSFWorkbook(excelFile.getInputStream());
List pictures = workbook.getAllPictures();
XSSFWorkbook 객체를 생성하여 모든 PictureData를 받아옵니다.
String ext = picture.suggestFileExtension();
byte[] data = picture.getData();
PictureData에서 확장자와 바이트배열 데이터를 받아옵니다.
String saveImage(String extension, byte[] data) throws IOException {
String uuid = UUID.randomUUID().toString();
String fileName = uuid + "." + extension;
String webPath = "/upload/dog";
String realPath = ctx.getRealPath(webPath);
File savePath = new File(realPath);
if (!savePath.exists())
savePath.mkdirs();
realPath += File.separator + fileName;
File saveFile = new File(realPath);
FileOutputStream out = new FileOutputStream(saveFile);
out.write(data);
out.close();
return fileName;
}
받아온 확장자와 바이트배열 데이터를 사용해 이미지를 저장해줍니다.
파일 이름은 중복 방지를 위해 UUID를 사용하여 생성해줍니다.
저장되는 경로는 [프로젝트] > src > main > webapp > upload > dog 입니다.

파일 이름을 DB에 저장해줄 수 있도록 파일 이름을 반환해줍니다.
2. Service 작성
- ExcelImageService.java
package com.excel.domain.image.service;
import java.util.List;
public interface ExcelImageService {
List<String> getImages();
void saveImages(List<String> images);
}
3. Service 구현
- ExcelImageServiceImp.java
package com.excel.domain.image.service.imp;
import com.excel.dao.ExcelImageDAO;
import com.excel.domain.image.service.ExcelImageService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class ExcelImageServiceImp implements ExcelImageService {
@Autowired
ExcelImageDAO excelImageDAO;
@Override
public List<String> getImages() {
return excelImageDAO.getImages();
}
@Override
public void saveImages(List<String> images) {
excelImageDAO.saveImages(images);
}
}
4. DAO 작성
- ExcelImageDAO.java
package com.excel.dao;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
@Mapper
public interface ExcelImageDAO {
List<String> getImages();
void saveImages(List<String> images);
}
5. Mapper 작성
- ExcelImageDaoMapper.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.excel.dao.ExcelImageDAO">
<select id="getImages" resultType="String">
SELECT CONCAT('http://localhost:8080/image/dog/', image) image
FROM images
</select>
<insert id="saveImages" parameterType="String">
INSERT INTO images(image)
VALUES
<foreach collection="list" item="image" separator=", ">
(#{image})
</foreach>
</insert>
</mapper>
6. 화면 구성
- images.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>Excel</title>
</head>
<body>
<form th:action="@{/image}" method="POST" enctype="multipart/form-data">
<input type="file" th:name="excelFile">
<input th:type="submit" value="제출" />
</form>
<br><br>
<table class="table table-striped">
<tbody>
<tr th:each="image : ${images}" >
<td>
<img th:src="${image}" width="100" height="100">
</td>
</tr>
</tbody>
</table>
</body>
</html>
전체 코드: https://github.com/DevDotUng/Excel-Read
GitHub - DevDotUng/Excel-Read: [Spring boot] POI로 엑셀 파일 읽기
[Spring boot] POI로 엑셀 파일 읽기. Contribute to DevDotUng/Excel-Read development by creating an account on GitHub.
github.com
'Spring' 카테고리의 다른 글
| [SpringBoot] Gradle 프로젝트 Jar 빌드 및 실행 (Terminal, MacOS, Linux) (0) | 2024.02.26 |
|---|---|
| [SpringBoot] Log4j2를 사용하여 로깅하기 - 로그 설정 (2) | 2024.01.04 |
| [SpringBoot] Thymeleaf란? 기본 문법과 사용법 (0) | 2023.11.29 |
| [SpringBoot] POI 를 사용하여 엑셀(.xlsx) 파일 읽기 (0) | 2023.11.14 |
| Spring boot 프로젝트 생성 (1) | 2023.09.20 |