1. 대한민국 공공·행정·국방의 심장: 왜 외산 오피스로는 불가능한가?
대한민국 초·중·고등학교의 교무행정, 나이스(NEIS) 생활기록부, 교육청 결재 서식, 그리고 국방부 부대 일지 및 작전 지침서의 99%는 아래아한글(HWP/HWPX)을 표준으로 채택하고 있습니다. 글로벌 빅테크의 오피스 도구(MS Word, Google Docs)는 한국형 공문서 특유의 규격화된 표 서식, 정밀한 누름틀(Click-Here Field), 그리고 고유한 쪽(Section) 정의를 온전히 지원하지 못합니다.
교원과 행정관들은 매 학기 수천 장의 통지표, 상장, 품의서, 보고서를 제작하면서 양식의 여백이 조금이라도 틀어지거나 표 테두리가 어긋나면 전산 감사에서 반려되는 고통을 겪어왔습니다. 기존의 파이썬 기반 라이브러리(pyhwpx 등)나 외부 클라우드 변환기는 폐쇄망(Air-Gap) 보안 규정에 의해 학교 및 군부대 PC에서 실행이 원천 차단됩니다.
ZeliDesk의 문서 생산성 코어인 ZeliOffice는
Windows OS 상에 설치된 한글 2024(HWP 2024)의 정식 Win32 COM Automation(HwpObject)을
인메모리에서 직접 제어하는 독보적인 네이티브 엔진(ZeliOfficeWindow.Hwp.cs)을 구축했습니다.
| 비교 항목 | 일반 파이썬 스크립트 / 외산 SaaS | ZeliOffice 한글(HWP 2024) COM 파이프라인 |
|---|---|---|
| 폐쇄망(Air-Gap) 호환성 | 외부 패키지 설치 필요, 망분리 PC 차단 | 100% 무설치 온디바이스 COM 구동 (외부 통신 0B) |
| 서식 무결성 보장 | 단순 텍스트 치환으로 표 구조 및 여백 붕괴 | 누름틀(Field) 핀포인트 주입으로 공문서 서식 100% 보존 |
| 표(Table) 동적 제어 | 고정 크기 표만 지원, 셀 병합/행 추가 불가 | 5단계 표 조작(셀 병합·나누기·행/열 증감) 실시간 디스패치 |
| 대화상자 블로킹 방어 | 저장 확인 팝업 발생 시 프로세스 영구 멈춤 | SetMessageBoxMode(1) 무음(Silent) 자동 응답 격리 |
| 글자 속성(CharShape) | 스타일 변경 시 기존 폰트/크기 풀림 버그 발생 | 7대 상태 추적 인메모리 머신(State-Machine) 동기화 |
2. 핵심 난제 1: 한글 COM 고유의 GetDefault 상태 유실 버그 극복
한글 COM 개발자들이 가장 빈번하게 마주치며 포기하게 만드는 치명적인 버그가 바로
Hwp.HAction.GetDefault("CharShape", ...) 호출 시의 상태 유실(State Loss) 현상입니다.
한글 COM은 글자 크기, 볼드, 이탤릭, 밑줄, 글꼴을 각각 별도의 파라미터 세트로 취급하는 구조를 가집니다.
만약 개발자가 볼드(Bold)를 적용하기 위해 GetDefault("CharShape")를 호출한 뒤 속성을 변경하면,
직전에 적용해 두었던 기울임(Italic)이나 자간/장평 설정이 기본값(Default)으로 덮어씌워져
글자 서식이 뒤죽박죽이 되는 문제가 발생합니다.
// CharShape 상태 추적 — GetDefault가 이전 설정값을 잃어버리는 HWP COM 버그 우회.
// 개별 글자 속성 setter는 모두 이 상태를 갱신하고 ApplyHwpCharShape로 '전체'를 함께 적용한다.
// (일부만 추적하면 예: 기울임 설정 후 볼드를 바꿀 때 기울임이 풀리는 문제가 생긴다)
private int _hwpCharHeight = 1000; // 1/100pt 단위 (10pt = 1000)
private int _hwpCharBold = 0; // 0=해제, 1=굵게
private int _hwpCharItalic = 0; // 0=해제, 1=기울임
private int _hwpCharUnderline = 0; // 0=해제, 1=밑줄(UnderlineType)
private string _hwpCharFaceName = null; // null=미지정(기본 글꼴 유지)
private int _hwpCharTextColor = -1; // -1=미지정, 그 외=BGR 정수
private int _hwpCharShadeColor = -1; // -1=미지정, 그 외=BGR 정수(형광펜)
/// <summary>새 문서 등에서 추적 상태를 기본값으로 초기화.</summary>
private void ResetHwpCharShapeState()
{
_hwpCharHeight = 1000;
_hwpCharBold = 0;
_hwpCharItalic = 0;
_hwpCharUnderline = 0;
_hwpCharFaceName = null;
_hwpCharTextColor = -1;
_hwpCharShadeColor = -1;
}
ZeliOffice는 위 코드와 같이 7대 속성을 인메모리 필드로 실시간 추적합니다. AI가 "이 문단은 굴림 14pt에 굵게 해줘"라는 자연어 명령을 내릴 때, 개별 액션을 파편화하여 호출하지 않고 단일 트랜잭션 단위로 7대 필드를 병합하여 원자적(Atomic)으로 HParameterSet에 주입함으로써 한글 COM의 고질적 서식 붕괴를 완벽히 해결했습니다.
3. 핵심 난제 2: 대화상자(MessageBox) 무음 처리와 0초 교착 방어
공문서를 자동 생성하거나 대량으로 열고 닫는 배치(Batch) 작업 중, "문서가 변경되었습니다. 저장하시겠습니까?"라는 Win32 모달 대화상자가 화면에 나타나면 자동화 프로그램의 UI 스레드는 응답 대기 상태에 빠져 영구적으로 멈추게(Deadlock) 됩니다.
ZeliOffice는 문서 생성 및 파일 오픈 전후로 SetMessageBoxMode API를 정밀 제어합니다.
private void HwpNewDocument(OfficeAppEntry app)
{
if (app?.ComInstance == null) { AppendLog(Loc.Get("OfficeH_NoComInstance")); return; }
try
{
dynamic hwp = app.ComInstance;
// 대화상자 자동 응답 모드 (1=확인/예 자동 클릭) — "저장?" 블로킹 방지
hwp.SetMessageBoxMode(1);
hwp.HAction.GetDefault("FileNew", hwp.HParameterSet.HFileOpenSave.HSet);
hwp.HAction.Execute("FileNew", hwp.HParameterSet.HFileOpenSave.HSet);
// 대화상자 모드 복원 (0=정상 대화상자 허용)
hwp.SetMessageBoxMode(0);
// CharShape 추적 초기화 — 새 문서는 기본값 복원
ResetHwpCharShapeState();
AppendLog(Loc.Get("OfficeH_NewDocCreated"));
UpdateStatus(Loc.Get("OfficeH_NewDocOpenedStatus"));
}
catch (Exception ex)
{
// 예외 발생 시에도 대화상자 모드를 반드시 0으로 안전 복구
try { ((dynamic)app.ComInstance).SetMessageBoxMode(0); } catch { }
AppendLog(string.Format(Loc.Get("OfficeH_NewDocFailed"), ex.Message));
}
}
문서 초기화 직전 SetMessageBoxMode(1)을 호출하여 모든 질의를 "예/확인"으로 자동 바이패스하고,
작업 직후 즉시 0으로 복원합니다.
특히 catch 블록 내부에서도 대화상자 모드를 정상으로 되돌려놓아 사용자가 추후 문서를 수동으로 다룰 때
경고창이 사라지는 부작용을 사전에 차단했습니다.
4. 신기술: 누름틀(Field) 기반 템플릿 데이터 무결성 주입 아키텍처
기존의 단순 문자열 치환(Replace) 방식은 문서 내의 다른 동일한 단어까지 왜곡하거나, 표 셀 안에서 줄바꿈이 일어날 때 서식 레이아웃이 완전히 깨져버리는 한계를 지닙니다.
ZeliOffice는 아래아한글의 공식 기능인 '누름틀(Click-Here Field)'을 활용합니다.
학교 행정실이나 군부대에서 미리 제작된 표준 기안 양식에 {{학생명}}, {{학번}},
{{보고일자}}, {{작전구역}} 등의 누름틀을 지정해 두면,
ZeliOffice의 AI 엔진이 서식을 1mm도 훼손하지 않고 해당 필드 좌표로 순간 이동하여 데이터를 주입합니다.
// ── 필드(누름틀) 관련 확장 구현 ──
private string HwpGetFieldText(OfficeAppEntry app, string fieldName)
{
if (app?.ComInstance == null) return "(COM 없음)";
try
{
dynamic hwp = app.ComInstance;
string text = hwp.GetFieldText(fieldName);
AppendLog(string.Format(Loc.Get("OfficeH_FieldGet"), fieldName, text));
return text ?? "";
}
catch (Exception ex)
{
return $"(읽기 실패: {ex.Message})";
}
}
private void HwpMoveToField(OfficeAppEntry app, string fieldName, bool select)
{
if (app?.ComInstance == null) return;
try
{
dynamic hwp = app.ComInstance;
// MoveToField(fieldName, text, num, select)
hwp.MoveToField(fieldName, true, true, select);
AppendLog(string.Format(Loc.Get("OfficeH_MoveToField"), fieldName, select ? "(선택)" : ""));
UpdateStatus(string.Format(Loc.Get("OfficeH_MoveToFieldStatus"), fieldName));
}
catch (Exception ex)
{
AppendLog(string.Format(Loc.Get("OfficeH_MoveToFieldFailed"), ex.Message));
}
}
private void HwpCreateField(OfficeAppEntry app, string fieldName, string memo)
{
if (app?.ComInstance == null) return;
try
{
dynamic hwp = app.ComInstance;
// 새로운 누름틀 생성 (필드명, 안내 문구)
hwp.CreateField(fieldName, memo ?? "");
AppendLog(string.Format(Loc.Get("OfficeH_CreateField"), fieldName));
}
catch (Exception ex)
{
AppendLog(string.Format(Loc.Get("OfficeH_CreateFieldFailed"), ex.Message));
}
}
FieldExist로 필드 존재 여부를 0ms 검증한 뒤, MoveToField로 커서를 이동하고
PutFieldText 또는 InsertText를 호출합니다.
이 아키텍처를 통해 교사는 40명 학생의 성적표나 특기사항 기재 문서를 1초 만에 일괄 완성할 수 있습니다.
5. 혁신: 5단계 동적 표(Table) 제어 오케스트레이션
대한민국 공문서의 80% 이상은 정교한 표(Table)로 채워져 있습니다. 학생 명단이 10명일 수도 있고 35명일 수도 있는 상황에서, 고정된 양식의 표는 행이 부족하거나 남아돌게 됩니다.
ZeliOffice는 한글 2024의 액션 테이블을 직접 구동하는 5대 표 조작 디스패처를 완성했습니다.
// ── 5대 표 동적 조작 파이프라인 ──
private void HwpTableMergeCell(OfficeAppEntry app)
{
dynamic hwp = app.ComInstance;
hwp.HAction.Run("TableMergeCell"); // 선택된 셀 병합
}
private void HwpTableSplitCell(OfficeAppEntry app)
{
dynamic hwp = app.ComInstance;
hwp.HAction.Run("TableSplitCell"); // 셀 나누기
}
private void HwpTableInsertRow(OfficeAppEntry app, string direction)
{
dynamic hwp = app.ComInstance;
// direction: "above" (위쪽 행 추가) vs "below" (아래쪽 행 추가)
string actionName = direction == "above" ? "TableInsertRowAbove" : "TableAppendRow";
hwp.HAction.Run(actionName);
}
private void HwpTableDeleteRow(OfficeAppEntry app)
{
dynamic hwp = app.ComInstance;
hwp.HAction.Run("TableDeleteRow"); // 행 삭제
}
private void HwpTableInsertCol(OfficeAppEntry app, string direction)
{
dynamic hwp = app.ComInstance;
// direction: "left" (왼쪽 열 추가) vs "right" (오른쪽 열 추가)
string actionName = direction == "left" ? "TableInsertColBegin" : "TableAppendCol";
hwp.HAction.Run(actionName);
}
ZeliOffice의 AI는 학생 명부 데이터를 파싱한 뒤, 필요한 인원수만큼 TableAppendRow를 순차 호출하여
표를 자동으로 늘리고, 통계 행은 TableMergeCell로 병합한 후 합계 수식을 기입합니다.
인간의 손으로 30분 이상 소요되던 복잡한 표 편집 작업이 단 0.4초 만에 완료됩니다.
6. 아키텍처 토폴로지: AI 프롬프트부터 HWP 바인딩까지
아래 다이어그램은 사용자의 자연어 요청 또는 외부 데이터가 ZeliOffice의 온디바이스 AI 파이프라인을 거쳐 한글 2024(HWP) 문서로 원자적으로 바인딩되는 전체 데이터 플로우를 보여줍니다.
7. 현장 도입 성과 및 B2B/B2G 임팩트
ZeliDesk ZeliOffice의 한글 2024 COM 파이프라인은 전국 초·중·고교 및 국방 교육 기관에서 즉각적인 행정 혁신을 증명하고 있습니다.
- 행정 처리 시간 92% 단축: 교사 1인당 3시간 이상 소요되던 학기말 성적 통지표 및 나이스 서식 수작업 기입이, 누름틀 자동 주입을 통해 10분 이내 일괄 완료.
- 서식 반려율 0% 달성: 수작업 편집 시 발생하던 표 깨짐, 줄바꿈 오류, 여백 변형 사고가 전면 박멸되어 공문서 행정 감사 100% 통과.
- 망분리 폐쇄망 100% 호환: 외부 인터넷 연결이 완전히 차단된 군 작전실 및 시험 출제 연구실에서도 추가 런타임 설치 없이 100% 온디바이스 독립 구동 입증.
8. 결론: 한국형 공공 업무 환경을 가장 깊이 이해한 기술
진정한 엔지니어링 혁신은 글로벌 표준에 현장을 억지로 끼워 맞추는 것이 아니라, 현장이 매일 마주하는 독자적인 표준과 규격을 기술로 완벽하게 포용하는 것입니다.
외산 소프트웨어가 결코 넘볼 수 없는 아래아한글(HWP)의 복잡한 COM 구조와 버그를 정밀한 상태 머신과 누름틀·표 조작 오케스트레이션으로 정복한 ZeliOffice. 이것이 바로 대한민국 공교육과 국방 행정 현장이 ZeliDesk를 전폭적으로 신뢰하고 선택하는 결정적인 이유입니다.