Небольшая демонстрация онлайн-превью в формате PDF (текст можно скопировать)

Vue.js

Однажды девушка-испытатель мне сказала, почему этот pdf не открывается в ie? Потом я взглянул:

This browser does not support inline PDFs. Please download the PDF to view it: Download PDF

Раньше у меня не было большого контакта с онлайн-чтением PDF, этот проект также является старым проектом, а затем я пошел посмотреть, какие несовместимые, т.е. плагины для онлайн-чтения PDF, используют эти ребята, и обнаружил, что этоPDFObject,ОднакоPDFObject не поддерживает рендеринг pdf в браузерах без средства рендеринга pdf
Если так, то мыЗагрузите Adobe ReaderБар! Подождите... я должен напоминать каждому покупателю загрузить эту читалку? Психология клиента не будет mmp?

это здесьАвторы PDFObject предполагают, что вы можете использоватьpdf.jsПринудительный рендеринг PDF

You can also use PDF.js to force PDF rendering in-browser without a plugin, but that's outside the scope of PDFObject.

Узнайте что-то новое, начните с демонстрации

1. Установите PDF.js

Эта демонстрация используется непосредственноvue-cliСоздайте

  • Установить из исходников, изОфициальный сайтЗагрузите исходный код напрямую
  • CDN можно использовать следующими способами

Woohoo. Рейтинг JS Deli VR.com/package/year…

CDN Acceleration.com/libraries/Боюсь…
unpkg.com/pdfjs-dist/

  • Используйте готовую версию, загруженную из npm.
npm i pdfjs-dist

or

yarn add pdfjs-dist

2. Использование в вью

import PDFJS from 'pdfjs-dist';

PDFJS.GlobalWorkerOptions.workerSrc = 'pdfjs-dist/build/pdf.worker.js';

Чтобы повысить производительность парсинга и рендеринга PDF, был представлен pdf.js.Web Workers, вы можете ткнуть учителя Руан Ифэн, если вы не знаете обувь веб-работникаэта статья

PDFJ черезcanvasдля отображения содержимого PDF в браузере, поэтому нам нужно добавитьcanvas

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

Однако содержимое PDF, отображаемое таким образом, выбрать нельзя. Что мне делать?

использоватьgetTextContentПолучите содержимое в формате PDF, а затем передайтеTextLayerBuilderотображать контент вcanvasслой можно выбрать

первый звонокPDFJS.getDocumentспособ получитьPDFDocumentLoadingTask,

getDocument (источник) → { PDFDocumentLoadingTask }

тип src может бытьstring | TypedArray | DocumentInitParameters | PDFDataRangeTransport, здесь мы напрямую используемstringТип, строка URL-адреса pdf

Хотя метод возвращаетPDFDocumentLoadingTask, но все еще может использоваться какpromiseИспользуйте его так же, исходный код выглядит следующим образом, при вызовеpdf.thenвернетPromiseобъект.

  class PDFDocumentLoadingTask {
    /* 
    省略若干代码
    */
    /**
     * @return {Promise}
     */
    get promise() {
      return this._capability.promise;
    }

    then(onFulfilled, onRejected) {
      deprecated('PDFDocumentLoadingTask.then method, ' +
                 'use the `promise` getter instead.');
      return this.promise.then.apply(this.promise, arguments);
    }
  }

получатьPDFDocumentLoadingTaskПосле этого получить pdf текущей страницы по номеру страницы pdf

let pdf = await PDFJS.getDocument(url) // URL为pdf的链接
let page = await pdf.getPage(num) // num 为页码,如 1

Установите размер страницы (соотношение отображения) документа PDf

let scale = 1.5;
let viewport = page.getViewport(scale);

визуализировать pdf

let renderContext = {
    canvasContext: context, // 此为canvas的context
    viewport: viewport
};
        
await page.render(renderContext); // 这里await是为了后面渲染pdf文本

Затем получите содержимое PDF-файла и преобразуйте его в текст.

let textContent = await page.getTextContent()
/* ... */
// 创建新的TextLayerBuilder实例
var textLayer = new TextLayerBuilder({
    textLayerDiv: textLayerDiv, // 放置文本的dom
    pageIndex: page.pageIndex, // pdf页码
    viewport: viewport
});

textLayer.setTextContent(textContent);

textLayer.render();

Полный код выглядит следующим образом, следующим шагом является отображение резюме Дафа, вы можете обратиться кexample

Барбара...

import PDFJS from "pdfjs-dist";
import { TextLayerBuilder } from "pdfjs-dist/web/pdf_viewer";
import "pdfjs-dist/web/pdf_viewer.css";
PDFJS.GlobalWorkerOptions.workerSrc = "pdfjs-dist/build/pdf.worker.js";

var container;
export default {
  name: "HelloWorld",
  props: {
    msg: String
  },
  mounted() {
    this.$nextTick(() => {
        let url =
        "http://mozilla.github.io/pdf.js/web/compressed.tracemonkey-pldi-09.pdf";
        this.getPDF(url);
    });
  },
  methods: {
    async getPDF(url) {
        let pdf = await PDFJS.getDocument(url)
        container = container || document.querySelector('#container')
        for(let i = 0; i < pdf.numPages; i++) {
            try{
                await this.rendPDF(pdf, i)
            } catch(e) {
                // console.error(e)
            }
        }
    },
    async renderPDF(pdf, num) {
        let page = await pdf.getPage(num)
        // 设置展示比例
        let scale = 1.5;
        let viewport = page.getViewport(scale);

        let pageDiv = document.createElement('div');
        pageDiv.setAttribute('id', 'page-' + (page.pageIndex + 1));
        pageDiv.setAttribute('style', 'position: relative');
        container.appendChild(pageDiv);

        let canvas = document.createElement('canvas');
        pageDiv.appendChild(canvas);
        let context = canvas.getContext('2d');
        canvas.height = viewport.height;
        canvas.width = viewport.width;
        
        let renderContext = {
            canvasContext: context,
            viewport: viewport
        };
        
        await page.render(renderContext);
        let textContent = await page.getTextContent()
        // 创建文本图层div
        const textLayerDiv = document.createElement('div');
        textLayerDiv.setAttribute('class', 'textLayer');
        textLayerDiv.setAttribute('style', `width: ${viewport.width}px; margin: 0 auto;`)
        // 将文本图层div添加至每页pdf的div中
        pageDiv.appendChild(textLayerDiv);
        
        // 创建新的TextLayerBuilder实例
        var textLayer = new TextLayerBuilder({
            textLayerDiv: textLayerDiv,
            pageIndex: page.pageIndex,
            viewport: viewport
        });
        
        textLayer.setTextContent(textContent);
        
        textLayer.render();

    }
  }
};

3. Эффекты


Вы можете видеть, что текст содержимого был представлен как обычный текст.

С выделением текста тоже нет проблем.
Наконец прикреплендемонстрационный адрес
промах~