HomeLập trìnhJavaScriptCách trích xuất...

Cách trích xuất các trang từ PDF và kết xuất chúng bằng JavaScript


PDF là viết tắt của định dạng tài liệu di động. Các tệp PDF được Adobe thiết kế vào những năm 90 cho Windows. Chúng là những tài liệu độc lập với sự hỗ trợ cho gần như tất cả các hệ điều hành chính.

Nhưng đôi khi bạn sẽ cần sửa đổi một tệp PDF cho phù hợp với nhu cầu của mình chứ không chỉ xem nó. Thật không may, phần mềm có sẵn dành cho các tệp PDF thường không đáp ứng được các yêu cầu chuyên biệt của bạn.

Nhưng bạn là một lập trình viên, phải không? Tại sao không tạo một số phần mềm giúp PDF hoạt động như bạn muốn? Vâng, đây là nguồn cảm hứng cho bài viết này.

Trong bài viết này, chúng ta sẽ khám phá tất cả các thư viện liên quan đến PDF phổ biến trong JavaScript. Tại sao lại là JavaScript? Bởi vì nó có sẵn một số gói PDF khá tốt và mọi người thích nó. Đặc biệt là bản thân tôi.

Dự án Trình xem PDF Bạn sẽ Xây dựng trong Hướng dẫn này

Pdf_Modification_--
Ảnh chụp màn hình của trình xem PDF mà bạn sẽ xây dựng

Đây là bản trình diễn trực tiếp về những gì bạn sẽ xây dựng trong hướng dẫn này.

  1. Trước tiên, chúng ta sẽ khám phá một số gói PDF phổ biến hiện có dành cho công việc liên quan đến PDF trong JavaScript. Sau đó, chúng tôi sẽ so sánh chúng và tìm gói tốt nhất phù hợp với yêu cầu của chúng tôi.
  2. Tiếp theo, chúng tôi sẽ tải một tệp PDF hiện có và trích xuất một số trang từ tệp đó. Các trang được trích xuất sẽ tạo thành một tài liệu PDF mới.
  3. Sau đó, chúng tôi sẽ hiển thị tệp PDF mới (mà chúng tôi đã tạo ở bước thứ 2) bên trong trình duyệt.
  4. Cuối cùng, chúng tôi sẽ tải xuống bản PDF mới để sử dụng sau này.

Vì vậy, đây là tất cả các bước chúng ta sẽ thực hiện ở đây. Tôi hy vọng bạn đang vui mừng để xem kết quả. Hãy đi sâu vào.

Thư viện PDF cho JavaScript

Tôi đã phát hiện ra hai loại thư viện PDF chính trong JavaScript. Một là để hiển thị PDF và một là để thao tác (hoặc sửa đổi) PDF. Tôi đã tìm thấy rất nhiều thư viện PDF sau khi tìm kiếm khoảng một giờ và đây là những lựa chọn tốt nhất của tôi.

Tất cả các gói được liệt kê ở đây là các gói miễn phí và mã nguồn mở. Bạn có thể tìm thấy tất cả các gói này trong sổ đăng ký npm.

pdfjs

Gói này được tạo bởi Mozilla, công ty đứng sau trình duyệt web Firefox. pdfjs là một nền tảng dựa trên các tiêu chuẩn web để phân tích cú pháp và hiển thị các tệp PDF.
Khi bạn xem PDF trong Firefox, trình xem PDF được tạo bằng gói pdfjs này.

Sức mạnh cốt lõi của gói này là kết xuất PDF trên trang web. Các tính năng sửa đổi PDF khác rất hạn chế với gói này. Nếu bạn muốn tạo trình xem PDF tùy chỉnh cho trang web của mình, có lẽ đây là gói bạn đang tìm kiếm.

pdfjs có API rất đơn giản. Họ có rất nhiều hướng dẫn để bắt đầu với thư viện. Nếu chưa đủ thuyết phục, hãy thử chơi thư viện này một thời gian và chắc chắn bạn sẽ mê mẩn nó.

pdf-lib

Không giống như gói pdfjs trước đó, pdf-lib chủ yếu được sử dụng để tạo và thao tác PDF. Bạn có thể tự động tạo một tài liệu PDF mới với gói này theo nhu cầu của mình.

Gói này có hỗ trợ mạnh mẽ để sửa đổi một tài liệu hiện có. Bạn có thể thực hiện nhiều sửa đổi PDF với thư viện này. Ví dụ: bạn có thể thực hiện tách và hợp nhất PDF, đồng thời có thể trích xuất một trang, chú thích tài liệu pdf, thêm dàn bài và nhiều thứ khác mà bạn có thể tưởng tượng.

Đọc thêm  Cách sử dụng thư viện JavaScript trong ứng dụng Angular 2+

Nó chỉ có JavaScript là một phần phụ thuộc. Vì vậy, nó có thể chạy trên mọi thiết bị có thời gian chạy JavaScript. Trình duyệt, Nodejs, Deno và React Native được hỗ trợ tốt. Nếu bạn có thể quản lý để cài đặt JavaScript trên thiết bị, thì chắc chắn thư viện này sẽ hoạt động.

Hạn chế chính của pdf-lib là nó không có hỗ trợ hiển thị mạnh mẽ. Nếu bạn muốn tạo một giao diện người dùng đẹp để xem pdf với thư viện này, thì pdf-lib không phải là lựa chọn phù hợp cho bạn. Trong trường hợp này, bạn nên sử dụng pdfjs để thay thế.

pdfjs #2

Nếu bạn đang nghĩ rằng tôi đang lặp lại chính mình, thì tôi không phải vậy. Đây là thư viện JavaScript để tạo tài liệu PDF. Nó có một API rất đơn giản để làm việc.

Thư viện pdfjs trước đây mà chúng ta đã thảo luận có hỗ trợ hiển thị rất mạnh trong giao diện người dùng nhưng nó thiếu các tính năng tạo và sửa đổi PDF.

Nhưng thư viện này được xây dựng với mục đích tạo PDF. Nó có một API rất đơn giản và thân thiện với người mới bắt đầu. Bạn có thể so sánh nó với gói pdf-lib.

Hạn chế chính của thư viện pdfjs này là hỗ trợ sửa đổi các tài liệu hiện có vẫn đang trong giai đoạn thử nghiệm. Nó không hoạt động mọi lúc và vẫn đang trong quá trình hoàn thiện.

Nếu trọng tâm chính của bạn là sửa đổi PDF (ví dụ: trích xuất trang, hợp nhất, chia nhỏ, chú thích, v.v.) thì thư viện này có thể không phù hợp với bạn.

Nếu những người đóng góp có thể làm cho tính năng sửa đổi hoạt động, thì đây có thể là gói PDF tốt nhất cho JavaScript.

js-pdf

Không giống như tất cả các gói PDF được liệt kê ở trên, thư viện này là một con thú hoàn chỉnh. Bạn có thể thực hiện bất kỳ công việc nào liên quan đến PDF với thư viện này. Điều này giống như một jack của tất cả các thư viện giao dịch. Nếu bạn muốn một số nội dung phức tạp liên quan đến PDF, thì thư viện này có thể làm được.

Nhưng có những gói tốt hơn trong JavaScript rất tốt cho các tác vụ riêng lẻ. Ví dụ: pdfjs là trình kết xuất PDF tốt hơn js-pdf và pdf-lib có hỗ trợ sửa đổi tốt hơn js-pdf.

Ở đây tôi không nói về hiệu suất thực tế hoặc các loại số liệu khác, tôi đang nói về trải nghiệm của nhà phát triển. Tôi thấy rằng API của nó không trực quan lắm. Đối với người mới bắt đầu, nó có thể bị choáng ngợp ngay từ cái nhìn đầu tiên. Tuy nhiên, đây là ý kiến ​​​​của tôi và những gì tôi đã trải nghiệm khi sử dụng nó.

Tạo PDF là thế mạnh chính của thư viện này. Bạn có thể tạo bất kỳ loại PDF nào với bất kỳ thiết kế nào bạn có. Gói này sẽ làm tất cả các công việc nặng nhọc cho bạn. Nếu bạn có kinh nghiệm, thì đây có thể là đặt cược tốt nhất cho bạn.

phản ứng-pdf

Đúng như tên gọi, thư viện này chuyên về hệ sinh thái React. Việc sử dụng rất React-ish. Bạn có thể dễ dàng tạo một tài liệu với cú pháp giống như JSX của nó.

Bạn có thể tạo và hiển thị tài liệu PDF với các thành phần React đơn giản. Nhưng các tính năng rất hạn chế. Thư viện này chủ yếu dành cho việc tạo PDF.

Nếu mục tiêu của bạn là hiển thị tệp PDF cho người dùng thì bạn có thể sử dụng gói này. Là một người yêu thích React, bạn sẽ thích thư viện này. Kiểm tra sân chơi của họ và dành thời gian với gói này. Bằng cách này, bạn sẽ biết mình có cần thư viện này hay không.

Đọc thêm  Ví dụ JavaScript String.Replace() với RegEx

Tại sao chúng tôi sẽ sử dụng pdf-lib trong Hướng dẫn này

Trong số tất cả các thư viện PDF được đề cập ở trên, tôi sẽ sử dụng pdf-lib cho bài viết này. Vì chúng ta sẽ tách và hợp nhất các trang PDF, đồng thời hiển thị chúng trong trình duyệt, pdf-lib dường như là lựa chọn tốt nhất cho ngữ cảnh này.

Ngoài ra, pdf-lib có một API khá đơn giản để làm việc và tất cả các API này đều được ghi chép đầy đủ. Nếu bạn đang sử dụng TypeScript, bạn cũng có thể nhận được suy luận kiểu, điều này rất hữu ích.

Cuối cùng nhưng không kém phần quan trọng, ví dụ của họ rất tốt. Bạn có thể đứng dậy và chạy trong vài phút. Vì vậy, tôi thích thư viện này cho các trường hợp sử dụng của mình.

Cách đọc tệp PDF cục bộ trong JavaScript

Trước khi thực hiện bất kỳ thao tác nào trên tài liệu PDF của chúng tôi, chúng tôi phải lấy tài liệu từ người dùng. Đọc bất kỳ tập tin nào trong trình duyệt có thể được xử lý bởi FileReader API web.

Đầu tiên, chúng ta sẽ tạo và tạo nút nhập tệp, sau đó xử lý tệp đã tải lên bằng cách sử dụng FileReader API web.

<input type="file" id="file-selector" accept=".pdf" onChange={onFileSelected} />

Vì API Trình đọc tệp hoạt động với các lệnh gọi lại, tôi thấy async/await gọn gàng và dễ làm việc hơn rất nhiều. Vì vậy, hãy tạo một hàm trợ giúp để sửa đổi các cuộc gọi lại của Trình đọc tệp thành không đồng bộ/chờ đợi.

function readFileAsync(file) {
    return new Promise((resolve, reject) => {
      let reader = new FileReader();
      reader.onload = () => {
        resolve(reader.result);
      };
      reader.onerror = reject;
      reader.readAsArrayBuffer(file);
    });
  }

Bây giờ khi người dùng tải tệp lên bằng cách sử dụng đầu vào tệp trước đó, chúng tôi sẽ lắng nghe sự kiện đầu vào tệp và sau đó đọc tệp bằng cách này readFileAsync chức năng.

Việc thực hiện logic này trông như thế này trong mã:

const onFileSelected = async (e) => {
    const fileList = e.target.files;
    if (fileList?.length > 0) {
      const pdfArrayBuffer = await readFileAsync(fileList[0]);
    }
  };

Cho đến thời điểm này, PDF của chúng tôi đã được tải lên và chuyển đổi thành JavaScript ArrayBuffer. Vì chúng tôi đang trích xuất một loạt các trang từ PDF, chúng tôi muốn có một mảng có các số trang đó của PDF.

Tạo một mảng các số tự nhiên không khó trong JavaScript. Vì vậy, chúng tôi thực hiện một chức năng có tên range() để tạo tất cả các chỉ mục chúng tôi muốn.

Chúng tôi phải cung cấp số trang bắt đầu và số trang kết thúc và sau đó là số này range() chức năng có thể tạo ra một mảng với số trang thích hợp.

function range(start, end) {
	let length = end - start + 1;
	return Array.from({ length }, (_, i) => start + i - 1);
}

Ở đây chúng tôi thêm -1 vào cuối. Bạn có biết lý do không? Có – trong lập trình, các chỉ mục bắt đầu từ 0, không phải 1. Vì vậy, chúng tôi phải trừ -1 từ mỗi số trang để có được hành vi mà chúng tôi muốn.

Bây giờ hãy bắt đầu phần chính của bài viết này: trích xuất. Trước khi thực hiện bất kỳ công việc nào, hãy nhập thư viện pdf-lib.

import { PDFDocument } from "pdf-lib";

Lúc đầu, chúng tôi tải PDF ArrayBuffer chúng tôi đã nhận được từ trước onFileSelected chức năng. Sau đó, chúng tôi tải ArrayBuffer vào PDFDocument.load(arraybuffer) chức năng. Đây là bản PDF do người dùng của chúng tôi cung cấp. Để thuận tiện, chúng tôi sẽ gọi nó là pdfSrcDoc.

Bây giờ chúng ta sẽ tạo một tệp PDF mới. Tất cả các trang PDF được trích xuất từ ​​tài liệu do người dùng cung cấp được hợp nhất trong tài liệu mới. chúng tôi sử dụng PDFDocument.create() chức năng để làm điều đó. Để dễ sử dụng, chúng tôi gọi nó là pdfNewDoc.

Sau đó, chúng tôi sao chép các trang mong muốn từ pdfSrcDoc vào trong pdfNewDoc bằng cách sử dụng copyPages() chức năng. Sau đó, chúng tôi sẽ thêm trang đã sao chép vào pdfNewDoc.

Để lưu các thay đổi, hãy chạy pdfNewDoc.save(). Hãy tạo một chức năng gọi là extractPdfPage() để sử dụng lại logic. Mã bên trong hàm sẽ trông như thế này:

async function extractPdfPage(arrayBuff) {
    const pdfSrcDoc = await PDFDocument.load(arrayBuff);
    const pdfNewDoc = await PDFDocument.create();
    const pages = await pdfNewDoc.copyPages(pdfSrcDoc,range(2,3));
    pages.forEach(page=>pdfNewDoc.addPage(page));
    const newpdf= await pdfNewDoc.save();
    return newpdf;
  }

Chúng tôi đang trở lại một Uint8Array từ extractPdfPage() chức năng.

Đọc thêm  Cách tạo Mạng nơ-ron trong JavaScript chỉ với 30 dòng mã

Cách kết xuất PDF trong trình duyệt

Đến bây giờ, chúng tôi có một Uint8Array của một tệp PDF đã sửa đổi. Để hiển thị nó bên trong trình duyệt của bạn, chúng tôi phải chuyển đổi nó thành Blob.

Sau đó, chúng tôi sẽ tạo một URL từ đó và hiển thị nó bên trong iframe.

Bạn cũng có thể tạo trình xem PDF tùy chỉnh của mình bằng thư viện pdfjs như tôi đã đề cập ở trên. Nhưng nếu bạn không cần nhãn hiệu và tùy chỉnh như vậy, trình xem PDF mặc định của trình duyệt sẽ phù hợp với mục đích này.

function renderPdf(uint8array) {
    const tempblob = new Blob([uint8array], {
      type: "application/pdf",
    });
    const docUrl = URL.createObjectURL(tempblob);
    setPdfFileData(docUrl);
  }

Bây giờ bạn có thể dễ dàng hiển thị docUrl này được trả về từ renderPdf() chức năng bên trong một iframe.

Ví dụ mã hoàn chỉnh

Tôi đang sử dụng Next.js cho hướng dẫn này. Nếu bạn đang sử dụng một số framework hoặc vanilla JavaScript khác, kết quả sẽ tương tự. Đây là tất cả các mã cho dự án này:

import { useState } from "react";
import { PDFDocument } from "pdf-lib";

export default function Home() {
  const [pdfFileData, setPdfFileData] = useState();

  function readFileAsync(file) {
    return new Promise((resolve, reject) => {
      let reader = new FileReader();
      reader.onload = () => {
        resolve(reader.result);
      };
      reader.onerror = reject;
      reader.readAsArrayBuffer(file);
    });
  }

  function renderPdf(uint8array) {
    const tempblob = new Blob([uint8array], {
      type: "application/pdf",
    });
    const docUrl = URL.createObjectURL(tempblob);
    setPdfFileData(docUrl);
  }

  function range(start, end) {
    let length = end - start + 1;
    return Array.from({ length }, (_, i) => start + i - 1);
  }

  async function extractPdfPage(arrayBuff) {
    const pdfSrcDoc = await PDFDocument.load(arrayBuff);
    const pdfNewDoc = await PDFDocument.create();
    const pages = await pdfNewDoc.copyPages(pdfSrcDoc, range(2, 3));
    pages.forEach((page) => pdfNewDoc.addPage(page));
    const newpdf = await pdfNewDoc.save();
    return newpdf;
  }

  // Execute when user select a file
  const onFileSelected = async (e) => {
    const fileList = e.target.files;
    if (fileList?.length > 0) {
      const pdfArrayBuffer = await readFileAsync(fileList[0]);
      const newPdfDoc = await extractPdfPage(pdfArrayBuffer);
      renderPdf(newPdfDoc);
    }
  };

  return (
    <>
      <h1>Hello world</h1>
      <input
        type="file"
        id="file-selector"
        accept=".pdf"
        onChange={onFileSelected}
      />
      <iframe
        style={{ display: "block", width: "100vw", height: "90vh" }}
        title="PdfFrame"
        src={pdfFileData}
        frameborder="0"
        type="application/pdf"
      ></iframe>
    </>
  );
}

Giờ đây, bạn có thể lưu tệp PDF thu được bằng cách sử dụng nút tải xuống trên trình xem PDF.

Đi đâu từ đây

Trong bài viết này, tôi mới chỉ chạm vào phần nổi của tảng băng chìm. Nếu bạn muốn làm việc với các tệp PDF và muốn tạo ra thứ gì đó từ nó, thì pdf-lib là một thư viện rất mạnh cho mục đích này.

Bạn có thể hợp nhất hai tệp PDF thành một, bạn có thể xoay trang hoặc xóa một số trang khỏi tệp PDF. Đây chỉ là một số ví dụ – khả năng là vô tận.

Nếu bạn muốn triển khai ứng dụng Next.js của mình lên các trang Cloudflare, thì đây là bài viết bạn nên xem.

Làm một cái gì đó ra khỏi nó. Làm một số công cụ sáng tạo và cho tôi xem Twitter.

Phần kết luận

Nếu bạn đã đọc cho đến bây giờ, tôi rất biết ơn. Có cảm giác như tôi đang tạo nội dung mà ai đó từ nơi khác trên thế giới sẽ đọc. Hãy chia sẻ với bạn bè mã hóa của bạn.

Bạn có muốn thêm dàn bài vào tài liệu PDF của mình không? Tôi biết đây là một nhiệm vụ rất khó đạt được. Tôi đã phải trải qua rất nhiều khó khăn để thêm tính năng này vào tài liệu PDF bằng JavaScript. Bạn có hứng thú không? Đó là chuyện của tương lai.

Chúc bạn ngày mới tốt lành.





Zik.vn – Biên dịch & Biên soạn Lại

spot_img

Create a website from scratch

Just drag and drop elements in a page to get started with Newspaper Theme.

Buy Now ⟶

Bài viết liên quang

DMCA.com Protection Status