Hyun_dev

Playwright와 Thymeleaf를 활용하여 이메일에 첨부파일 보내기

7/7/2025

﹖ 왜 이 기능을 만들었나?

  • 사내에서 PDF 형태의 명세서를 메일 첨부파일로 보내는 기능이 필요했다. 처음에는 openhtmltopdf 라이브러리를 사용했으나 CSS 호환성이 너무 안좋았고, 테이블 레이아웃, Bootstrap 등의 CSS가 의도한 대로 나오지 않아 답답했다.
  • 브라우저를 띄워 그대로 스냅샷처럼 PDF로 변환하기 때문에, CSS 등의 걱정이 없었다.
  • 물론 서버에서 작동되는 것이기 때문에 서버에 부담을 줄 순 있지만 많은 양을 한번에 작업하는 것도 아니고 간단한 Table 형식을 PDF로 변환하는 것이기 때문에 큰 고려사항은 아니라고 판단했다.

⚙️ 구현 과정

  1. Thymeleaf View Templates을 반환하는 Controller를 만든다. (동적으로 데이터를 가져와서 원하는 형태의 Thymeleaf 템플릿을 만든다.)
  • 이는 유지보수시 로컬 주소에서 직접 화면을 보면서 수정할 수 있고, 해당 화면이 PDF로 찍혀서 나오는 것이기 때문에 매우 편리하다.
  • ViewTestController
@Controller
@RequestMapping("/before-pdf")
@RequiredArgsConstructor
public class ViewTestController {

	private final OrderOutService orderOutService;

	@GetMapping("/attachment")
	public String transOutInvoice(@RequestParam String Parameters, Model model) {

		List<Map<String, Object>> Data = xxxService.xxxMapper(Parameters)

		model.addAttribute("printData", Data);
		return "attachmentHtml";
	}
}
  1. Playwright Service 생성
  • 세션이 필요한 경우, 쿠키를 Context에 추가 (필자는 세션이 필요했기 때문에 추가했다.)
  • 해당 URL로 접속 후, PDF로 변환 -> byte[] 형태로 반환.
  • PlaywrightPdfService
@Service
public class PlaywrightPdfService {

	public byte[] generatePdfFromUrl(String url, Map<String, String> cookies) throws Exception {
		try (Playwright playwright = Playwright.create()) {
			Browser browser = playwright.chromium().launch(new BrowserType.LaunchOptions().setHeadless(true));
			BrowserContext context = browser.newContext();

			if (cookies != null && !cookies.isEmpty()) {
				List<Cookie> cookieList = new ArrayList<>();
				for (Map.Entry<String, String> entry : cookies.entrySet()) {
					cookieList.add(new Cookie(entry.getKey(), entry.getValue())
						.setDomain("localhost")
						.setPath("/"));
				}

				context.addCookies(cookieList);
			}

			Page page = context.newPage();
			page.navigate(url);

			byte[] pdfBytes = page.pdf(new Page.PdfOptions()
				.setFormat("A4")
				.setPrintBackground(true)
			);

			browser.close();
			return pdfBytes;
		}
	}
}
  1. 변환한 바이트 배열을 Email 첨부파일에 추가하여 보낸다.

🙌 후기

  • 진짜 2-3일 동안 방법을 찾기 위해 많이 노력했던 것 같다, 물론 앞에 서술한 방법 말고도 다른 방법은 존재한다. 단지 내가 모를뿐....
  • 브라우저 렌더링 그대로 PDF로 출력되므로 CSS 스트레스가 확 줄어서 너무 좋았다.
  • 서버에서 headless chromium을 띄우기 때문에, 서버에 살짝 부담을 줄 순 있으나, 복수 개의 파일이 아니라면 고려하기 좋은 기능인 것 같다.

📌 Playwright Attachment 예제