/**
* 레포트 HTML을 별도 iframe 문서로 열어 인쇄·PDF 저장 (메인 앱 visibility 인쇄 버그 회피)
*/
/** App.css 전체 로드 전에도 PDF 다페이지·하단 잘림 방지 */
const CRITICAL_PRINT_CSS = `
@media print {
html, body {
height: auto !important;
overflow: visible !important;
margin: 0 !important;
padding: 0 !important;
}
.btd-report-print-doc,
.btd-report-print-area,
.brd-dashboard,
.brd-dashboard--report {
overflow: visible !important;
max-height: none !important;
min-height: 0 !important;
height: auto !important;
font-family: 'Apple SD Gothic Neo', 'Malgun Gothic', 'Noto Sans KR', sans-serif !important;
}
.brd-dashboard {
break-inside: auto !important;
page-break-inside: auto !important;
}
.brd-row,
.brd-row--2col,
.brd-row--3col,
.brd-card,
.brd-card--full {
break-inside: auto !important;
page-break-inside: auto !important;
overflow: visible !important;
}
.brd-kpi-grid {
break-inside: auto !important;
page-break-inside: auto !important;
}
.brd-kpi-card,
.brd-dash-header {
break-inside: avoid !important;
page-break-inside: avoid !important;
}
.brd-sig-scroll {
max-height: none !important;
overflow: visible !important;
height: auto !important;
}
.brd-expand-btn {
display: none !important;
}
.btd-report-print-footer {
break-inside: avoid !important;
page-break-inside: avoid !important;
}
}
@page {
size: A4 portrait;
margin: 10mm;
}
`;
const FONT_LINKS = `
`;
function escapeHtml(s: string): string {
return s
.replace(/&/g, '&')
.replace(//g, '>')
.replace(/"/g, '"');
}
function collectDocumentStyles(): string {
const links = Array.from(document.querySelectorAll('link[rel="stylesheet"]'))
.filter(l => l.href && !l.href.includes('fonts.googleapis.com'))
.map(l => ``);
const inline = Array.from(document.querySelectorAll('style'))
.map(s => s.outerHTML);
return [...links, ...inline].join('\n');
}
export function printReportDocument(contentHtml: string, documentTitle: string): void {
const iframe = document.createElement('iframe');
iframe.setAttribute('title', 'print');
iframe.style.cssText = 'position:fixed;width:0;height:0;border:0;left:-9999px;top:0;';
document.body.appendChild(iframe);
const win = iframe.contentWindow;
const doc = win?.document;
if (!doc) {
iframe.remove();
return;
}
doc.open();
doc.write(`
${escapeHtml(documentTitle)}
${FONT_LINKS}
${collectDocumentStyles()}
`);
doc.close();
if (doc.body) {
doc.body.insertAdjacentHTML('beforeend', contentHtml);
}
let printed = false;
const runPrint = () => {
if (printed) return;
printed = true;
try {
win?.focus();
win?.print();
} finally {
window.setTimeout(() => iframe.remove(), 2000);
}
};
iframe.addEventListener('load', () => {
window.setTimeout(runPrint, 500);
}, { once: true });
window.setTimeout(runPrint, 900);
}