티스토리 뷰

728x90

0. 이번에는 PDF 파일을 생성하는 예제이다. 사용하는 방법은 Email 모듈 작성과 동일하고 작성순서는 다음과 같다.

  0-1. maven dependency를 입력한다.

  0-2. 인터페이스, 구현체를 사용하거나 그냥 단독으로 구현 클래스를 작성한다.

  0-3. 해당 구현 기능을 사용한다.

 

1. itextpdf 의존성을 Maven에 추가한다.

 

<!-- https://mvnrepository.com/artifact/com.itextpdf/itextpdf -->
<dependency>
	<groupId>com.itextpdf</groupId>
	<artifactId>itextpdf</artifactId>
	<version>5.5.13.1</version>
</dependency>

 

2. 패키지에서 제공하는 기능을 필요에 맞게 구현한다.

  2-0. 구현 순서는 

    2-0-1. Document를 생성한다.

    2-0-2. Document와 Output Stream을 연결하여 완성된 PDF 정보를 파일로 저장되도록 한다.

    2-0-3. Document를 open한다.

    2-0-4. Document에 정보를 작성한다.

    2-0-5. 완성된 Document를 close한다.

 

  2-1. 아래의 예제는 예약한 항공티켓 관련 정보를 PDF로 출력하는 기능이다.

    2-1-1. PDF에 해당하는 Document 객체를 생성한다.

    2-1-2. PdfWriter를 통해서 document와 출력스트림을 연결한다.

 

    2-1-3. 출력스트림은 지정된 파일 경로로 데이터를 저장한다.

      2-1-3-1 반환 객체는 PdfWriter이지만 내부적으로 document에 PdfDocument가 추가된다.

      2-1-3-2 PdfDocument문서에 Output 스트림에 연결된 PdfWriter가 추가된다. 

      2-1-3-3 PdfWriter를 생성할 때 PdfDocument와 Output스트림을 연결한다.

      2-1-3-4 내부적으로 PDF파일이 Output Stream과 연결된다는 것이다. 반환된 객체는 사용하지 않는다.

 

    2-1-4. document를 open한다.

    2-1-5. document에 테이블을 하나 추가한다.

    2-1-6. 테이블에 비행정보와 탑승객 정보를 입력한다. generateTable 메소드 참조

    2-1-7. 완성된 document를 close한다.

    2-1-8. 완성된 document를 내용을 작성할 때 파일로 쓰여진다.

    2-1-9. 아래의 코드의 FileOutputStream의 파일경로에 폴더가 존재해야 한다. 안전하게 미리 만들어 두는 게 좋다.

 

import java.io.FileNotFoundException;
import java.io.FileOutputStream;

import org.springframework.stereotype.Component;

import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Phrase;
import com.itextpdf.text.pdf.PdfPCell;
import com.itextpdf.text.pdf.PdfPTable;
import com.itextpdf.text.pdf.PdfWriter;

import pe.pilseong.flightreservation.entities.Reservation;

@Component
public class PdfGenerator {
  public void generateItinerary(Reservation reservation, String filePath) {
    Document document = new Document();
    
    try {
      PdfWriter.getInstance(document, new FileOutputStream(filePath));
      
      document.open();
      
      document.add(generateTable(reservation));
      
      document.close();
      
    } catch (FileNotFoundException | DocumentException e) {
      e.printStackTrace();
    }
  }

  private PdfPTable generateTable(Reservation reservation) {
    PdfPTable table = new PdfPTable(2);
    
    PdfPCell cell;
    
    cell = new PdfPCell(new Phrase("Flight Itinerary"));
    cell.setColspan(2);
    table.addCell(cell);
    
    cell = new PdfPCell(new Phrase("Flight Details"));
    cell.setColspan(2);
    table.addCell(cell);
    
    table.addCell("Airlines");
    table.addCell(reservation.getFlight().getOperatingAirlines());
    
    table.addCell("Departure City");
    table.addCell(reservation.getFlight().getDepartureCity());
    
    table.addCell("Arrival City");
    table.addCell(reservation.getFlight().getArrivalCity());
    
    table.addCell("Flight Number");
    table.addCell(reservation.getFlight().getFlightNumber());
    
    table.addCell("Departure Date");
    table.addCell(reservation.getFlight().getDateOfDeparture().toString());
    
    table.addCell("Departure Time");
    table.addCell(reservation.getFlight().getEstimatedDepartureTime().toString());
    
    cell = new PdfPCell(new Phrase("Passenger Details"));
    cell.setColspan(2);
    table.addCell(cell);
    
    table.addCell("First Name");
    table.addCell(reservation.getPassenger().getFirstName());
    
    table.addCell("Last Name");
    table.addCell(reservation.getPassenger().getLastName());
    
    table.addCell("Email");
    table.addCell(reservation.getPassenger().getEmail());
    
    table.addCell("Phone");
    table.addCell(reservation.getPassenger().getPhone());
    
    return table;
  }
}

 

3. 프로그램에서 해당 컴포넌트를 주입 받아서 사용한다.

  3-1. 보통은 Service에서는 어떤 요청을 처리한 후 부가적으로 결과물이 필요할 때 이런 기능을 사용한다.

  3-2. 아래의 코드는 bookFlight를 통해 예약정보를 저장하고 마지막에 전체 정보를 PDF로 만들어 Email로 전송한다.

 

@Service
public class ReservationServiceImpl implements ReservationService {

  
  @Autowired
  private FlightRepository flightRepository;
  
  @Autowired
  private ReservationRepository reservationRepository;
  
  @Autowired
  private PassengerRepository passengerRepository;
  
  @Autowired
  private EmailUtil emailUtil;
  
  @Autowired
  private PdfGenerator pdfGenerator;
  
  @Override
  public Reservation bookFlight(ReservationRequest request) {
    // make payment logic - card or cash etc.
    
    Long flightId = request.getFlightId();
    Flight flight = this.flightRepository.findById(flightId).get();
    
    Passenger passenger = new Passenger();
    passenger.setFirstName(request.getPassengerFirstName());
    passenger.setLastName(request.getPassengerLastName());
    passenger.setEmail(request.getPassengerEmail());
    passenger.setPhone(request.getPassengerPhone());
    
    Passenger savedPassenger = this.passengerRepository.save(passenger); 
    
    Reservation reservation = new Reservation();
    reservation.setFlight(flight);
    reservation.setPassenger(savedPassenger);
    reservation.setCheckedIn(false);
    
    Reservation saveReservation = this.reservationRepository.save(reservation);
    
    String filePath = "C:\\Users\\heops\\Documents\\reservation-" + saveReservation.getId().toString() + ".pdf";
    
    this.pdfGenerator.generateItinerary(reservation, filePath);
    this.emailUtil.sendItinerary(passenger.getEmail(), filePath);
    
    return saveReservation;
  }
}

 

4. Pdf 파일 생성과 관련은 없지만 참고를 위해 Email 구현 부분을 붙인다.

  4-1. MimeMessage를 생성하고 MimeMessageHelper를 통하여 메일 정보를 추가한다.

  4-2. 특이한 부분은 addAttachment로 파일을 추가하는데 사용한다.

    4-2-1. PDF의 경로를 받아 그 파일을 읽어 Itinerary.pdf파일로 메일에 붙인다.

 

@Component
public class EmailUtil {
  
  @Autowired
  private JavaMailSender sender;
  
  public void sendItinerary(String toAddress, String filePath) {
    MimeMessage message = this.sender.createMimeMessage();
    
    try {
      MimeMessageHelper messageHelper = new MimeMessageHelper(message, true);
      
      messageHelper.setTo(toAddress);
      messageHelper.setSubject("Itinerary for your Flight");
      messageHelper.setText("Please check your itinerary attached");
      messageHelper.addAttachment("Itinerary.pdf", new File(filePath));
      sender.send(message);
      
    } catch (MessagingException e) {
      e.printStackTrace();
    }
  }
}

 

5. 결과는 아래의 형식이다.

 

728x90
댓글