diff --git a/frontend/components/report/designer/ReportPreviewModal.tsx b/frontend/components/report/designer/ReportPreviewModal.tsx
index 8f39cc4f..f058e513 100644
--- a/frontend/components/report/designer/ReportPreviewModal.tsx
+++ b/frontend/components/report/designer/ReportPreviewModal.tsx
@@ -42,85 +42,215 @@ export function ReportPreviewModal({ isOpen, onClose }: ReportPreviewModalProps)
};
const handlePrint = () => {
- // 현재 미리보기 영역만 인쇄
- const printContent = document.getElementById("preview-content");
- if (!printContent) return;
+ // HTML 생성하여 인쇄
+ const printHtml = generatePrintHTML();
const printWindow = window.open("", "_blank");
if (!printWindow) return;
- printWindow.document.write(`
-
-
- 리포트 인쇄
-
-
-
- ${printContent.innerHTML}
-
-
- `);
+ printWindow.document.write(printHtml);
printWindow.document.close();
printWindow.print();
};
- // PDF 다운로드 (브라우저 인쇄 기능 이용)
- const handleDownloadPDF = () => {
- const printContent = document.getElementById("preview-content");
- if (!printContent) return;
+ // HTML 생성 (인쇄/PDF용)
+ const generatePrintHTML = (): string => {
+ // 컴포넌트별 HTML 생성
+ const componentsHTML = components
+ .map((component) => {
+ const queryResult = component.queryId ? getQueryResult(component.queryId) : null;
+ let content = "";
- const printWindow = window.open("", "_blank");
- if (!printWindow) return;
+ // Text/Label 컴포넌트
+ if (component.type === "text" || component.type === "label") {
+ const displayValue = getComponentValue(component);
+ content = `${displayValue}
`;
+ }
- printWindow.document.write(`
+ // Image 컴포넌트
+ else if (component.type === "image" && component.imageUrl) {
+ const imageUrl = component.imageUrl.startsWith("data:")
+ ? component.imageUrl
+ : getFullImageUrl(component.imageUrl);
+ content = `
`;
+ }
+
+ // Divider 컴포넌트
+ else if (component.type === "divider") {
+ const width = component.orientation === "horizontal" ? "100%" : `${component.lineWidth || 1}px`;
+ const height = component.orientation === "vertical" ? "100%" : `${component.lineWidth || 1}px`;
+ content = ``;
+ }
+
+ // Signature 컴포넌트
+ else if (component.type === "signature") {
+ const labelPosition = component.labelPosition || "left";
+ const showLabel = component.showLabel !== false;
+ const labelText = component.labelText || "서명:";
+ const imageUrl = component.imageUrl
+ ? component.imageUrl.startsWith("data:")
+ ? component.imageUrl
+ : getFullImageUrl(component.imageUrl)
+ : "";
+
+ if (labelPosition === "left" || labelPosition === "right") {
+ content = `
+
+ ${showLabel ? `
${labelText}
` : ""}
+
+ ${imageUrl ? `

` : ""}
+ ${component.showUnderline ? '
' : ""}
+
+
`;
+ } else {
+ content = `
+
+ ${showLabel && labelPosition === "top" ? `
${labelText}
` : ""}
+
+ ${imageUrl ? `

` : ""}
+ ${component.showUnderline ? '
' : ""}
+
+ ${showLabel && labelPosition === "bottom" ? `
${labelText}
` : ""}
+
`;
+ }
+ }
+
+ // Stamp 컴포넌트
+ else if (component.type === "stamp") {
+ const showLabel = component.showLabel !== false;
+ const labelText = component.labelText || "(인)";
+ const personName = component.personName || "";
+ const imageUrl = component.imageUrl
+ ? component.imageUrl.startsWith("data:")
+ ? component.imageUrl
+ : getFullImageUrl(component.imageUrl)
+ : "";
+
+ content = `
+
+ ${personName ? `
${personName}
` : ""}
+
+ ${imageUrl ? `

` : ""}
+ ${showLabel ? `
${labelText}
` : ""}
+
+
`;
+ }
+
+ // Table 컴포넌트
+ else if (component.type === "table" && queryResult && queryResult.rows.length > 0) {
+ const columns =
+ component.tableColumns && component.tableColumns.length > 0
+ ? component.tableColumns
+ : queryResult.fields.map((field) => ({
+ field,
+ header: field,
+ align: "left" as const,
+ width: undefined,
+ }));
+
+ const tableRows = queryResult.rows
+ .map(
+ (row) => `
+
+ ${columns.map((col) => `| ${String(row[col.field] ?? "")} | `).join("")}
+
+ `,
+ )
+ .join("");
+
+ content = `
+
+
+
+ ${columns.map((col) => `| ${col.header} | `).join("")}
+
+
+
+ ${tableRows}
+
+
`;
+ }
+
+ return `
+
+ ${content}
+
`;
+ })
+ .join("");
+
+ return `
+
리포트 인쇄
- ${printContent.innerHTML}
+
+ ${componentsHTML}
+
-
- `);
+