Vue 기반의 백오피스나 관리 시스템 개발 시, 주문서나 보고서 같은 문서를 사용자가 직접 디자인하고 출력하는 기능은 필수적입니다. 하지만 WYSIWYG(위지윅) 방식의 템플릿 에디터를 직접 구현하거나 무거운 외부 라이브러리를 도입하면, 동적 데이터 바인딩이나 페이지네이션 등에서 예상치 못한 문제에 직면하기 쉽습니다. 이러한 상황에서 가볍고 확장성이 뛰어난 vue-plugin-hiprint는 매우 효과적인 대안이 될 수 있습니다.
이 글에서는 vue-plugin-hiprint의 기초적인 사용법을 넘어, 실제 비즈니스 로직에 통합할 때 자주 발생하는 문제들과 그 해결 방안을 중점적으로 다룹니다. CRM 시스템의 계약서 출력이나 ERP의 송장 인쇄 등 다양한 시나리오에 바로 적용할 수 있는 핵심 메커니즘을 살펴보겠습니다.
1. 아키텍처 및 핵심 개념 파악
본격적인 개발에 앞서 vue-plugin-hiprint의 내부 구조를 이해해야 합니다. 이 라이브러리는 크게 디자이너(Designer), 템플릿(Template), 렌더러(Renderer) 세 가지 계층으로 분리되어 있습니다. 디자이너는 브라우저 상에서 UI 요소를 시각적으로 배치하는 역할을 하며, 템플릿은 배치된 요소들의 스타일과 위치를 JSON 형태로 저장합니다. 마지막으로 렌더러는 이 JSON 템플릿과 실제 비즈니스 데이터를 결합하여 최종 인쇄용 HTML을 생성합니다.
1.1 의존성 설치 및 환경 구성
Vue 프로젝트(Vite 또는 Webpack 기반)에 핵심 라이브러리와 부가 기능을 위한 패키지를 설치합니다.
# 핵심 인쇄 플러그인 설치
npm i vue-plugin-hiprint
# 바코드 생성이 필요한 경우
npm i jsbarcode
# PDF 내보내기 기능 사용 시
npm i jspdf
여기서 주의해야 할 중요한 트러블슈팅 포인트가 있습니다. 많은 레거시 문서에서 '직접 인쇄(시스템 인쇄 대화상자 생략)' 기능을 위해 socket.io-client 설치를 권장합니다. 하지만 이 기능은 로컬에서 별도의 데스크톱 클라이언트 애플리케이션이 실행 중이어야만 동작합니다. 일반적인 웹 환경에서 사용자가 브라우저의 인쇄 미리보기를 통해 출력하는 시나리오라면, socket.io 관련 패키지는 전혀 필요 없습니다. 불필요한 설치는 번들 사이즈를 증가시키고 콘솔에 웹소켓 연결 오류를 유발할 수 있으므로 제외하는 것이 좋습니다.
패키지 설치 후, 전역 또는 컴포넌트 단위로 라이브러리를 등록합니다.
// Vue 3 및 로컬 컴포넌트에서의 호출 예시
import { hiprint } from 'vue-plugin-hiprint';
import 'vue-plugin-hiprint/dist/hiPrint.css';
// 전역 플러그인으로 등록할 경우 (Vue 3 앱 인스턴스 사용)
import { hiPrintPlugin } from 'vue-plugin-hiprint';
app.use(hiPrintPlugin);
1.2 Provider를 활용한 요소 정의 및 초기화
vue-plugin-hiprint에서 Provider는 인쇄 템플릿에 사용할 수 있는 '드래그 앤 드롭 요소들의 집합'을 정의하는 구성 요소입니다. 텍스트, 이미지, 테이블, 바코드 등 다양한 요소를 Provider를 통해 그룹화하고 관리합니다. 커스텀 요소를 추가하려면 반드시 자체 Provider를 생성하여 시스템에 주입해야 합니다.
import { hiprint } from 'vue-plugin-hiprint';
import { myCustomProvider } from '@/config/hiprintProviders'; // 사용자 정의 Provider
export default {
mounted() {
// 디자이너 초기화 및 Provider 주입
hiprint.init({
providers: [myCustomProvider]
});
// 좌측 요소 패널에 사용자 정의 Provider의 요소들 렌더링
hiprint.PrintElementTypeManager.build('.sidebar-elements', 'myCustomProvider');
// 인쇄 템플릿 인스턴스 생성 및 캔버스 연결
this.designerInstance = new hiprint.PrintTemplate({
template: this.loadSavedTemplate(), // 기존에 저장된 JSON 템플릿 로드
settingContainer: '.properties-panel', // 우측 속성 설정 패널 DOM 선택자
paginationContainer: '.page-preview-area' // 페이지네이션 미리보기 DOM 선택자
});
// 캔버스에 템플릿 적용
this.designerInstance.design('#canvas-container');
}
}