diff --git a/frontend/components/report/designer/CanvasComponent.tsx b/frontend/components/report/designer/CanvasComponent.tsx
index 554c7065..ccc3aa8a 100644
--- a/frontend/components/report/designer/CanvasComponent.tsx
+++ b/frontend/components/report/designer/CanvasComponent.tsx
@@ -357,11 +357,11 @@ export function CanvasComponent({ component }: CanvasComponentProps) {
height: snappedSize,
});
} else {
- // Grid Snap 적용
- updateComponent(component.id, {
- width: snapValueToGrid(boundedWidth),
- height: snapValueToGrid(boundedHeight),
- });
+ // Grid Snap 적용
+ updateComponent(component.id, {
+ width: snapValueToGrid(boundedWidth),
+ height: snapValueToGrid(boundedHeight),
+ });
}
}
};
@@ -444,17 +444,17 @@ export function CanvasComponent({ component }: CanvasComponentProps) {
case "text":
case "label":
return (
-
- {displayValue}
+ style={{
+ fontSize: `${component.fontSize}px`,
+ color: component.fontColor,
+ fontWeight: component.fontWeight,
+ textAlign: component.textAlign as "left" | "center" | "right",
+ whiteSpace: "pre-wrap",
+ }}
+ >
+ {displayValue}
);
@@ -534,7 +534,7 @@ export function CanvasComponent({ component }: CanvasComponentProps) {
// 기본 테이블 (데이터 없을 때)
return (
- 쿼리를 연결하세요
+ 쿼리를 연결하세요
);
@@ -858,12 +858,12 @@ export function CanvasComponent({ component }: CanvasComponentProps) {
// 계산 결과 (첫 번째 항목은 기준값, 두 번째부터 연산자 적용)
const calculateResult = (): number => {
if (calcItems.length === 0) return 0;
-
+
// 첫 번째 항목은 기준값
let result = getCalcItemValue(
calcItems[0] as { label: string; value: number | string; operator: string; fieldName?: string },
);
-
+
// 두 번째 항목부터 연산자 적용
for (let i = 1; i < calcItems.length; i++) {
const item = calcItems[i];
@@ -899,30 +899,30 @@ export function CanvasComponent({ component }: CanvasComponentProps) {
item: { label: string; value: number | string; operator: string; fieldName?: string },
index: number,
) => {
- const itemValue = getCalcItemValue(item);
- return (
-
-
- {item.label}
-
-
- {formatNumber(itemValue)}
-
-
- );
+ const itemValue = getCalcItemValue(item);
+ return (
+
+
+ {item.label}
+
+
+ {formatNumber(itemValue)}
+
+
+ );
},
)}
diff --git a/frontend/components/report/designer/ReportPreviewModal.tsx b/frontend/components/report/designer/ReportPreviewModal.tsx
index bf0603b7..7069bb75 100644
--- a/frontend/components/report/designer/ReportPreviewModal.tsx
+++ b/frontend/components/report/designer/ReportPreviewModal.tsx
@@ -17,6 +17,9 @@ import { getFullImageUrl } from "@/lib/api/client";
import JsBarcode from "jsbarcode";
import QRCode from "qrcode";
+// mm -> px 변환 상수
+const MM_TO_PX = 4;
+
interface ReportPreviewModalProps {
isOpen: boolean;
onClose: () => void;
@@ -149,8 +152,8 @@ function PreviewWatermarkLayer({ watermark, pageWidth, pageHeight }: PreviewWate
// 타일 스타일
if (watermark.style === "tile") {
const tileSize = watermark.type === "text" ? (watermark.fontSize || 48) * 4 : 150;
- const cols = Math.ceil((pageWidth * 3.7795) / tileSize) + 2;
- const rows = Math.ceil((pageHeight * 3.7795) / tileSize) + 2;
+ const cols = Math.ceil((pageWidth * MM_TO_PX) / tileSize) + 2;
+ const rows = Math.ceil((pageHeight * MM_TO_PX) / tileSize) + 2;
return (
@@ -514,7 +517,7 @@ export function ReportPreviewModal({ isOpen, onClose }: ReportPreviewModalProps)
printWindow.document.write(printHtml);
printWindow.document.close();
- printWindow.print();
+ // print()는 HTML 내 스크립트에서 이미지 로드 완료 후 자동 호출됨
};
// 워터마크 HTML 생성 헬퍼 함수
@@ -554,8 +557,8 @@ export function ReportPreviewModal({ isOpen, onClose }: ReportPreviewModalProps)
if (watermark.style === "tile") {
const tileSize = watermark.type === "text" ? (watermark.fontSize || 48) * 4 : 150;
- const cols = Math.ceil((pageWidth * 3.7795) / tileSize) + 2;
- const rows = Math.ceil((pageHeight * 3.7795) / tileSize) + 2;
+ const cols = Math.ceil((pageWidth * MM_TO_PX) / tileSize) + 2;
+ const rows = Math.ceil((pageHeight * MM_TO_PX) / tileSize) + 2;
const tileItems = Array.from({ length: rows * cols })
.map(() => `
${textContent}
`)
.join("");
@@ -650,9 +653,9 @@ export function ReportPreviewModal({ isOpen, onClose }: ReportPreviewModalProps)
: "";
content = `
-
- ${personName ? `
${personName}
` : ""}
-
+
+ ${personName ? `
${personName}
` : ""}
+
${imageUrl ? `

` : ""}
${showLabel ? `
${labelText}
` : ""}
@@ -891,8 +894,15 @@ export function ReportPreviewModal({ isOpen, onClose }: ReportPreviewModalProps)
`;
}
+ // 컴포넌트 값은 px로 저장됨 (캔버스는 pageWidth * MM_TO_PX px)
+ // 인쇄용 mm 단위로 변환: px / MM_TO_PX = mm
+ const xMm = component.x / MM_TO_PX;
+ const yMm = component.y / MM_TO_PX;
+ const widthMm = component.width / MM_TO_PX;
+ const heightMm = component.height / MM_TO_PX;
+
return `
-
+
${content}
`;
})
@@ -901,7 +911,7 @@ export function ReportPreviewModal({ isOpen, onClose }: ReportPreviewModalProps)
const watermarkHTML = generateWatermarkHTML(watermark, pageWidth, pageHeight);
return `
-
+
${watermarkHTML}
${componentsHTML}
`;
@@ -933,20 +943,18 @@ export function ReportPreviewModal({ isOpen, onClose }: ReportPreviewModalProps)
리포트 인쇄