한글뷰어 기능수정
This commit is contained in:
969
문서뷰어_구현방법_가이드.html
Normal file
969
문서뷰어_구현방법_가이드.html
Normal file
@@ -0,0 +1,969 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ko">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>웹 문서/도면 미리보기 구현 가이드</title>
|
||||
<!-- 프리미엄 한글 웹폰트 및 아이콘용 폰트 연동 -->
|
||||
<link rel="stylesheet" as="style" crossorigin href="https://cdn.jsdelivr.net/gh/orioncactus/pretendard@v1.3.9/dist/web/static/pretendard.css" />
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
|
||||
|
||||
<style>
|
||||
:root {
|
||||
--primary-color: #2563eb;
|
||||
--primary-hover: #1d4ed8;
|
||||
--primary-light: #eff6ff;
|
||||
--bg-color: #f8fafc;
|
||||
--card-bg: #ffffff;
|
||||
--text-color: #1e293b;
|
||||
--text-muted: #64748b;
|
||||
--border-color: #e2e8f0;
|
||||
--badge-free: #10b981;
|
||||
--badge-free-bg: #ecfdf5;
|
||||
--badge-paid: #f59e0b;
|
||||
--badge-paid-bg: #fffbeb;
|
||||
--badge-warning: #ef4444;
|
||||
--badge-warning-bg: #fef2f2;
|
||||
--badge-current: #3b82f6;
|
||||
--badge-current-bg: #dbeafe;
|
||||
--badge-option: #475569;
|
||||
--badge-option-bg: #f1f5f9;
|
||||
--shadow-sm: 0 1px 3px 0 rgba(0, 0, 0, 0.05);
|
||||
--shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.05), 0 2px 4px -1px rgba(0, 0, 0, 0.03);
|
||||
--shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.05), 0 4px 6px -2px rgba(0, 0, 0, 0.03);
|
||||
--transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: 'Pretendard', -apple-system, BlinkMacSystemFont, system-ui, Roboto, sans-serif;
|
||||
background-color: var(--bg-color);
|
||||
color: var(--text-color);
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
line-height: 1.6;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
}
|
||||
|
||||
/* 헤더 스타일 */
|
||||
header {
|
||||
background: linear-gradient(135deg, #1e3a8a 0%, #2563eb 100%);
|
||||
color: white;
|
||||
padding: 3.5rem 2rem;
|
||||
text-align: center;
|
||||
box-shadow: var(--shadow-md);
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
header::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background: radial-gradient(circle at 80% 20%, rgba(255,255,255,0.08) 0%, transparent 50%);
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
header h1 {
|
||||
font-size: 2.2rem;
|
||||
font-weight: 800;
|
||||
margin: 0 0 0.8rem 0;
|
||||
letter-spacing: -0.03em;
|
||||
}
|
||||
|
||||
header p {
|
||||
font-size: 1.1rem;
|
||||
opacity: 0.9;
|
||||
margin: 0;
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
/* 메인 컨테이너 */
|
||||
main {
|
||||
max-width: 1200px;
|
||||
margin: -2rem auto 4rem auto;
|
||||
padding: 0 1.5rem;
|
||||
position: relative;
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
/* 탭 내비게이션 */
|
||||
.tab-nav {
|
||||
display: flex;
|
||||
background: var(--card-bg);
|
||||
padding: 0.5rem;
|
||||
border-radius: 1rem;
|
||||
box-shadow: var(--shadow-lg);
|
||||
margin-bottom: 2rem;
|
||||
overflow-x: auto;
|
||||
scrollbar-width: none; /* Firefox */
|
||||
border: 1px solid var(--border-color);
|
||||
}
|
||||
|
||||
.tab-nav::-webkit-scrollbar {
|
||||
display: none; /* Chrome/Safari */
|
||||
}
|
||||
|
||||
.tab-btn {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 0.6rem;
|
||||
padding: 1rem 1.5rem;
|
||||
border: none;
|
||||
background: transparent;
|
||||
font-size: 1rem;
|
||||
font-weight: 700;
|
||||
color: var(--text-muted);
|
||||
cursor: pointer;
|
||||
border-radius: 0.75rem;
|
||||
transition: var(--transition);
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.tab-btn i {
|
||||
font-size: 1.2rem;
|
||||
transition: var(--transition);
|
||||
}
|
||||
|
||||
.tab-btn:hover {
|
||||
color: var(--primary-color);
|
||||
background-color: var(--primary-light);
|
||||
}
|
||||
|
||||
.tab-btn.active {
|
||||
color: white;
|
||||
background: var(--primary-color);
|
||||
box-shadow: 0 4px 12px rgba(37, 99, 235, 0.2);
|
||||
}
|
||||
|
||||
/* 탭 콘텐츠 패널 */
|
||||
.tab-panel {
|
||||
display: none;
|
||||
animation: fadeIn 0.4s ease-out forwards;
|
||||
}
|
||||
|
||||
.tab-panel.active {
|
||||
display: block;
|
||||
}
|
||||
|
||||
@keyframes fadeIn {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateY(10px);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
|
||||
/* 카드 및 테이블 공통 스타일 */
|
||||
.card {
|
||||
background: var(--card-bg);
|
||||
border-radius: 1.25rem;
|
||||
padding: 2rem;
|
||||
box-shadow: var(--shadow-md);
|
||||
border: 1px solid var(--border-color);
|
||||
margin-bottom: 2rem;
|
||||
}
|
||||
|
||||
.card-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.75rem;
|
||||
margin-bottom: 1.5rem;
|
||||
border-bottom: 2px solid var(--primary-light);
|
||||
padding-bottom: 1rem;
|
||||
}
|
||||
|
||||
.card-header h2 {
|
||||
font-size: 1.4rem;
|
||||
font-weight: 800;
|
||||
margin: 0;
|
||||
color: var(--text-color);
|
||||
letter-spacing: -0.02em;
|
||||
}
|
||||
|
||||
.card-header i {
|
||||
font-size: 1.5rem;
|
||||
color: var(--primary-color);
|
||||
}
|
||||
|
||||
/* 반응형 테이블 */
|
||||
.table-responsive {
|
||||
overflow-x: auto;
|
||||
border-radius: 0.75rem;
|
||||
border: 1px solid var(--border-color);
|
||||
}
|
||||
|
||||
table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
text-align: left;
|
||||
font-size: 0.95rem;
|
||||
}
|
||||
|
||||
th {
|
||||
background-color: #f8fafc;
|
||||
color: var(--text-color);
|
||||
font-weight: 700;
|
||||
padding: 1rem 1.25rem;
|
||||
border-bottom: 2px solid var(--border-color);
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
td {
|
||||
padding: 1.25rem;
|
||||
border-bottom: 1px solid var(--border-color);
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
tr:last-child td {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
tr:hover td {
|
||||
background-color: #fafafa;
|
||||
}
|
||||
|
||||
.col-method {
|
||||
font-weight: 700;
|
||||
color: var(--primary-color);
|
||||
width: 22%;
|
||||
}
|
||||
|
||||
.col-desc {
|
||||
width: 28%;
|
||||
}
|
||||
|
||||
.col-pros {
|
||||
color: #0f766e;
|
||||
width: 25%;
|
||||
}
|
||||
|
||||
.col-cons {
|
||||
color: #b91c1c;
|
||||
width: 25%;
|
||||
}
|
||||
|
||||
/* 장단점 리스트 아이콘 */
|
||||
.bullet-list {
|
||||
margin: 0;
|
||||
padding-left: 1.2rem;
|
||||
}
|
||||
|
||||
.bullet-list li {
|
||||
margin-bottom: 0.4rem;
|
||||
}
|
||||
|
||||
.bullet-list li:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
/* 라이선스 및 적용 배지 */
|
||||
.badge {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
padding: 0.25rem 0.75rem;
|
||||
border-radius: 9999px;
|
||||
font-size: 0.8rem;
|
||||
font-weight: 700;
|
||||
line-height: 1.2;
|
||||
margin-bottom: 0.25rem;
|
||||
}
|
||||
|
||||
.badge-free {
|
||||
color: var(--badge-free);
|
||||
background-color: var(--badge-free-bg);
|
||||
border: 1px solid rgba(16, 185, 129, 0.2);
|
||||
}
|
||||
|
||||
.badge-paid {
|
||||
color: var(--badge-paid);
|
||||
background-color: var(--badge-paid-bg);
|
||||
border: 1px solid rgba(245, 158, 11, 0.2);
|
||||
}
|
||||
|
||||
.badge-warning {
|
||||
color: var(--badge-warning);
|
||||
background-color: var(--badge-warning-bg);
|
||||
border: 1px solid rgba(239, 68, 68, 0.2);
|
||||
}
|
||||
|
||||
/* 현재 시스템 적용 표시 전용 배지 */
|
||||
.badge-current {
|
||||
color: #1e40af;
|
||||
background-color: #dbeafe;
|
||||
border: 1px solid rgba(59, 130, 246, 0.4);
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 0.25rem;
|
||||
font-size: 0.75rem;
|
||||
margin-top: 0.5rem;
|
||||
padding: 0.2rem 0.6rem;
|
||||
border-radius: 0.375rem;
|
||||
}
|
||||
|
||||
.badge-option {
|
||||
color: #475569;
|
||||
background-color: #f1f5f9;
|
||||
border: 1px solid rgba(71, 85, 105, 0.3);
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 0.25rem;
|
||||
font-size: 0.75rem;
|
||||
margin-top: 0.5rem;
|
||||
padding: 0.2rem 0.6rem;
|
||||
border-radius: 0.375rem;
|
||||
}
|
||||
|
||||
/* 가이드 팁 알림창 */
|
||||
.alert-box {
|
||||
background-color: var(--primary-light);
|
||||
border-left: 4px solid var(--primary-color);
|
||||
padding: 1.25rem 1.5rem;
|
||||
border-radius: 0.5rem;
|
||||
margin-top: 1.5rem;
|
||||
display: flex;
|
||||
gap: 0.8rem;
|
||||
align-items: flex-start;
|
||||
}
|
||||
|
||||
.alert-box i {
|
||||
color: var(--primary-color);
|
||||
font-size: 1.2rem;
|
||||
margin-top: 0.2rem;
|
||||
}
|
||||
|
||||
.alert-box div {
|
||||
margin: 0;
|
||||
font-size: 0.95rem;
|
||||
color: #1e3a8a;
|
||||
}
|
||||
|
||||
/* 베스트 프랙티스 카드 */
|
||||
.bp-container {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
|
||||
gap: 1.5rem;
|
||||
margin-top: 2.5rem;
|
||||
}
|
||||
|
||||
.bp-card {
|
||||
background: var(--card-bg);
|
||||
border-radius: 1.25rem;
|
||||
padding: 1.75rem;
|
||||
box-shadow: var(--shadow-md);
|
||||
border: 1px solid var(--border-color);
|
||||
border-top: 5px solid var(--primary-color);
|
||||
transition: var(--transition);
|
||||
}
|
||||
|
||||
.bp-card:hover {
|
||||
transform: translateY(-5px);
|
||||
box-shadow: var(--shadow-lg);
|
||||
}
|
||||
|
||||
.bp-card.premium {
|
||||
border-top-color: #8b5cf6;
|
||||
}
|
||||
|
||||
.bp-card h3 {
|
||||
margin: 0 0 0.75rem 0;
|
||||
font-size: 1.2rem;
|
||||
font-weight: 800;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
|
||||
.bp-card h3 i {
|
||||
color: var(--primary-color);
|
||||
}
|
||||
|
||||
.bp-card.premium h3 i {
|
||||
color: #8b5cf6;
|
||||
}
|
||||
|
||||
.bp-card p {
|
||||
margin: 0;
|
||||
font-size: 0.9rem;
|
||||
color: var(--text-muted);
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
/* 하단 저작권 표시 */
|
||||
footer {
|
||||
text-align: center;
|
||||
padding: 2rem;
|
||||
color: var(--text-muted);
|
||||
font-size: 0.85rem;
|
||||
border-top: 1px solid var(--border-color);
|
||||
background: var(--card-bg);
|
||||
}
|
||||
|
||||
/* 반응형 모바일 브레이크포인트 */
|
||||
@media (max-width: 768px) {
|
||||
header {
|
||||
padding: 2.5rem 1rem;
|
||||
}
|
||||
header h1 {
|
||||
font-size: 1.7rem;
|
||||
}
|
||||
.tab-btn {
|
||||
padding: 0.8rem 1rem;
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
td, th {
|
||||
padding: 0.9rem;
|
||||
}
|
||||
.col-method {
|
||||
width: 25%;
|
||||
}
|
||||
.col-desc {
|
||||
width: 25%;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<header>
|
||||
<h1>웹 문서 및 도면 미리보기 기술 가이드</h1>
|
||||
<p>무료 오픈소스 라이브러리 및 서버 렌더러 방식을 중심으로 한 아키텍처 비교표</p>
|
||||
</header>
|
||||
|
||||
<main>
|
||||
<!-- 탭 내비게이션 메뉴 -->
|
||||
<nav class="tab-nav" aria-label="파일 형식별 보기">
|
||||
<button class="tab-btn active" onclick="switchTab('word')">
|
||||
<i class="fa-regular fa-file-word"></i> Word (.docx)
|
||||
</button>
|
||||
<button class="tab-btn" onclick="switchTab('excel')">
|
||||
<i class="fa-regular fa-file-excel"></i> Excel (.xlsx)
|
||||
</button>
|
||||
<button class="tab-btn" onclick="switchTab('ppt')">
|
||||
<i class="fa-regular fa-file-powerpoint"></i> PPT (.pptx)
|
||||
</button>
|
||||
<button class="tab-btn" onclick="switchTab('hwp')">
|
||||
<i class="fa-solid fa-file-lines"></i> 한글 (.hwp)
|
||||
</button>
|
||||
<button class="tab-btn" onclick="switchTab('cad')">
|
||||
<i class="fa-solid fa-drafting-compass"></i> CAD (.dwg)
|
||||
</button>
|
||||
</nav>
|
||||
|
||||
<!-- 1. Word 탭 -->
|
||||
<div id="word" class="tab-panel active">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<i class="fa-regular fa-file-word"></i>
|
||||
<h2>Word (.doc, .docx) 미리보기 방식 비교</h2>
|
||||
</div>
|
||||
<div class="table-responsive">
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>구현 방법</th>
|
||||
<th>설명</th>
|
||||
<th>장점 (Pros)</th>
|
||||
<th>단점 (Cons)</th>
|
||||
<th>라이선스 / 비용</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td class="col-method">
|
||||
docx-preview<br>(npm 패키지)
|
||||
<div class="badge-current"><i class="fa-solid fa-check"></i> 현재 기본 적용됨</div>
|
||||
</td>
|
||||
<td class="col-desc">docx 이진 데이터를 읽어 브라우저 JS로 파싱하여 HTML/CSS로 그리기</td>
|
||||
<td class="col-pros">
|
||||
<ul class="bullet-list">
|
||||
<li>순수 프론트엔드 작동 (서버 부하 없음)</li>
|
||||
<li>워드 파일 서식 보존 수준 우수</li>
|
||||
</ul>
|
||||
</td>
|
||||
<td class="col-cons">
|
||||
<ul class="bullet-list">
|
||||
<li>구형 <code>.doc</code> 파일 감지 및 파싱 불가</li>
|
||||
<li>일부 복잡한 다단, 도형 객체 깨짐</li>
|
||||
</ul>
|
||||
</td>
|
||||
<td><span class="badge badge-free">완전 무료 (MIT)</span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="col-method">
|
||||
서버 PDF 변환<br>(LibreOffice)
|
||||
<div class="badge-option"><i class="fa-solid fa-gear"></i> PDF로 보기 선택적용</div>
|
||||
</td>
|
||||
<td class="col-desc">서버 단에서 LibreOffice CLI로 PDF 변환 후 브라우저 PDF.js로 화면 표출</td>
|
||||
<td class="col-pros">
|
||||
<ul class="bullet-list">
|
||||
<li><strong>100% 보안 및 오프라인망 지원</strong></li>
|
||||
<li>다양한 오피스 파일 공통 규격 처리 가능</li>
|
||||
</ul>
|
||||
</td>
|
||||
<td class="col-cons">
|
||||
<ul class="bullet-list">
|
||||
<li>최초 변환 대기 시간 발생 (1~2초)</li>
|
||||
<li>서버 자원 소모 및 변환 엔진 세팅 필요</li>
|
||||
</ul>
|
||||
</td>
|
||||
<td><span class="badge badge-free">완전 무료 (LGPLv3)</span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="col-method">Microsoft Office<br>Online Viewer</td>
|
||||
<td class="col-desc">MS 뷰어 URL 주소에 파일 링크를 태워 iframe으로 임베드하는 방식</td>
|
||||
<td class="col-pros">
|
||||
<ul class="bullet-list">
|
||||
<li>개발 공수 제로에 가까움</li>
|
||||
<li>오리지널 서식 레이아웃 완벽 보존</li>
|
||||
</ul>
|
||||
</td>
|
||||
<td class="col-cons">
|
||||
<ul class="bullet-list">
|
||||
<li>외부 인터넷 연동 필수 (로컬 사용 불가)</li>
|
||||
<li>사내 기밀 문서 외부 반출 보안 이슈</li>
|
||||
</ul>
|
||||
</td>
|
||||
<td><span class="badge badge-free">무료 (비상업용 제한)</span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="col-method">Mammoth.js</td>
|
||||
<td class="col-desc">docx 구조를 순수 HTML 스트링 텍스트로 가볍게 치환해 표출</td>
|
||||
<td class="col-pros">
|
||||
<ul class="bullet-list">
|
||||
<li>매우 가볍고 렌더링 속도가 가장 빠름</li>
|
||||
<li>본문 텍스트 추출 및 본문 검색에 유리</li>
|
||||
</ul>
|
||||
</td>
|
||||
<td class="col-cons">
|
||||
<ul class="bullet-list">
|
||||
<li>레이아웃 및 원본 스타일 대부분 유실</li>
|
||||
<li>줄글 형태 이외의 디자인 요소 깨짐</li>
|
||||
</ul>
|
||||
</td>
|
||||
<td><span class="badge badge-free">완전 무료 (BSD)</span></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 2. Excel 탭 -->
|
||||
<div id="excel" class="tab-panel">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<i class="fa-regular fa-file-excel"></i>
|
||||
<h2>Excel (.xls, .xlsx) 미리보기 방식 비교</h2>
|
||||
</div>
|
||||
<div class="table-responsive">
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>구현 방법</th>
|
||||
<th>설명</th>
|
||||
<th>장점 (Pros)</th>
|
||||
<th>단점 (Cons)</th>
|
||||
<th>라이선스 / 비용</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td class="col-method">
|
||||
SheetJS (xlsx.js)<br>+ Luckysheet
|
||||
<div class="badge-current"><i class="fa-solid fa-check"></i> 현재 기본 적용됨</div>
|
||||
</td>
|
||||
<td class="col-desc">브라우저 JS로 엑셀 파일을 읽어 순수 HTML Table 및 Luckysheet 웹 엑셀 셀로 렌더링</td>
|
||||
<td class="col-pros">
|
||||
<ul class="bullet-list">
|
||||
<li>완전한 클라이언트 독립 처리 (서버 연산 없음)</li>
|
||||
<li>스프레드시트 형태에 유사하게 파싱하여 표출</li>
|
||||
</ul>
|
||||
</td>
|
||||
<td class="col-cons">
|
||||
<ul class="bullet-list">
|
||||
<li>복잡한 글꼴, 서식 일부 및 테두리 소실 우려</li>
|
||||
<li>엑셀 내장형 차트 및 피벗 드로잉 불가</li>
|
||||
</ul>
|
||||
</td>
|
||||
<td><span class="badge badge-free">무료 (Community 에디션)</span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="col-method">
|
||||
서버 PDF 변환<br>(LibreOffice)
|
||||
<div class="badge-option"><i class="fa-solid fa-gear"></i> PDF로 보기 선택적용</div>
|
||||
</td>
|
||||
<td class="col-desc">서버 단에서 엑셀을 PDF/HTML로 변환하여 브라우저에 표시</td>
|
||||
<td class="col-pros">
|
||||
<ul class="bullet-list">
|
||||
<li>보안 유출 없는 자체 서버 환경 구축</li>
|
||||
<li>열 너비, 정밀 선 스타일 보존 우수</li>
|
||||
</ul>
|
||||
</td>
|
||||
<td class="col-cons">
|
||||
<ul class="bullet-list">
|
||||
<li>시트가 여러 개일 때 출력 용지 맞춤 조절 필요</li>
|
||||
<li>인터랙션(필터링, 탭 편집) 불가</li>
|
||||
</ul>
|
||||
</td>
|
||||
<td><span class="badge badge-free">완전 무료 (LGPLv3)</span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="col-method">Microsoft Office<br>Online Viewer</td>
|
||||
<td class="col-desc">MS 뷰어 URL 주소에 파일 링크를 태워 iframe으로 임베드하는 방식</td>
|
||||
<td class="col-pros">
|
||||
<ul class="bullet-list">
|
||||
<li>시트 탭, 대용량 표, 차트 완벽 렌더링</li>
|
||||
<li>수식 연산 결과 그대로 노출</li>
|
||||
</ul>
|
||||
</td>
|
||||
<td class="col-cons">
|
||||
<ul class="bullet-list">
|
||||
<li>인터넷 및 공인 URL 필수</li>
|
||||
<li>사내 기밀 엑셀 데이터 반출 위험</li>
|
||||
</ul>
|
||||
</td>
|
||||
<td><span class="badge badge-free">무료 (비상업용 제한)</span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="col-method">Handsontable</td>
|
||||
<td class="col-desc">SheetJS 등 데이터 파서 결과와 연동해 엑셀 형태 그리드로 표출</td>
|
||||
<td class="col-pros">
|
||||
<ul class="bullet-list">
|
||||
<li>가장 엑셀에 근접한 편집/뷰포트 UI</li>
|
||||
<li>정렬, 필터, 다중 복사 기능 지원</li>
|
||||
</ul>
|
||||
</td>
|
||||
<td class="col-cons">
|
||||
<ul class="bullet-list">
|
||||
<li>단순 미리보기 뷰어 대비 오버스펙</li>
|
||||
<li>라이선스 비용이 매우 높음</li>
|
||||
</ul>
|
||||
</td>
|
||||
<td><span class="badge badge-paid">비영리만 무료 / 상업 유료</span></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 3. PPT 탭 -->
|
||||
<div id="ppt" class="tab-panel">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<i class="fa-regular fa-file-powerpoint"></i>
|
||||
<h2>PPT (.ppt, .pptx) 미리보기 방식 비교</h2>
|
||||
</div>
|
||||
<div class="table-responsive">
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>구현 방법</th>
|
||||
<th>설명</th>
|
||||
<th>장점 (Pros)</th>
|
||||
<th>단점 (Cons)</th>
|
||||
<th>라이선스 / 비용</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td class="col-method">
|
||||
서버 PDF 변환<br>+ PDF.js
|
||||
<div class="badge-current"><i class="fa-solid fa-check"></i> 현재 기본 적용됨</div>
|
||||
</td>
|
||||
<td class="col-desc">서버 단에서 PPT를 PDF로 일체 변환 후 브라우저에 임베딩 렌더링</td>
|
||||
<td class="col-pros">
|
||||
<ul class="bullet-list">
|
||||
<li><strong>자체 사내망 보안 완벽 보존 (100% 로컬)</strong></li>
|
||||
<li>슬라이드 레이아웃 훼손 없는 완벽한 품질 열람</li>
|
||||
<li>페이지 점프 및 반응형 뷰어 연동</li>
|
||||
</ul>
|
||||
</td>
|
||||
<td class="col-cons">
|
||||
<ul class="bullet-list">
|
||||
<li>최초 요청 시 PDF 변환 연산 시간 필요</li>
|
||||
<li>전환 애니메이션 및 동영상 등 미디어 소실</li>
|
||||
</ul>
|
||||
</td>
|
||||
<td><span class="badge badge-free">완전 무료 (LGPLv3)</span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="col-method">Microsoft Office<br>Online Viewer</td>
|
||||
<td class="col-desc">MS 뷰어 URL 주소에 파일 링크를 태워 iframe으로 임베드하는 방식</td>
|
||||
<td class="col-pros">
|
||||
<ul class="bullet-list">
|
||||
<li>슬라이드 애니메이션 효과 지원</li>
|
||||
<li>도형, 그림, 차트 레이아웃 100% 보존</li>
|
||||
</ul>
|
||||
</td>
|
||||
<td class="col-cons">
|
||||
<ul class="bullet-list">
|
||||
<li>인터넷 및 공인 URL 필수</li>
|
||||
<li>대용량 도표가 포함된 발표 기밀 반출 위험</li>
|
||||
</ul>
|
||||
</td>
|
||||
<td><span class="badge badge-free">무료 (비상업용 제한)</span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="col-method">PptxGenJS 역파싱<br>/ PPTXjs</td>
|
||||
<td class="col-desc">pptx 압축을 풀어 XML 벡터 데이터를 해석해 Canvas/SVG로 드로잉</td>
|
||||
<td class="col-pros">
|
||||
<ul class="bullet-list">
|
||||
<li>서버 전처리 없이 프론트 브라우저 드로잉</li>
|
||||
</ul>
|
||||
</td>
|
||||
<td class="col-cons">
|
||||
<ul class="bullet-list">
|
||||
<li>조금만 복잡한 도형, 스마트아트 깨짐 매우 심함</li>
|
||||
<li>글꼴 폰트 밀림으로 텍스트 겹침 다수 발생</li>
|
||||
</ul>
|
||||
</td>
|
||||
<td><span class="badge badge-free">완전 무료 (오픈소스)</span></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 4. 한글 탭 -->
|
||||
<div id="hwp" class="tab-panel">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<i class="fa-solid fa-file-lines"></i>
|
||||
<h2>한글 (.hwp, .hwpx) 미리보기 방식 비교</h2>
|
||||
</div>
|
||||
|
||||
<div class="alert-box">
|
||||
<i class="fa-solid fa-triangle-exclamation"></i>
|
||||
<div>
|
||||
<strong>현재 한글 미리보기 적용 형태:</strong> 현재 PM 시스템에는 <strong>hwp.js 기반의 직접 렌더링 방식</strong>이 프론트엔드에 기본 탑재되어 있으며, 오피스 파일 공통으로 <strong>"PDF로 보기"</strong> 버튼을 제공하여 백엔드의 LibreOffice 엔진으로 변환하여 정밀하게 볼 수도 있도록 이중 구성(Hybrid)되어 있습니다.
|
||||
</div>
|
||||
</div>
|
||||
<br>
|
||||
|
||||
<div class="table-responsive">
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>구현 방법</th>
|
||||
<th>설명</th>
|
||||
<th>장점 (Pros)</th>
|
||||
<th>단점 (Cons)</th>
|
||||
<th>라이선스 / 비용</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td class="col-method">
|
||||
hwp.js<br>(오픈소스 파서)
|
||||
<div class="badge-current"><i class="fa-solid fa-check"></i> 현재 기본 적용됨</div>
|
||||
</td>
|
||||
<td class="col-desc">오픈소스 HWP 바이너리 파서를 활용하여 브라우저에서 HTML5 객체화</td>
|
||||
<td class="col-pros">
|
||||
<ul class="bullet-list">
|
||||
<li>서버 거치지 않아 즉시 로딩</li>
|
||||
<li>완전한 오프라인/폐쇄망 무료 사용</li>
|
||||
</ul>
|
||||
</td>
|
||||
<td class="col-cons">
|
||||
<ul class="bullet-list">
|
||||
<li>정밀한 표 테두리, 수식 개체 스타일 일부 깨짐</li>
|
||||
<li>신형 규격인 <code>.hwpx</code> 파싱력 아직 불안정</li>
|
||||
</ul>
|
||||
</td>
|
||||
<td><span class="badge badge-free">완전 무료 (MIT)</span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="col-method">
|
||||
서버 LibreOffice<br>(Linux / Windows)
|
||||
<div class="badge-option"><i class="fa-solid fa-gear"></i> PDF로 보기 선택적용</div>
|
||||
</td>
|
||||
<td class="col-desc">리눅스 등 무료 백엔드 서버에서 LibreOffice 내장 변환 필터로 PDF 변환</td>
|
||||
<td class="col-pros">
|
||||
<ul class="bullet-list">
|
||||
<li>추가 하드웨어 및 OS 제약 없음</li>
|
||||
<li>최근 규격인 <code>.hwpx</code>는 꽤 준수하게 변환</li>
|
||||
</ul>
|
||||
</td>
|
||||
<td class="col-cons">
|
||||
<ul class="bullet-list">
|
||||
<li>구형 <code>.hwp</code>의 경우 폰트/표 틀어짐 가능성 있음</li>
|
||||
<li>서버에 나눔 폰트 등 전용 한글 폰트 사전 설치 필수</li>
|
||||
</ul>
|
||||
</td>
|
||||
<td><span class="badge badge-free">완전 무료 (LGPLv3)</span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="col-method">한컴 공식<br>클라우드 뷰어 API</td>
|
||||
<td class="col-desc">한글과컴퓨터 공식 API 서버를 거쳐 문서 미리보기를 HTML로 획득</td>
|
||||
<td class="col-pros">
|
||||
<ul class="bullet-list">
|
||||
<li>한글 문서 원본과 100% 일치하는 퀄리티</li>
|
||||
</ul>
|
||||
</td>
|
||||
<td class="col-cons">
|
||||
<ul class="bullet-list">
|
||||
<li>고가의 연간 이용요금 발생</li>
|
||||
<li>외부 클라우드 통신 및 계약 절차 번거로움</li>
|
||||
</ul>
|
||||
</td>
|
||||
<td><span class="badge badge-warning">유료 (계약 및 과금)</span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="col-method">서버 한글 프로그램<br>(Windows 서버)</td>
|
||||
<td class="col-desc">Windows 서버 환경에 한글 패키지 설치 후 백그라운드 CLI로 PDF 인쇄</td>
|
||||
<td class="col-pros">
|
||||
<ul class="bullet-list">
|
||||
<li>안정적인 고품질 한글 PDF 변환 가능</li>
|
||||
</ul>
|
||||
</td>
|
||||
<td class="col-cons">
|
||||
<ul class="bullet-list">
|
||||
<li>서버가 Windows 환경으로 강제 제한됨</li>
|
||||
<li>상업용 한글 오피스 구매 라이선스 비용</li>
|
||||
</ul>
|
||||
</td>
|
||||
<td><span class="badge badge-paid">Windows 라이선스 / 한컴 비용</span></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 5. CAD 탭 -->
|
||||
<div id="cad" class="tab-panel">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<i class="fa-solid fa-drafting-compass"></i>
|
||||
<h2>CAD (.dwg, .dxf) 미리보기 방식 비교</h2>
|
||||
</div>
|
||||
<div class="table-responsive">
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>구현 방법</th>
|
||||
<th>설명</th>
|
||||
<th>장점 (Pros)</th>
|
||||
<th>단점 (Cons)</th>
|
||||
<th>라이선스 / 비용</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td class="col-method">
|
||||
서버 이미지/PDF 변환<br>(QCAD 등)
|
||||
<div class="badge-current"><i class="fa-solid fa-check"></i> 현재 기본 적용됨</div>
|
||||
</td>
|
||||
<td class="col-desc">백엔드 서버 내의 변환 필터를 거쳐 DWG/DXF 캐드 파일을 PDF로 강제 변환 후 브라우저에 PDF.js로 표출</td>
|
||||
<td class="col-pros">
|
||||
<ul class="bullet-list">
|
||||
<li><strong>보안 및 오프라인 지원:</strong> 도면의 외부 반출 원천 차단</li>
|
||||
<li>SHX 한글 캐드 폰트 세팅 시 치수 및 글자 깨짐 없음</li>
|
||||
</ul>
|
||||
</td>
|
||||
<td class="col-cons">
|
||||
<ul class="bullet-list">
|
||||
<li>도면 렌더링에 따른 백엔드 서버 부하</li>
|
||||
<li>도면 레이어 제어 불가능 (고정된 평면 PDF 형태)</li>
|
||||
</ul>
|
||||
</td>
|
||||
<td><span class="badge badge-free">무료 (단, 기업 라이선스 체크)</span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="col-method">dxf-parser +<br>Three.js / Canvas</td>
|
||||
<td class="col-desc">DXF 아스키 텍스트 데이터를 분석해 브라우저 3D/2D Canvas로 직접 드로잉</td>
|
||||
<td class="col-pros">
|
||||
<ul class="bullet-list">
|
||||
<li>인터랙티브 휠 줌/인/아웃, 팬(이동) 가능</li>
|
||||
<li>도면 레이어 On/Off 제어 스위치 구현 가능</li>
|
||||
</ul>
|
||||
</td>
|
||||
<td class="col-cons">
|
||||
<ul class="bullet-list">
|
||||
<li>이진 파일인 <code>.dwg</code> 직접 파싱 불가</li>
|
||||
<li>대형 설계 도면 로드 시 브라우저 연산 렉 유발</li>
|
||||
<li>한글/설계 폰트 유실 시 텍스트 위치 틀어짐</li>
|
||||
</ul>
|
||||
</td>
|
||||
<td><span class="badge badge-free">완전 무료 (MIT)</span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="col-method">Autodesk Platform<br>Services (APS)</td>
|
||||
<td class="col-desc">오토캐드 공식 클라우드 뷰어 API를 iframe으로 웹 포털에 삽입</td>
|
||||
<td class="col-pros">
|
||||
<ul class="bullet-list">
|
||||
<li>설계 도면을 왜곡 없이 100% 완벽히 렌더링</li>
|
||||
<li>치수 측정, 단면 추출, 3D 단면 분해 제공</li>
|
||||
</ul>
|
||||
</td>
|
||||
<td class="col-cons">
|
||||
<ul class="bullet-list">
|
||||
<li>종량제 기반의 API 요금 발생</li>
|
||||
<li>기밀 도면 설계 자산 유출 우려</li>
|
||||
</ul>
|
||||
</td>
|
||||
<td><span class="badge badge-paid">유료 (사용량 종량제 과금)</span></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 실무진 추천 전략 (Best Practice) -->
|
||||
<h2 style="margin-top: 3rem; font-weight: 800; font-size: 1.6rem; letter-spacing: -0.03em;">💡 사내 시스템 개발을 위한 최적의 조합 (Best Practice)</h2>
|
||||
<div class="bp-container">
|
||||
<div class="bp-card">
|
||||
<h3><i class="fa-solid fa-shield-halved"></i> 1순위: 자체 서버 PDF 선변환 방식</h3>
|
||||
<p>
|
||||
<strong>대상:</strong> Word, Excel, PPT, HWP, CAD 공통<br>
|
||||
<strong>설명:</strong> LibreOffice + QCAD 변환 엔진을 사내 서버에 탑재하고, <strong>파일이 업로드되는 즉시 백그라운드에서 PDF로 변환을 완료</strong>해 저장해 둡니다. 사용자가 열람 시 이미 변환된 PDF를 PDF.js로 보여주므로 <strong>대기 시간 0초에 완벽한 사내 보안</strong>을 달성하는 실무상 가장 검증된 안전한 구성입니다.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="bp-card premium">
|
||||
<h3><i class="fa-solid fa-crown"></i> 2순위: 설치형 OnlyOffice 서버 도입</h3>
|
||||
<p>
|
||||
<strong>대상:</strong> MS Office 파일군 (Word, Excel, PPT)<br>
|
||||
<strong>설명:</strong> 사내 인프라(Docker 등)에 무료 오픈소스인 <strong>OnlyOffice Document Server</strong>를 1대 개설하여 iframe으로 연동합니다. 변환 대기 시간 없이 오리지널 수준의 재현력을 자랑하며, 웹 상에서 직접 편집 및 문서 다중 협업 기능까지 추가할 수 있는 중대형 인트라넷을 위한 최고급 구성입니다.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<footer>
|
||||
<p>© 2026 Antigravity. Web Document Viewer Implementation Guide for Enterprise. All Rights Reserved.</p>
|
||||
</footer>
|
||||
|
||||
<!-- 탭 전환 인터랙티브 자바스크립트 -->
|
||||
<script>
|
||||
function switchTab(tabId) {
|
||||
// 모든 탭 버튼 비활성화
|
||||
const buttons = document.querySelectorAll('.tab-btn');
|
||||
buttons.forEach(btn => btn.classList.remove('active'));
|
||||
|
||||
// 모든 탭 패널 숨기기
|
||||
const panels = document.querySelectorAll('.tab-panel');
|
||||
panels.forEach(panel => panel.classList.remove('active'));
|
||||
|
||||
// 클릭한 탭 활성화
|
||||
const clickedBtn = Array.from(buttons).find(btn => btn.getAttribute('onclick').includes(tabId));
|
||||
if (clickedBtn) clickedBtn.classList.add('active');
|
||||
|
||||
// 클릭한 탭 패널 노출
|
||||
const targetPanel = document.getElementById(tabId);
|
||||
if (targetPanel) targetPanel.classList.add('active');
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user