스프링을 사용해서 pdf 생성

Back-End/Spring 2019. 6. 19. 23:21
728x90
반응형

스프링을 사용해서 pdf파일 생성해보기 



- itextpdf 라이브러리 -



   

 - 참고할만한 사이트들 -


 - http://itextpdf.com (pdf관련 예제 수록)


 - API : http://developers.itextpdf.com/examples-itext5 (pdf관련 API)






  사전 설정


  pom.xml에 pdf에 한글처리를 위해 폰트 정보를 메이븐 저장소 홈페이지에서 복사해온다.



  기본 구조


  뷰 => 컨트롤러 => Service => dto => Service => 컨트롤러 => 뷰


  1. admin_menu.jsp 에서 pdf링크를 만들어 list.do ( url )로 컨트롤러와 맵핑


  2. pdf파일을 만들기 위해 컨트롤러에서 서비스, 서비스에서 서비스 구현 클래스를 호출


3. PdfServiceImpl.java에서 pdf를 만들기 위해 createpdf메소드를 실행


     ㄱ. pdf 문서를 처리하는 객체인 Document 생성


     ㄴ. pdf 문서의 저장경로 설정, 한글폰트 처리 및 폰트의 사이즈를 따로 지정 해준다.


     ㄷ. pdf 문서에 나타날 셀을 설정하고 테이블에 집어넣는다.


     ㄹ. 타이틀을 지정하고, 가운데 정렬하고, 줄바꿈을 해준다. (타이틀이 테이블보다 위쪽에 있기 때문에)


     ㅁ. 위에서 만든 셀에 "상품명", "수량", "단가", "금액" 값을 정렬방식과 폰트를 지정해서 넣는다.


     ㅂ. 그리고 테이블에 위에서 생성시킨 셀을 넣는다.


     ㅅ. 서비스에 저장되어있던 장바구니리스트에 id값을 매개값으로 리스트에 저장


     ㅇ. 리스트에 저장한 값들을 반복문을 사용해서 하나씩 출력해서 dto에 저장한다.

          ㄱ. pdf 문서를 처리하는 객체인 Document 생성


     ㄴ. pdf 문서의 저장경로 설정, 한글폰트 처리 및 폰트의 사이즈를 따로 지정 해준다.


     ㄷ. pdf 문서에 나타날 셀을 설정하고 테이블에 집어넣는다.


     ㄹ. 타이틀을 지정하고, 가운데 정렬하고, 줄바꿈을 해준다. (타이틀이 테이블보다 위쪽에 있기 때문에)


     ㅁ. 위에서 만든 셀에 "상품명", "수량", "단가", "금액" 값을 정렬방식과 폰트를 지정해서 넣는다.


     ㅂ. 그리고 테이블에 위에서 생성시킨 셀을 넣는다.


     ㅅ. 서비스에 저장되어있던 장바구니리스트에 id값을 매개값으로 리스트에 저장


     ㅇ. 리스트에 저장한 값들을 반복문을 사용해서 하나씩 출력해서 dto에 저장한

     ㅈ. dto에 저장한 값들을 pdfCell 객체를 생성해서 cell안에 넣어준다.


     ㅊ. Cell에 저장한 데이터들을 table 안에 저장한다.

 

     ㅋ. document 객체에 table를 저장하고, 저장이 끝났으면 document객체를 닫는다.


     

  4. createpdf 메소드를 실행한 후 컨트롤러로 돌아옴


  5. 컨트롤러에서 결과값을 result.jsp에 전달해서 pdf파일이 생성되었는지, 안되었는지 확인하고 

     결과에 대한 메시지가 result.jsp 파일에 출력이 되도록 한다.




 1. 한글 처리를 위해서는 폰트 정보가 필요함


pom.xml에 라이브러리를 추가. (메이븐 저장소홈페이지에서 복사해온다.)

(https://mvnrepository.com/search?q=itextpdf&p=1)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
<!-- https://mvnrepository.com/artifact/com.itextpdf/itextpdf -->
<dependency>
    <groupId>com.itextpdf</groupId>
    <artifactId>itextpdf</artifactId>
    <version>5.5.13</version>
</dependency>
 
<!-- https://mvnrepository.com/artifact/com.itextpdf/itext-pdfa -->
<dependency>
    <groupId>com.itextpdf</groupId>
    <artifactId>itext-pdfa</artifactId>
    <version>5.5.13</version>
    <scope>test</scope>
</dependency>
 
<!-- https://mvnrepository.com/artifact/com.itextpdf/itext-xtra -->
<dependency>
    <groupId>com.itextpdf</groupId>
    <artifactId>itext-xtra</artifactId>
    <version>5.5.13</version>
</dependency>
 
<!-- https://mvnrepository.com/artifact/com.itextpdf.tool/xmlworker -->
<dependency>
    <groupId>com.itextpdf.tool</groupId>
    <artifactId>xmlworker</artifactId>
    <version>5.5.13</version>
</dependency>
 
<!-- https://mvnrepository.com/artifact/com.itextpdf/font-asian -->
<dependency>
    <groupId>com.itextpdf</groupId>
    <artifactId>font-asian</artifactId>
    <version>7.1.6</version>
    <scope>test</scope>
</dependency>
cs




2. pdf 기능을 테스트하기 위해서 관리자 메뉴 페이지에 pdf 링크 추가


admin_menu.jsp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
 
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<!-- core태그를 사용하기 위해 taglib를 사용 -->
 
<!-- 관리자로그인한 상태에서만 보이는 메뉴 -->
 
<!-- 메뉴 링크를 추가하고 PDF리스트로 갈수있는 링크도 추가 -->
<a href="${path}/shop/product/list.do">상품목록</a>
<a href="${path}/shop/product/write.do">상품등록</a>
<a href="${path}/pdf/list.do">PDF</a>
 
<c:choose>
 
    <c:when test="${sessionScope.admin_userid == null }">
        <a href="${path }/admin/login.do">관리자 로그인</a>
        <!-- 세션에 관리자 아이디의 값이 NULL일때 (즉 로그인 되어있지 않은 상태일때) -->
        <!-- 관리자 로그인 링크를 표시 -->
    </c:when>
 
 
    <c:otherwise>
${sessionScope.admin_name}님이 로그인중입니다.
<a href="${path}/admin/logout.do">로그아웃</a>
        <!-- 관리자가 로그인한 상태일때는 로그아웃 링크를 표시 -->
    </c:otherwise>
 
</c:choose>
<hr>
cs



3. PdfController.java 로 맵핑된다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
package com.example.spring02.controller.pdf;
 
import javax.inject.Inject;
 
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
 
import com.example.spring02.service.pdf.PdfService;
 
@Controller //컨트롤러 표시 어노테이션
@RequestMapping("/pdf/*")//공통주소를 맵핑
 
public class PdfController {
    
    @Inject
    PdfService pdfService;
    //서비스 객체를 사용하기 위해 의존성을 주입
    
    @RequestMapping("list.do"//View에서 맵핑 url 주소
    public ModelAndView list() throws Exception {
        String result = pdfService.createPdf(); //createPdf()메소드에서 pdf파일이 생성되었는지 결과가 result에 담긴다.
        return new ModelAndView("pdf/result","message",result); //그 결과가 message로 pdf/result페이지로 전송된다.
    }
}
cs



PdfService.java

1
2
3
4
5
6
7
package com.example.spring02.service.pdf;
 
public interface PdfService {
    public String createPdf();
    //pdf를 만드는 추상 메소드
}
 
cs



PdfServiceImpl.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
package com.example.spring02.service.pdf;
 
import java.io.FileOutputStream;
 
import javax.inject.Inject;
 
import org.springframework.stereotype.Service;
 
import com.example.spring02.model.shop.dto.CartDTO;
import com.example.spring02.service.shop.CartService;
import com.itextpdf.text.Chunk;
import com.itextpdf.text.Document;
import com.itextpdf.text.Element;
import com.itextpdf.text.Font;
import com.itextpdf.text.List;
import com.itextpdf.text.Paragraph;
import com.itextpdf.text.Phrase;
import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.text.pdf.PdfPCell;
import com.itextpdf.text.pdf.PdfPTable;
import com.itextpdf.text.pdf.PdfWriter;
 
@Service
//서비스에서는 이 어노테이션을 사용해야한다.
public class PdfServiceImpl implements PdfService {
 
    @Inject
    CartService cartService; // 장바구니에 있는 내용들을 pdf파일로 만들기 위해 장바구니 서비스객체를 사용하기 위해서 의존성을 주입시킨다.
 
    @Override
    public String createPdf() {
        String result = ""// 초기값이 null이 들어가면 오류가 발생될수 있기 때문에 공백을 지정
 
        try {
            Document document = new Document(); // pdf문서를 처리하는 객체
 
            PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream("d:/sample.pdf"));
            // pdf파일의 저장경로를 d드라이브의 sample.pdf로 한다는 뜻
 
            document.open(); // 웹페이지에 접근하는 객체를 연다
 
            BaseFont baseFont = BaseFont.createFont("c:/windows/fonts/malgun.ttf", BaseFont.IDENTITY_H,
                    BaseFont.EMBEDDED);
            // pdf가 기본적으로 한글처리가 안되기 때문에 한글폰트 처리를 따로 해주어야 한다.
            // createFont메소드에 사용할 폰트의 경로 (malgun.ttf)파일의 경로를 지정해준다.
            // 만약에 이 경로에 없을 경우엔 java파일로 만들어서 집어넣어야 한다.
 
            Font font = new Font(baseFont, 12); // 폰트의 사이즈를 12픽셀로 한다.
 
            PdfPTable table = new PdfPTable(4); // 4개의 셀을 가진 테이블 객체를 생성 (pdf파일에 나타날 테이블)
            Chunk chunk = new Chunk("장바구니", font); // 타이틀 객체를 생성 (타이틀의 이름을 장바구니로 하고 위에 있는 font를 사용)
            Paragraph ph = new Paragraph(chunk);
            ph.setAlignment(Element.ALIGN_CENTER);
            document.add(ph); // 문단을 만들어서 가운데 정렬 (타이틀의 이름을 가운데 정렬한다는 뜻)
 
            document.add(Chunk.NEWLINE);
            document.add(Chunk.NEWLINE); // 줄바꿈 (왜냐하면 타이틀에서 두줄을 내린후에 셀(테이블)이 나오기 때문)
 
            PdfPCell cell1 = new PdfPCell(new Phrase("상품명", font)); // 셀의 이름과 폰트를 지정해서 셀을 생성한다.
            cell1.setHorizontalAlignment(Element.ALIGN_CENTER); // 셀의 정렬방식을 지정한다. (가운데정렬)
 
            PdfPCell cell2 = new PdfPCell(new Phrase("단가", font));
            cell2.setHorizontalAlignment(Element.ALIGN_CENTER);
 
            PdfPCell cell3 = new PdfPCell(new Phrase("수량", font));
            cell3.setHorizontalAlignment(Element.ALIGN_CENTER);
 
            PdfPCell cell4 = new PdfPCell(new Phrase("금액", font));
            cell4.setHorizontalAlignment(Element.ALIGN_CENTER);
 
            table.addCell(cell1); // 그리고 테이블에 위에서 생성시킨 셀을 넣는다.
            table.addCell(cell2);
            table.addCell(cell3);
            table.addCell(cell4);
 
            List<CartDTO> items = cartService.listCart("park"); // 서비스로부터 id값을 매개값으로 주어서 장바구니목록을 가져온다.
 
            for (int i = 0; i < items.size(); i++) {
                CartDTO dto = items.get(i); // 레코드에 값들을 꺼내서 dto에 저장
                PdfPCell cellProductName = new PdfPCell(new Phrase(dto.getProduct_name(), font)); // 반복문을 사용해서 상품정보를 하나씩
                                                                                                    // 출력해서 셀에 넣고 테이블에
                                                                                                    // 저장한다.
 
                PdfPCell cellPrice = new PdfPCell(new Phrase("" + dto.getPrice(), font));
                // Phrase타입은 숫자형(int형 같은타입)으로 하면 에러가 발생되기 때문에 dto앞에 공백("")주어서 String타입으로 변경한다.
 
                PdfPCell cellAmount = new PdfPCell(new Phrase("" + dto.getAmount(), font));
                // Phrase타입은 숫자형(int형 같은타입)으로 하면 에러가 발생되기 때문에 dto앞에 공백("")주어서 String타입으로 변경한다.
 
                PdfPCell cellMoney = new PdfPCell(new Phrase("" + dto.getMoney(), font));
                // Phrase타입은 숫자형(int형 같은타입)으로 하면 에러가 발생되기 때문에 dto앞에 공백("")주어서 String타입으로 변경한다.
 
                table.addCell(cellProductName); // 셀의 데이터를 테이블에 저장한다. (장바구니안에 들어있는 갯수만큼 테이블이 만들어진다)
                table.addCell(cellPrice);
                table.addCell(cellAmount);
                table.addCell(cellMoney);
            }
            document.add(table); // 웹접근 객체에 table를 저장한다.
            document.close(); // 저장이 끝났으면 document객체를 닫는다.
            result = "pdf 파일이 생성되었습니다.";
 
        } catch (Exception e) {
            e.printStackTrace();
            result = "pdf 파일 생성 실패...";
        }
        return result;
    }
 
}
 
cs



result.jsp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<!-- 컨트롤러에서 pdf파일이 생성되었는지 알려주는 페이지 (메시지로 알려준다) -->
<title>Insert title here</title>
<%@ include file = "../include/header.jsp" %>
</head>
<body>
<%@ include file = "../include/admin_menu.jsp" %>
<h2>${message}</h2>
 
</body>
</html>
cs


728x90
반응형
: