관리 메뉴

피터의 개발이야기

웹페이지 내에 PDF 웹 뷰어 만들기 본문

개발이야기

웹페이지 내에 PDF 웹 뷰어 만들기

기록하는 백앤드개발자 2021. 1. 21. 08:00
반응형

오늘은 웹개발에 대한 부분을 이야기 해 보도록 하겠습니다. 저는 참고로 리엑트 개발자가 아닙니다.

하지만 업무상 리엑트 웹어드민을 종종 수정 개발을 하기도 합니다.

 

개발 사항은 어드민 웹페이지 중에 이미지를 보여주는 부분에 PDF도 볼 수 있도록 수정하는 것이었습니다.

 

 

1. PDF.js

 

 PDF.js를 이용해 Javascript으로 구현하는 방법입니다.

무엇보다 예제 정리가 잘 되어 있습니다. 

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>'Hello, world!' example</title>
</head>
<body>

<h1>'Hello, world!' example</h1>

<canvas id="the-canvas" style="border: 1px solid black; direction: ltr;"></canvas>

<script src="../../node_modules/pdfjs-dist/build/pdf.js"></script>

<script id="script">
  //
  // If absolute URL from the remote server is provided, configure the CORS
  // header on that server.
  //
  var url = './helloworld.pdf';

  //
  // The workerSrc property shall be specified.
  //
  pdfjsLib.GlobalWorkerOptions.workerSrc =
    '../../node_modules/pdfjs-dist/build/pdf.worker.js';

  //
  // Asynchronous download PDF
  //
  var loadingTask = pdfjsLib.getDocument(url);
  loadingTask.promise.then(function(pdf) {
    //
    // Fetch the first page
    //
    pdf.getPage(1).then(function(page) {
      var scale = 1.5;
      var viewport = page.getViewport({ scale: scale, });

      //
      // Prepare canvas using PDF page dimensions
      //
      var canvas = document.getElementById('the-canvas');
      var context = canvas.getContext('2d');
      canvas.height = viewport.height;
      canvas.width = viewport.width;

      //
      // Render PDF page into canvas context
      //
      var renderContext = {
        canvasContext: context,
        viewport: viewport,
      };
      page.render(renderContext);
    });
  });
</script>

<hr>
<h2>JavaScript code:</h2>
<pre id="code"></pre>
<script>
  document.getElementById('code').textContent =
      document.getElementById('script').text;
</script>
</body>
</html>

 

 

base64 encoded PDF 뷰어 

무엇보다 좋은 점은 base64로 인코딩된 PDF를 보여줄 수 있다는 점입니다.

보안상 파일을 암호화가 필요한 경우 base64+ 암호화 토큰을 붙여 전송 시에 유용한 방법입니다.

아래는 예제로 제공되는 코드입니다. 더 다양한 예제는 여기를 클릭하세요.

// atob() is used to convert base64 encoded PDF to binary-like data.
// (See also https://developer.mozilla.org/en-US/docs/Web/API/WindowBase64/
// Base64_encoding_and_decoding.)
var pdfData = atob(
  'JVBERi0xLjcKCjEgMCBvYmogICUgZW50cnkgcG9pbnQKPDwKICAvVHlwZSAvQ2F0YWxvZwog' +
  'IC9QYWdlcyAyIDAgUgo+PgplbmRvYmoKCjIgMCBvYmoKPDwKICAvVHlwZSAvUGFnZXMKICAv' +
  'TWVkaWFCb3ggWyAwIDAgMjAwIDIwMCBdCiAgL0NvdW50IDEKICAvS2lkcyBbIDMgMCBSIF0K' +
  'Pj4KZW5kb2JqCgozIDAgb2JqCjw8CiAgL1R5cGUgL1BhZ2UKICAvUGFyZW50IDIgMCBSCiAg' +
  'L1Jlc291cmNlcyA8PAogICAgL0ZvbnQgPDwKICAgICAgL0YxIDQgMCBSIAogICAgPj4KICA+' +
  'PgogIC9Db250ZW50cyA1IDAgUgo+PgplbmRvYmoKCjQgMCBvYmoKPDwKICAvVHlwZSAvRm9u' +
  'dAogIC9TdWJ0eXBlIC9UeXBlMQogIC9CYXNlRm9udCAvVGltZXMtUm9tYW4KPj4KZW5kb2Jq' +
  'Cgo1IDAgb2JqICAlIHBhZ2UgY29udGVudAo8PAogIC9MZW5ndGggNDQKPj4Kc3RyZWFtCkJU' +
  'CjcwIDUwIFRECi9GMSAxMiBUZgooSGVsbG8sIHdvcmxkISkgVGoKRVQKZW5kc3RyZWFtCmVu' +
  'ZG9iagoKeHJlZgowIDYKMDAwMDAwMDAwMCA2NTUzNSBmIAowMDAwMDAwMDEwIDAwMDAwIG4g' +
  'CjAwMDAwMDAwNzkgMDAwMDAgbiAKMDAwMDAwMDE3MyAwMDAwMCBuIAowMDAwMDAwMzAxIDAw' +
  'MDAwIG4gCjAwMDAwMDAzODAgMDAwMDAgbiAKdHJhaWxlcgo8PAogIC9TaXplIDYKICAvUm9v' +
  'dCAxIDAgUgo+PgpzdGFydHhyZWYKNDkyCiUlRU9G');

// Loaded via <script> tag, create shortcut to access PDF.js exports.
var pdfjsLib = window['pdfjs-dist/build/pdf'];

// The workerSrc property shall be specified.
pdfjsLib.GlobalWorkerOptions.workerSrc = '//mozilla.github.io/pdf.js/build/pdf.worker.js';

// Using DocumentInitParameters object to load binary data.
var loadingTask = pdfjsLib.getDocument({data: pdfData});
loadingTask.promise.then(function(pdf) {
  console.log('PDF loaded');
  
  // Fetch the first page
  var pageNumber = 1;
  pdf.getPage(pageNumber).then(function(page) {
    console.log('Page loaded');
    
    var scale = 1.5;
    var viewport = page.getViewport({scale: scale});

    // Prepare canvas using PDF page dimensions
    var canvas = document.getElementById('the-canvas');
    var context = canvas.getContext('2d');
    canvas.height = viewport.height;
    canvas.width = viewport.width;

    // Render PDF page into canvas context
    var renderContext = {
      canvasContext: context,
      viewport: viewport
    };
    var renderTask = page.render(renderContext);
    renderTask.promise.then(function () {
      console.log('Page rendered');
    });
  });
}, function (reason) {
  // PDF loading error
  console.error(reason);
});

 

 

2. Iframe Code

어드민이 리엑트로 개발되어 최소한의 수정으로 PDF뷰어를 구현해야했습니다.

그래서 선택한 방법은 Iframe을 이용하는 것입니다. 소스는 정말 간단하였습니다. 

제가 한것은 기존의 이미지 뷰어와 구분하기 위해 확장자를 식별한 후에 PDF용 iframe를 생성합니다.

 

const isPdf = 
    images && imageLength > 0 ? 
      (images[0].substring(images[0].lastIndexOf('.')+1, images[0].length).toLowerCase() == 'pdf')
      :false;
      
      
<iframe src={images[0]} width={'100%'} height={'100%'}></iframe>

 

 

 

브라우저에서 PDF를 열었을 때의 축소판으로 보여줍니다. 

확대도 가능하였습니다. 

 

 

 

반응형
Comments