지난 엑셀 다루기 포스팅에 이어 Apache POI를 이용하여 워드에 데이터를 입력하는 방법에 대해 포스팅하려고 합니다.
Maven 추가 및 Apache POI에 대한 내용은 지난 글을 확인해주세요.
테스트 시나리오는 다음과 같습니다.
- 웹에서 데이터 입력
- 웹에서 입력된 데이터가 워드 샘플 파일에 저장
- 저장된 워드 파일 다운로드
테스트를 위한 샘플 파일과 입력 화면을 만들었습니다.
데이터 전송은 POST 방식 Submit으로 넘깁니다.
ex04.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<!DOCTYPE html>
<html>
<head>
<title>Apache POI Example</title>
<%@ include file="/WEB-INF/views/include/source.jsp" %>
<script>
$(document).ready(function() {
$("#testForm").submit(function(event){
var url = $("#testForm").attr("action");
var data = $("#testForm").serialize();
$.post(url, data).done();
});
});
</script>
</head>
<body>
<form id="testForm" action="/apachepoi/goToWord.do" method="post">
<div class="container">
<div class="row border-bottom mb-3">
<div class="col-12">
<p class="h1">EX04. Apache POI Word 데이터 쓰기</p>
</div>
</div>
<div class="row">
<div class="col-4">
<div class="input-group mb-3">
<div class="input-group-prepend">
<span class="input-group-text">성명</span>
</div>
<input type="text" class="form-control" id="name" name="name">
</div>
<div class="input-group mb-3">
<div class="input-group-prepend">
<span class="input-group-text">메일</span>
</div>
<input type="text" class="form-control" id="email" name="email">
</div>
</div>
<div class="col-12">
<button type="submit" class="btn btn-primary">제출</button>
</div>
</div>
</div>
<%@ include file="/WEB-INF/views/common/bottom.jsp" %>
</form>
</body>
</html>
서버단에 넘어와서,
ApachePOIController.java
@RequestMapping(value = "/apachepoi/goToWord.do", method = { RequestMethod.GET,RequestMethod.POST })
public ModelAndView goToWord(Model model, @RequestParam HashMap<String, Object> paramMap) throws Exception {
String sample = PATH + "ex04.docx";
FileOutputStream fos = null;
try {
File file = new File(sample);
XWPFDocument doc = new XWPFDocument(new FileInputStream(file));
XWPFTable table = null;
// -------- 테이블 요소 구하기
Iterator<IBodyElement> docElementsIterator = doc.getBodyElementsIterator();
while(docElementsIterator.hasNext()) {
IBodyElement docElement = docElementsIterator.next();
if("TABLE".equalsIgnoreCase(docElement.getElementType().name())) {
List<XWPFTable> xwpfTableList = docElement.getBody().getTables();
table = xwpfTableList.get(0);
}
}
// ----------------------------
String name = (String) paramMap.get("name");
String email = (String) paramMap.get("email");
XWPFTableRow row = null;
row = table.getRow(0);
row.getCell(1).setText(name);
row = table.getRow(1);
row.getCell(1).setText(email);
fos = new FileOutputStream(new File(sample));
doc.write(fos);
if(fos != null) fos.close();
} catch (Exception e) {
e.printStackTrace();
}
File file = new File(sample);
return new ModelAndView("download", "downloadFile", file);
}
(9번 라인) XWPFDocument 클래스를 사용하여 샘플 파일의 도큐먼트 객체를 생성합니다.
(13번 라인~) 샘플 파일인 워드 문서에서 테이블 요소를 찾는 소스입니다.
getBodyEelementsIterator() 함수는 문서의 단락과 테이블을 읽어옵니다.
루프를 돌며 테이블 요소를 찾아 XWPFTable 객체를 생성하면 테이블 요소에 접근이 가능합니다.(getElementType().name() 함수를 사용하여 요소 이름을 가져올 수 있었습니다)
(20번 라인) 여기서는 하나의 테이블로 가정하고 소스를 작성했기 때문에 여러개의 테이블에 데이터를 넣고 싶다면 커스터마이징이 필요합니다.
(30번 라인) XWPFTableRow 클래스를 사용해 테이블 각 행에 데이터를 입력합니다.
(36~37번 라인) 데이터가 입력된 파일을 FileOutputStream으로 생성해주고 생성된 파일은 다운로드를 처리하는 ModelAndView 객체에 저장합니다.
[결과]
본 예제에서는 단순히 샘플 파일에 데이터를 입력하는 것이었습니다.
데이터가 입력된 샘플 파일을 다운로드하는 방식이기 때문에 데이터가 입력되면 샘플 파일이 변하게 됩니다. 이 부분은 다른 방법으로 해결할 수 있습니다. (샘플 파일을 복사한 후에 복사된 파일에 데이터를 입력하고 다운로드 이후에 삭제하는 방법등)
전체 소스는 Github에서 확인하실 수 있습니다 :)