From 374a4878784c056d1a7cb5b211f88719023f8a78 Mon Sep 17 00:00:00 2001 From: Nan Kyung Lee Date: Mon, 2 Mar 2026 10:07:06 +0900 Subject: [PATCH] =?UTF-8?q?feat(reports):=20HWP=20=EC=A0=80=EC=9E=A5?= =?UTF-8?q?=EC=9D=84=20=EC=8B=A4=EC=A0=9C=20HWPX=20=ED=8F=AC=EB=A7=B7?= =?UTF-8?q?=EC=9C=BC=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 기존 HTML Blob → .doc 저장 방식을 OWPML 표준 HWPX(ZIP+XML) 포맷으로 교체. JSZip으로 HWPX 파일을 순수 브라우저에서 생성하여 한글에서 직접 열 수 있도록 구현. - hwpxExport.ts 신규: HWPX ZIP 패키징 (mimetype, header.xml, section0.xml 등) - reportUtils.ts: exportAsHWP → dynamic import로 HWPX 위임 - ReportsView.tsx, TemplateFormEditor.tsx: 구조화 데이터 직접 전달 Co-Authored-By: Claude Opus 4.6 --- frontend/package-lock.json | 1 + frontend/package.json | 1 + .../tabs/reports/components/ReportsView.tsx | 12 +- .../reports/components/TemplateFormEditor.tsx | 17 +- .../src/tabs/reports/components/hwpxExport.ts | 703 ++++++++++++++++++ .../tabs/reports/components/reportUtils.ts | 19 +- 6 files changed, 729 insertions(+), 24 deletions(-) create mode 100644 frontend/src/tabs/reports/components/hwpxExport.ts diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 7182874..1e42f8c 100755 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -23,6 +23,7 @@ "@vis.gl/react-maplibre": "^8.1.0", "axios": "^1.13.5", "emoji-mart": "^5.6.0", + "jszip": "^3.10.1", "lucide-react": "^0.564.0", "maplibre-gl": "^5.19.0", "react": "^19.2.0", diff --git a/frontend/package.json b/frontend/package.json index d37aeb5..6876fd4 100755 --- a/frontend/package.json +++ b/frontend/package.json @@ -25,6 +25,7 @@ "@vis.gl/react-maplibre": "^8.1.0", "axios": "^1.13.5", "emoji-mart": "^5.6.0", + "jszip": "^3.10.1", "lucide-react": "^0.564.0", "maplibre-gl": "^5.19.0", "react": "^19.2.0", diff --git a/frontend/src/tabs/reports/components/ReportsView.tsx b/frontend/src/tabs/reports/components/ReportsView.tsx index 52af3a5..014c1a6 100755 --- a/frontend/src/tabs/reports/components/ReportsView.tsx +++ b/frontend/src/tabs/reports/components/ReportsView.tsx @@ -16,7 +16,8 @@ import { analysisCatColors, inferAnalysisCategory, type ViewState, -} from './reportUtils' +} from './reportUtils'; +import type { TemplateType } from './reportTypes'; import TemplateFormEditor from './TemplateFormEditor' import ReportGenerator from './ReportGenerator' @@ -296,7 +297,7 @@ export function ReportsView() { diff --git a/frontend/src/tabs/reports/components/TemplateFormEditor.tsx b/frontend/src/tabs/reports/components/TemplateFormEditor.tsx index 9ac4401..b3bf134 100644 --- a/frontend/src/tabs/reports/components/TemplateFormEditor.tsx +++ b/frontend/src/tabs/reports/components/TemplateFormEditor.tsx @@ -67,15 +67,14 @@ function TemplateFormEditor({ onSave, onBack }: TemplateFormEditorProps) { } const doExport = (format: 'pdf' | 'hwp') => { - const html = generateReportHTML( - template.label, - { writeTime: reportMeta.writeTime, author: reportMeta.author, jurisdiction: reportMeta.jurisdiction }, - template.sections, - getVal - ) + const meta = { writeTime: reportMeta.writeTime, author: reportMeta.author, jurisdiction: reportMeta.jurisdiction } const filename = formData['incident.name'] || `${template.label}_${reportMeta.writeTime.replace(/[\s:]/g, '_')}` - if (format === 'pdf') exportAsPDF(html, filename) - else exportAsHWP(html, filename) + if (format === 'pdf') { + const html = generateReportHTML(template.label, meta, template.sections, getVal) + exportAsPDF(html, filename) + } else { + exportAsHWP(template.label, meta, template.sections, getVal, filename) + } } return ( @@ -185,7 +184,7 @@ function TemplateFormEditor({ onSave, onBack }: TemplateFormEditorProps) {
- +