/** * 인쇄 유틸리티 함수 * 특정 요소만 인쇄하기 위한 헬퍼 함수들 */ interface PrintOptions { /** 문서 제목 (브라우저 인쇄 다이얼로그에 표시) */ title?: string; /** 추가 CSS 스타일 */ styles?: string; /** 인쇄 후 창 닫기 여부 */ closeAfterPrint?: boolean; } /** * 특정 요소의 내용만 인쇄합니다. * @param elementOrSelector - 인쇄할 요소 또는 CSS 선택자 * @param options - 인쇄 옵션 */ export function printElement( elementOrSelector: HTMLElement | string, options: PrintOptions = {} ): void { const { title = '문서 인쇄', styles = '', closeAfterPrint = true, } = options; // 요소 찾기 const element = typeof elementOrSelector === 'string' ? document.querySelector(elementOrSelector) : elementOrSelector; if (!element) { console.error('인쇄할 요소를 찾을 수 없습니다:', elementOrSelector); return; } // 인쇄용 새 창 열기 const printWindow = window.open('', '_blank', 'width=800,height=600'); if (!printWindow) { console.error('팝업 창을 열 수 없습니다. 팝업 차단을 확인해주세요.'); alert('인쇄 창을 열 수 없습니다. 팝업 차단을 해제해주세요.'); return; } // 현재 페이지의 스타일시트 수집 const styleSheets = Array.from(document.styleSheets) .map((styleSheet) => { try { if (styleSheet.href) { return ``; } if (styleSheet.cssRules) { const rules = Array.from(styleSheet.cssRules) .map((rule) => rule.cssText) .join('\n'); return ``; } } catch (e) { // CORS 에러 등으로 접근 불가한 스타일시트는 무시 if (styleSheet.href) { return ``; } } return ''; }) .join('\n'); // 기본 인쇄 스타일 const defaultPrintStyles = ` `; // 인쇄할 내용 복제 및 정리 const contentClone = element.cloneNode(true) as HTMLElement; // print-hidden 요소 제거 contentClone.querySelectorAll('.print-hidden').forEach((el) => el.remove()); // 불필요한 클래스 및 스타일 정리 contentClone.classList.remove('print-area'); contentClone.style.cssText = ''; // 내부 wrapper의 스타일 정리 const innerWrapper = contentClone.querySelector(':scope > div'); if (innerWrapper instanceof HTMLElement) { innerWrapper.style.cssText = 'max-width: none; margin: 0; padding: 0; box-shadow: none; border-radius: 0;'; } // HTML 작성 printWindow.document.write(` ${title} ${styleSheets} ${defaultPrintStyles} `); printWindow.document.close(); } /** * .print-area 클래스를 가진 요소를 인쇄합니다. * @param options - 인쇄 옵션 */ export function printArea(options: PrintOptions = {}): void { printElement('.print-area', options); }