چگونه یک PDF Viewer با جاوااسکریپت بسازیم
ﺯﻣﺎﻥ ﻣﻄﺎﻟﻌﻪ: 8 دقیقه

چگونه یک PDF Viewer با جاوااسکریپت بسازیم

فرمت اسناد قابل حمل یا به طور خلاصه PDF، برای به اشتراک گذاشتن اسناد حاوی تعداد زیادی متن و تصاویر قالب‌بندی شده مناسب است، به خصوص اگر چاپ شود یا به صورت آفلاین خوانده شود. اگرچه اکثر مرورگرهای مدرن می‌توانند فایلهای PDF را نمایش دهند، اما آن‌ها با استفاده از یک مشاهده‌گر PDF که در یک برگه یا پنجره مستقل اجرا می‌شود، این کار را انجام می‌دهند و کاربران را مجبور به ترک وبسایت شما می‌کنند.

PDF.js یک کتابخانه جاوااسکریپتی متن‌باز است که به شما امکان می‌دهد فایلهای PDF را درست در صفحات وب خود تجزیه و ارائه کنید. در این آموزش نحوه استفاده از آن برای ایجاد یک نمایشگر کاملا سفارشی PDF از صفر تا صد را به شما نشان خواهیم داد.

1 – ایجاد رابط کاربری

بیایید با ایجاد یک صفحه وب جدید و اضافه کردن کد معمول HTML5 به آن شروع کنیم.

<!doctype html>
 
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>My PDF Viewer</title>
</head>
<body>
     
</body>
</html>

بعد در داخل تگ <body>، یک عنصر <div> ایجاد کنید که می‌تواند به عنوان ظرفی برای نمایشگر PDF ما باشد.

<div id="my_pdf_viewer">
     
</div>

در قلب مشاهده‌گر PDF ما یک عنصر <canvas> خواهد بود. ما صفحات فایل‌های PDF خود را در داخل آن ارائه می‌دهیم. بنابراین کد زیر را درون عنصر <div> اضافه کنید.

<div id="canvas_container">
    <canvas id="pdf_renderer"></canvas>
</div

برای ساده نگه داشتن کارها، در هر زمان مشخص فقط یک صفحه را در داخل canvas ارائه می‌دهیم. با این وجود به کاربران این امکان را می‌دهیم که با فشار دادن یک دکمه، به صفحه قبلی یا صفحه بعد بروند. علاوه بر این، برای نمایش شماره صفحه فعلی و اجازه دادن به کاربران برای رفتن به صفحه مورد نظرشان، رابط ما یک قسمت ورودی خواهد داشت.

<div id="navigation_controls">
    <button id="go_previous">Previous</button>
    <input id="current_page" value="1" type="number"/>
    <button id="go_next">Next</button>
</div>

برای پشتیبانی از عملیات بزرگنمایی، دو دکمه دیگر به رابط اضافه کنید: یکی برای بزرگ کردن و دیگری برای کوچک کردن.

<div id="zoom_controls">  
    <button id="zoom_in">+</button>
    <button id="zoom_out">-</button>
</div>

2 – استفاده از PDF.js

اکنون که یک رابط کاربری ساده برای مشاهده‌گر PDF ما آماده است، اجازه دهید PDF.js را به صفحه وب خود اضافه کنیم. از آنجا که آخرین نسخه این کتابخانه در CDNJS موجود است، می‌توانیم با اضافه کردن خطوط زیر به انتهای صفحه وب، این کار را انجام دهیم.

<script
    class='lozad' data-src='https://cdnjs.cloudflare.com/ajax/libs/pdf.js/2.0.943/pdf.min.js'>
</script>

اگر ترجیح می‌دهید از نسخه محلی کتابخانه استفاده کنید، می‌توانید آن را از ریپازیتوری pdfjs-dist دانلود کنید.

3 – لود کردن فایل PDF

قبل از شروع بارگذاری یک فایل PDF، بیایید یک شی ساده جاوااسکریپت ایجاد کنیم تا حالت مشاهده‌گر PDF ما را ذخیره کند. در داخل آن سه مورد خواهیم داشت: یک ارجاع به خود فایل PDF، فهرست صفحه فعلی و سطح بزرگنمایی فعلی.

<script>
    var myState = {
        pdf: null,
        currentPage: 1,
        zoom: 1
    }
 
    // more code here
</script>

در این مرحله می‌توانیم با فراخوانی متد ()getDocument از شی pdfjsLib، که به صورت غیر همزمان اجرا می‌شود، فایل PDF خود را بارگیری کنیم.

pdfjsLib.getDocument('./my_document.pdf').then((pdf) => {
 
    // more code here
 
});

توجه داشته باشید که متد ()getDocument  از یک شی XMLHttpRequest برای بارگذاری فایل PDF استفاده می‌کند. این بدان معنی است که فایل باید در سرور وب وجود داشته باشد که به درخواست‌های متقابل اجازه بدهد.

اگر فایل PDF ندارید، می‌توانید یکی را از اینجا دریافت کنید.

پس از دانلود فایل PDF، می‌توانیم ویژگی pdf شیء حالت خود را به روز کنیم.

myState.pdf = pdf;

سرانجام، یک فراخوانی را به تابعی به نام render() اضافه کنید تا مشاهده‌گر PDF ما به طور خودکار صفحه اول فایل PDF را نمایش دهد. در مرحله بعدی تابع را تعریف می‌کنیم.

render();

4 – رندر کردن صفحه

با فراخوانی متد ()getPage از شیء pdf و انتقال شماره صفحه به آن، می‌توانیم به هر صفحه در داخل فایل PDF مرجع برسیم. اکنون بیایید صفحه فعلی شیئمان را به آن منتقل کنیم. این روش بیش از یک promise را بر می‌گرداند، بنابراین برای رسیدگی به نتیجه به یک تابع پاسخ گیری نیاز خواهیم داشت.

بر این اساس، یک تابع جدید به نام render() با کد زیر ایجاد کنید:

function render() {
    myState.pdf.getPage(myState.currentPage).then((page) => {
 
        // more code here
 
    }

برای رندر صفحه، باید متد render() شیء صفحه موجود را فراخوانی کنیم.این متد انتظار دارد مفهوم دو بعدی canvas ما و شی صفحه PageViewport، که می‌توانیم با فراخوانی متد ()getViewport بدست آوریم T از آنجا که متد ()getViewport از سطح بزرگنمایی مورد نظر به عنوان یک آرگومان انتظار دارد، باید ویژگی بزرگنمایی شیء حالت خود را به آن منتقل کنیم.

var canvas = document.getElementById("pdf_renderer");
var ctx = canvas.getContext('2d');
 
var viewport = page.getViewport(myState.zoom);

ابعاد viewport به اندازه اصلی صفحه و میزان بزرگنمایی بستگی دارد. برای اینکه مطمئن شویم که تمام محتوا در canvas نمایش داده می‌شود، باید اندازه canvas خود را تغییر دهیم تا مطابق با viewport باشد. که در اینجا آمده است:

canvas.width = viewport.width;
canvas.height = viewport.height;

در این مرحله، می‌توانیم جلو برویم و صفحه را رندر کنیم.

page.render({
    canvasContext: ctx,
    viewport: viewport
});

اگر صفحه وب را در یک مرورگر باز کنید، اکنون می‌توانید صفحه اول فایل PDF خود را مشاهده کنید.

شاید متوجه شده باشید که اندازه مشاهده‌گر PDF ما در حال حاضر به اندازه صفحه ارائه شده و میزان بزرگنمایی بستگی دارد. این ایده‌آل نیست زیرا ما نمی‌خواهیم در حالی که کاربران با مشاهده‌گر PDF در تعامل هستند، تاثیر ناخوشایندی بر آن‌ها بگذارد.

برای برطرف کردن این مسئله، تنها کاری که باید انجام دهیم این است که عرض و ارتفاع ثابت را به عنصر <div> بدهیم که canvas ما را محصور می‌کند و خاصیت سرریز آن را به صورت خودکار تنظیم می‌کند. این ویژگی در صورت لزوم، میله‌های پیمایش را به عنصر <div> اضافه می‌کند و به کاربران امکان می‌دهد تا هم به صورت افقی و هم به صورت عمودی حرکت کنند.

کد زیر را درون تگ <head> صفحه وب اضافه کنید:

<style>
    #canvas_container {
        width: 800px;
        height: 450px;
        overflow: auto;
    }
</style>

البته شما آزاد هستید که عرض و ارتفاع را تغییر دهید یا حتی از مدیا کوئری‌ها استفاده کنید تا عنصر <div> مطابق با شرایط شما باشد.

به صورت اختیاری می‌توانید کدهای CSS زیر را درج کنید تا عنصر <div> مجزا تر به نظر برسد:

#canvas_container {
    background: #333;
    text-align: center;
    border: solid 3px;
}

اگر حالا صفحه وب را رفرش کنید، باید چیزی شبیه به تصویر زیر را در صفحه خود مشاهده کنید:

 

5 – عوض کردن صفحه فعلی

در حال حاضر مشاهده‌گر PDF جاوااسکریپت ما قادر به نمایش تنها صفحه اول فایل PDF است که به آن داده شده است. برای اینکه کاربران بتوانند صفحه ارائه شده خود را تغییر دهند، باید اکنون رویداد کلیک را به دکمه‌های go_prelish و go_next که قبلاً ایجاد کرده‌ایم اضافه کنیم.

در داخل برنامه رویداد دکمه go_preicion، باید ویژگی شی صفحه فعلی را کاهش دهیم، تا مطمئن شویم که در زیر 1 قرار نمی گیرد. بعد از انجام این کار می‌توانیم به راحتی با فراخوانی تابع ()render عملکرد جدید صفحه را ارائه دهیم.

بعلاوه، باید مقدار فیلد text_page فعلی را به روز کنیم تا شماره صفحه جدید نمایش داده شود. کد زیر آن را به شما نشان می‌دهد:

document.getElementById('go_previous')
        .addEventListener('click', (e) => {
            if(myState.pdf == null
               || myState.currentPage == 1) return;
            myState.currentPage -= 1;
            document.getElementById("current_page")
                    .value = myState.currentPage;
            render();
        });

به طور مشابه، در داخل رویداد دکمه go_next، باید ویژگی فعلی را افزایش دهیم ضمن اینکه از تعداد صفحات موجود در فایل PDF تجاوز نکند، که می‌توانیم با استفاده از خاصیت numPages هدف pdfInfo_را تعیین کنیم.

document.getElementById('go_next')
        .addEventListener('click', (e) => {
            if(myState.pdf == null
               || myState.currentPage > myState.pdf
                                               ._pdfInfo.numPages) 
               return;
         
            myState.currentPage += 1;
            document.getElementById("current_page")
                    .value = myState.currentPage;
            render();
        });

در آخر، ما باید یک رویداد کلیدی را به قسمت متن text_page اضافه کنیم تا کاربران بتوانند با وارد کردن شماره صفحه و زدن کلید Enter، مستقیما به صفحه مورد نظر خود پرش کنند. در داخل رویداد، باید اطمینان حاصل کنیم که عددی که کاربر وارد کرده است هم از صفر بیشتر است و هم از خاصیت numPages کمتر یا برابر است.

document.getElementById('current_page')
        .addEventListener('keypress', (e) => {
            if(myState.pdf == null) return;
         
            // Get key code
            var code = (e.keyCode ? e.keyCode : e.which);
         
            // If key code matches that of the Enter key
            if(code == 13) {
                var desiredPage = 
                        document.getElementById('current_page')
                                .valueAsNumber;
                                 
                if(desiredPage >= 1 
                   && desiredPage <= myState.pdf
                                            ._pdfInfo.numPages) {
                        myState.currentPage = desiredPage;
                        document.getElementById("current_page")
                                .value = desiredPage;
                        render();
                }
            }
        });

مشاهده گر PDF ما اکنون می‌تواند هر صفحه از فایل PDF را نمایش دهد.

6 – تغییر دادن سطح زوم

از آنجا که تابع render() ما از ویژگی بزرگنمایی شیء در هنگام رندر صفحه استفاده می‌کند، تنظیم سطح بزرگنمایی به آسانی با افزایش یا کاهش ویژگی و فراخوانی تابع است.

در داخل دکمه zoom_in در لیست کلیک روی رویداد کلیک کنید، بیایید ویژگی بزرگنمایی را به 0.5 افزایش دهیم.

document.getElementById('zoom_in')
        .addEventListener('click', (e) => {
            if(myState.pdf == null) return;
            myState.zoom += 0.5;
            render();
        });

و در داخل دکمه zoom_out رویداد کلیک کنید، بیایید ویژگی بزرگنمایی را به 0.5 کاهش دهیم.

document.getElementById('zoom_out')
        .addEventListener('click', (e) => {
            if(myState.pdf == null) return;
            myState.zoom -= 0.5;

شما می‌توانید مرزهای بالا و پایین را به ویژگی بزرگنمایی اضافه کنید، اما این کار لازم نیست.

مشاهده‌گر PDF ما آماده است. اگر مجددا صفحه وب را رفرش کنید، باید بتوانید تمام صفحات موجود در فایل PDF را مشاهده کرده و در آن بزرگنمایی یا زوم کنید.

جمع‌بندی

اکنون می‌دانید که چگونه از PDF.js برای ایجاد یک PDF خوان جاوااسکریپت سفارشی برای وبسایت خود استفاده کنید. با استفاده از آن، شما می‌توانید ضمن نمایش بروشورهای سازمان، برگه‌های سفید، فرم‌ها و سایر اسناد به طور کلی به عنوان نسخه‌های توزیع شده، یک تجربه کاربری یکپارچه را ارائه دهید.

منبع

چه امتیازی برای این مقاله میدهید؟

خیلی بد
بد
متوسط
خوب
عالی
5 از 4 رای

/@heshmati74
عرفان حشمتی
Full-Stack Web Developer

کارشناس معماری سیستم های کامپیوتری، طراح و توسعه دهنده وب سایت

دیدگاه و پرسش

برای ارسال دیدگاه لازم است وارد شده یا ثبت‌نام کنید ورود یا ثبت‌نام

در حال دریافت نظرات از سرور، لطفا منتظر بمانید

در حال دریافت نظرات از سرور، لطفا منتظر بمانید

عرفان حشمتی

Full-Stack Web Developer

مقالات برگزیده

مقالات برگزیده را از این قسمت میتوانید ببینید

مشاهده همه مقالات