브라우저에서 Word 문서 미리보기 구현하기: docx-preview와 mammoth 비교

브라우저 기반 Word 문서 미리보기 핵심 라이브러리

프론트엔드 환경에서 Word 문서(.docx)를 미리보기 형태로 표시해야 할 때, 서버 변환 없이 클라이언트 단독으로 해결할 수 있는 두 가지 대표 라이브러리를 살펴봅니다.

docx-preview: 원본 그대로의 렌더링

Office 화면과 거의 동일한 시각적 결과를 추구할 때 선택합니다. 페이지 나누기, 머리글/바닥글, 표 서식 등 문서의 레이아웃을 정밀하게 재현합니다.

npm install docx-preview
import { renderAsync } from 'docx-preview';

const previewDocument = async (fileStream, targetElement) => {
  try {
    await renderAsync(fileStream, targetElement);
  } catch (err) {
    console.error('문서 렌더링 실패:', err);
  }
};

// 사용 예시
const fileData = await fetch('/sample.docx').then(r => r.blob());
previewDocument(fileData, document.querySelector('#viewer'));

mammoth: 구조 중심의 변환

Word 문서를 의미론적인 HTML로 변환하는 방식입니다. 시각적 정확도보다 콘텐츠 구조와 접근성을 우선시합니다.

npm install mammoth
import mammoth from 'mammoth';

const extractDocument = async (buffer) => {
  const { value: htmlContent, messages: logs } = await mammoth.convertToHtml({
    arrayBuffer: buffer
  });
  
  if (logs.length) {
    console.log('변환 알림:', logs);
  }
  
  return htmlContent;
};

실전 적용 시나리오

시나리오 A: 문서 뷰어 구축

사용자가 업로드한 Word 파일을 "Office에서 보는 것처럼" 확인해야 하는 경우, docx-preview를 구성합니다.

const initializeViewer = async (documentUrl) => {
  const response = await fetch(documentUrl);
  const blobData = await response.blob();
  
  const viewerConfig = {
    className: 'word-viewer',
    inWrapper: true,
    breakPages: true,
    renderHeaders: true,
    renderFooters: true,
    renderFootnotes: true,
    ignoreWidth: false
  };
  
  await renderAsync(
    blobData,
    document.getElementById('preview-zone'),
    document.getElementById('style-injection'),
    viewerConfig
  );
};

성능 고려사항: 100페이지 이상의 대용량 문서는 렌더링 지연 발생 가능. 필요 시 페이지 단위 지연 로딩 또는 가상 스크롤 적용 권장.

시나리오 B: 콘텐츠 편집 시스템

업로드된 Word 파일에서 텍스트를 추출하여 리치 텍스트 편집기에 주입하는 경우, mammoth가 적합합니다.

const transformForEditing = async (uploadedFile) => {
  const buffer = await uploadedFile.arrayBuffer();
  
  const styleRules = [
    "p[style-name='Heading 1'] => h1",
    "p[style-name='Heading 2'] => h2", 
    "p[style-name='Quote'] => blockquote",
    "p[style-name='Code'] => pre"
  ];
  
  const result = await mammoth.convertToHtml(
    { arrayBuffer: buffer },
    { styleMap: styleRules }
  );
  
  return {
    html: result.value,
    warnings: result.messages
  };
};

고급 설정 및 최적화

docx-preview 세부 제어

옵션기능기본값
breakPages페이지 분리 표시true
renderComments주석 렌더링false
useBase64URL이미지 인코딩 방식false
ignoreHeight페이지 높이 무시false
// 단일 연속 문서로 표시 (페이지 나누기 제거)
renderAsync(blob, container, null, {
  breakPages: false,
  ignoreHeight: true,
  className: 'seamless-document'
});

mammoth 이미지 처리 개선

기본 base64 인코딩은 문서 크기를 급격히 증가시킵니다. Blob URL 전환으로 메모리 사용량을 절감합니다.

const optimizedOptions = {
  convertImage: mammoth.images.imgElement((imgData) => 
    imgData.readAsArrayBuffer().then((rawBuffer) => {
      const imageBlob = new Blob([rawBuffer], { 
        type: imgData.contentType 
      });
      return {
        src: URL.createObjectURL(imageBlob),
        alt: imgData.altText || '문서 이미지'
      };
    })
  )
};

mammoth.convertToHtml({ arrayBuffer: docBuffer }, optimizedOptions);

대안 방식: Microsoft Office Online 임베드

공개 문서의 경우 Microsoft 제공 뷰어를 활용할 수 있습니다.

<iframe 
  src="https://view.officeapps.live.com/op/embed.aspx?src=공개문서URL"
  width="100%" 
  height="600" 
  frameborder="0">
</iframe>

제약조건: 문서가 인터넷에 공개되어 있어야 하며, 내부망 문서에는 적용 불가.

선택 가이드

기준docx-previewmammoth
시각적 정확도⭐⭐⭐⭐⭐⭐⭐⭐
HTML 깔끔함⭐⭐⭐⭐⭐⭐⭐
번들 크기중간 (~500KB)소형 (~100KB)
스타일 커스터마이징제한적자유로운
복잡한 표/차트완벽 지원단순화

요약: 원본 레이아웃 보존이 중요하면 docx-preview, 텐츠 재가공 및 웹 최적화가 목표면 mammoth를 채택하세요.

태그: docx-preview mammoth.js Word document rendering frontend document viewer Office Open XML

6월 15일 16:44에 게시됨