[pdfjs] pdf viewer 파일 다운로드 버튼 없는 뷰어
간혹 파일 다운로드 기능이 없는 pdf viewer를 찾는것을 본적이 있어 올립니다.
이건 커스텀 한것이기 때문에 pdfjs의 샘플에 있는 pdf뷰어에 다운로드 버튼을 없앤것과는 다른것입니다.
아래는 테스트용으로 간략하게 만든것으로 정식서비스에선 퍼블리셔와 디자이너의 도움을 받아 약간만 꾸미면 됩니다.
- 스크롤기능을 이용하여 페이지 이동에 대한 기능. 표시기능
- url호 호출할 수 있습니다. 만약 버튼을 이용하여 다른것을 호출해야 된다면(새로고침 없이)
오픈을 하게 되면 기존에 보여준것은 삭제하는 기능이 필요한데 직접 구현을 해야 합니다. jquery remove 기능 활용하면 됩니다.
- 캔버스에 있는것을 간단하게 섬네일로 만들어 줍니다
- 입력하면 해당 페이지를 직접이동 할 수 있습니다.
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>jQuery test </title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.2/dist/css/bootstrap.min.css" crossorigin="anonymous">
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.2/dist/js/bootstrap.min.js" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.2/dist/js/bootstrap.bundle.min.js" crossorigin="anonymous"></script>
</head>
<body>
<div class="container-fluid">
<div class="row">
<div class="col-md-12">
<div class="row navbar fixed-top navbar-light bg-info ">
<div class="col-md-4">
</div>
<div class="col-md-4">
<div style="width: 200px;">
<span> <input type="text" id="currentPageNum" name="currentPageNum" style="float: left; text-align: right; width: 80px"></span>
<span style="float: left; width: 30px; text-align: center; color: white"> / </span>
<span id="max_pdf_page" style="float: left; width: 70px; color: white"></span>
</div>
</div>
<div class="col-md-4">
</div>
<br><br><hr>
</div>
<div class="row" style="margin-top: 100px;">
<div class="col-md-3">
<div id="thumb_list"> </div>
</div>
<div class="col-md-9">
<div id="pdfBox" style="overflow-y:scroll; height:100%; padding-bottom: 730px;"> </div>
</div>
</div>
</div>
</div>
</div>
</body>
</html>
<script>
// ------------------------------------------------------------------------------
// ------------------------------------------------------------------------------
// 사용자
let MAX_PDF_PAGE = 0;
var scrollTop = 0;
// Loaded via <script> tag, create shortcut to access PDF.js exports.
var pdfjsLib = window['pdfjs-dist/build/pdf'];
// The workerSrc property shall be specified.
var pdfDoc = null,
pageNum = 0,
pageRendering = false,
pageNumPending = null,
scale = 1;
// canvas = document.getElementById('the-canvas'),
// ctx = canvas.getContext('2d');
/**
* Get page info from document, resize canvas accordingly, and render page.
* @param num Page number.
*/
function renderPage(num) {
pageRendering = true;
// Using promise to fetch the page
pdfDoc.getPage(num).then(function(page)
{
pageNum++;
var canvasBox = document.getElementById('pdfBox');
var viewport = page.getViewport({scale: scale});
var pageWidth = viewport.width;
var pageHeight = viewport.height;
var canvas = document.createElement('canvas');
canvas.setAttribute("id", "page_" + pageNum );
canvas.setAttribute("style", 'width: ' + pageWidth + 'px; height: ' + pageHeight + 'px; border: dotted 1px green');
canvas.width = pageWidth;
canvas.height = pageHeight;
canvasBox.appendChild(canvas);
// Render PDF page into canvas context
var ctx = canvas.getContext('2d');
var renderContext = {
canvasContext: ctx,
viewport: viewport
};
var renderTask = page.render(renderContext);
// Wait for rendering to finish
renderTask.promise.then(function( event )
{
pageRendering = false;
if (pageNumPending !== null) {
// New page rendering is pending
renderPage(pageNumPending);
pageNumPending = null;
}
let nowPageNum = page._pageIndex + 1;
// create canvas image
var imgUrl = canvas.toDataURL();
var imgThumb = document.getElementById('thumb_img_' + nowPageNum );
imgThumb.setAttribute('src', imgUrl); // base64
imgThumb.setAttribute('border', '1');
imgThumb.setAttribute('width', 150);
});
});
}
/**
* Asynchronously downloads PDF.
*/
function pdf_url( url )
{
pdfjsLib.getDocument(url).promise.then(function(pdfDoc_) {
pdfDoc = pdfDoc_;
// 전체 페이지 갯수를 상단에 넣어 준다
MAX_PDF_PAGE = pdfDoc.numPages;
$('#max_pdf_page').text(MAX_PDF_PAGE);
// 섬네일 보여줄 자리를 미리 만들어 주는것
let thumbList = '';
let pageNum = 0;
for ( pageNum = 1; pageNum <= MAX_PDF_PAGE; pageNum++ ) {
var alt = pageNum + ' page';
thumbList += '<a id="thumb_href_' + pageNum + '" onclick="pdf_page_move( ' + pageNum + ' )"><img id="thumb_img_' + pageNum + '" alt="' + alt + '"></a><br><div style="text-align: left;"> - ' + pageNum + ' - </div><p></p>';
}
$( "#thumb_list" ).append(thumbList);
// show pages
pageNum = 0;
for ( pageNum = 1; pageNum <= MAX_PDF_PAGE; pageNum++ ) {
renderPage(pageNum);
}
});
}
var url = 'https://raw.githubusercontent.com/mozilla/pdf.js/ba2edeae/web/compressed.tracemonkey-pldi-09.pdf';
pdf_url( url );
// ============================== user function ==============================
$(document).ready(function() {
// page move
$('#currentPageNum').keyup(function(event) {
if (event.key == "Enter") {
var pageNum = $("#currentPageNum").val();
pdf_page_move( pageNum );
}
});
// current page show
$(document).scroll(function()
{
scrollTop = $(this).scrollTop();
// console.log(scrollTop);
let pageScrollTop = 0;
let pageHeight = 0;
for ( var pageNum = 1; pageNum <= MAX_PDF_PAGE; pageNum++ ) {
pageScrollTop = $("#page_"+pageNum).offset().top;
pageHeight = $('#page_'+pageNum).outerHeight();
if ( scrollTop >= pageScrollTop && scrollTop <= pageScrollTop + pageHeight ) {
// console.log(pageNum);
$("#currentPageNum").val(pageNum);
break;
}
}
});
$("#currentPageNum").val(1);
});
/**
* pdf page move
*/
function pdf_page_move( pageNum ) {
$("#currentPageNum").val(pageNum);
$('html, body').animate({ scrollTop: $("#page_"+pageNum).offset().top }, 50);
}
</script>