미리보기 기능 구현

This commit is contained in:
dohyeons 2025-10-01 13:58:55 +09:00
parent 579d4224d5
commit 7a588b47f6
1 changed files with 103 additions and 45 deletions

View File

@ -18,10 +18,49 @@ interface ReportPreviewModalProps {
}
export function ReportPreviewModal({ isOpen, onClose }: ReportPreviewModalProps) {
const { components, canvasWidth, canvasHeight } = useReportDesigner();
const { components, canvasWidth, canvasHeight, getQueryResult } = useReportDesigner();
// 컴포넌트의 실제 표시 값 가져오기
const getComponentValue = (component: any): string => {
if (component.queryId && component.fieldName) {
const queryResult = getQueryResult(component.queryId);
if (queryResult && queryResult.rows.length > 0) {
const value = queryResult.rows[0][component.fieldName];
if (value !== null && value !== undefined) {
return String(value);
}
}
return `{${component.fieldName}}`;
}
return component.defaultValue || "텍스트";
};
const handlePrint = () => {
window.print();
// 현재 미리보기 영역만 인쇄
const printContent = document.getElementById("preview-content");
if (!printContent) return;
const printWindow = window.open("", "_blank");
if (!printWindow) return;
printWindow.document.write(`
<html>
<head>
<title> </title>
<style>
body { margin: 0; padding: 20px; }
@media print {
body { margin: 0; padding: 0; }
}
</style>
</head>
<body>
${printContent.innerHTML}
</body>
</html>
`);
printWindow.document.close();
printWindow.print();
};
const handleDownloadPDF = () => {
@ -45,63 +84,82 @@ export function ReportPreviewModal({ isOpen, onClose }: ReportPreviewModalProps)
{/* 미리보기 영역 */}
<div className="max-h-[500px] overflow-auto rounded border bg-gray-100 p-4">
<div
id="preview-content"
className="relative mx-auto bg-white shadow-lg"
style={{
width: `${canvasWidth}mm`,
minHeight: `${canvasHeight}mm`,
}}
>
{components.map((component) => (
<div
key={component.id}
className="absolute rounded border bg-white p-2"
style={{
left: `${component.x}px`,
top: `${component.y}px`,
width: `${component.width}px`,
height: `${component.height}px`,
fontSize: `${component.fontSize}px`,
color: component.fontColor,
backgroundColor: component.backgroundColor,
borderColor: component.borderColor,
borderWidth: `${component.borderWidth}px`,
}}
>
{component.type === "text" && (
<div>
<div className="mb-1 text-xs text-gray-500"> </div>
<div> </div>
</div>
)}
{component.type === "label" && (
<div>
<div className="mb-1 text-xs text-gray-500"></div>
<div className="font-semibold"> </div>
</div>
)}
{component.type === "table" && (
<div className="overflow-auto">
<div className="mb-1 text-xs text-gray-500"></div>
{components.map((component) => {
const displayValue = getComponentValue(component);
const queryResult = component.queryId ? getQueryResult(component.queryId) : null;
return (
<div
key={component.id}
className="absolute"
style={{
left: `${component.x}px`,
top: `${component.y}px`,
width: `${component.width}px`,
height: `${component.height}px`,
}}
>
{component.type === "text" && (
<div
style={{
fontSize: `${component.fontSize}px`,
color: component.fontColor,
backgroundColor: component.backgroundColor,
}}
>
{displayValue}
</div>
)}
{component.type === "label" && (
<div
className="font-semibold"
style={{
fontSize: `${component.fontSize}px`,
color: component.fontColor,
backgroundColor: component.backgroundColor,
}}
>
{displayValue}
</div>
)}
{component.type === "table" && queryResult && queryResult.rows.length > 0 ? (
<table className="w-full border-collapse text-xs">
<thead>
<tr className="bg-gray-100">
<th className="border p-1"></th>
<th className="border p-1"></th>
<th className="border p-1"></th>
{queryResult.fields.map((field) => (
<th key={field} className="border border-gray-300 p-1">
{field}
</th>
))}
</tr>
</thead>
<tbody>
<tr>
<td className="border p-1">1</td>
<td className="border p-1">10</td>
<td className="border p-1">50,000</td>
</tr>
{queryResult.rows.map((row, idx) => (
<tr key={idx}>
{queryResult.fields.map((field) => (
<td key={field} className="border border-gray-300 p-1">
{String(row[field] ?? "")}
</td>
))}
</tr>
))}
</tbody>
</table>
</div>
)}
</div>
))}
) : component.type === "table" ? (
<div className="text-xs text-gray-400"> </div>
) : null}
</div>
);
})}
</div>
</div>