projeto vue, use pdfjs no modo de instalação npm


前言:

npmSobre o PDF.jspacote tem dois, pdf.jse pdfjs-dist; é usado neste artigo pdfjs-dist; PDF.js fornece uma página de visualização viewer.htmlpara obter a visualização online do pdf; pdf.js pode ser baixado para o projeto como um recurso estático, basta alterar o endereço de o servidor onde o arquivo pdf está armazenado pode realizar a exibição online do pdf no projeto vue.

Use pdf.js no modo de instalação npm: você precisa escrever seus próprios estilos de acordo com suas necessidades para implementar funções relacionadas.

Formas de recursos estáticos: Baixe o pdf para um projeto local para a maneira de recursos estáticos, pdf.jsfornecido viewer.htmlpara mostrar o arquivo pdf no servidor de arquivos, sem necessidade de configurar seu próprio estilo (pdf.js existente conjunto completo de estilos e funções relacionadas, não Quando necessário, você pode removê-lo por conta própria alterando o código-fonte, etc.)

Um, instale o plug-in

yarn add pdfjs-dist

Em segundo lugar, teste se a introdução foi bem-sucedida no componente

const PDFJS = require("pdfjs-dist");
console.log("成功:",PDFJS )

Resultado da impressão:
Insira a descrição da imagem aqui

Três, pise na coleta do fosso

1. WorkerSrc precisa ser configurado manualmente

A mensagem de erro é a seguinte: Uncaught SyntaxError: Unexpected token '<' Cannot read property 'WorkerMessageHandler' of undefined
Insira a descrição da imagem aqui
注意:Aqui, a versão do pdf.js aplicada no projeto é 2.5.207

 "vue": "^2.6.11",
"pdfjs-dist": "^2.5.207",

Solução: é necessário definir o workerSrc manualmente :

const PDFJS = require("pdfjs-dist");
PDFJS.GlobalWorkerOptions.workerSrc =
"https://cdnjs.cloudflare.com/ajax/libs/pdf.js/2.5.207/pdf.worker.js";

2. Nota: Depois que a versão pdf.js é atualizada, seu getDocumentmétodo retorna umpromise

Consulte o código original escrito no exemplo anterior:

  loadFile(url) {
    
    
      let loadingTask = PDFJS.getDocument(url);
      loadingTask.then(pdf => {
    
     // 老版本该处是正确写法
       ......
      });
    },

TypeError: loadingTask.then is not a functionMensagem de erro ::
Insira a descrição da imagem aqui
Solução: Nota promise:

loadFile(url) {
    
    
      let loadingTask = PDFJS.getDocument(url);
      loadingTask.promise.then(pdf => {
    
     // 注意该行的promise,版本升级后,getDocument方法返回promise
    	......
      });
    },

Quarto, visualize todo o exemplo de documento de arquivo PDF

<template>
  <div class="preview-pdf">
    <h1>PDF在线预览</h1>
    <div :style="`margin:0 auto;width:${pdfWidth};`">
      <canvas
        v-for="page in pdfPages"
        :key="page"
        :id="'pdfCanvas' + page"
      ></canvas>
    </div>
  </div>
</template>
<script>
const PDFJS = require("pdfjs-dist");
PDFJS.GlobalWorkerOptions.workerSrc = "https://cdnjs.cloudflare.com/ajax/libs/pdf.js/2.5.207/pdf.worker.js";
export default {
    
    
  data() {
    
    
    return {
    
    
      pdfPages: [], // 页数
      pdfWidth: "", // 宽度
      pdfSrc: "", // 地址
      pdfDoc: "", // 文档内容
      pdfScale: 1.0 // 放大倍数
    };
  },
  mounted() {
    
    
    this.getPdfUrl();
  },
  methods: {
    
    
    getPdfUrl() {
    
    
      // todo 请求后台,获取pdf的url,这里用的是线上的地址
      this.pdfSrc =
        "https://raw.githubusercontent.com/mozilla/pdf.js/ba2edeae/web/compressed.tracemonkey-pldi-09.pdf";
      this.loadFile(this.pdfSrc);
    },
    loadFile(url) {
    
    
      let loadingTask = PDFJS.getDocument(url);
      loadingTask.promise.then(pdf => {
    
    
        this.pdfDoc = pdf;
        this.pdfPages = pdf.numPages;
        this.$nextTick(() => {
    
     
          this.renderPage(1);
        });
      });
    },
    renderPage(num) {
    
    
      const that = this;
      this.pdfDoc.getPage(num).then(page => {
    
    
        let canvas = document.getElementById("pdfCanvas" + num);
        let ctx = canvas.getContext("2d");
        let dpr = window.devicePixelRatio || 1;
        let bsr =
          ctx.webkitBackingStorePixelRatio ||
          ctx.mozBackingStorePixelRatio ||
          ctx.msBackingStorePixelRatio ||
          ctx.oBackingStorePixelRatio ||
          ctx.backingStorePixelRatio ||
          1;
        let ratio = dpr / bsr;
        let viewport = page.getViewport({
    
     scale: this.pdfScale });
        canvas.width = viewport.width * ratio;
        canvas.height = viewport.height * ratio;

        canvas.style.width = viewport.width + "px";

        that.pdfWidth = viewport.width + "px";

        canvas.style.height = viewport.height + "px";

        ctx.setTransform(ratio, 0, 0, ratio, 0, 0);
        // 将 PDF 页面渲染到 canvas 上下文中
        let renderContext = {
    
    
          canvasContext: ctx,
          viewport: viewport
        };
        page.render(renderContext);
        if (this.pdfPages > num) {
    
    
          this.renderPage(num + 1);
        }
      });
    }
  }
};
</script>
<style lang="scss">
.preview-pdf {
    
    
  h1 {
    
    
    margin: 30px auto;
    text-align: center;
    font-family: "宋体";
    letter-spacing: 2px;
  }
}
</style>

O efeito do código acima é o seguinte (a parte em inglês é o conteúdo do arquivo pdf):

Insira a descrição da imagem aqui

Cinco, página anterior próxima página, exemplo

<template>
  <div class="preview-pdf">
    <h1>PDF在线预览</h1>
    <div style="text-align:center;">
      <button id="prev" @click="onPrePage">
        Previous
      </button>
      <button id="next" @click="onNextPage">Next</button>

      <span>
        Page:
        <span id="page_num">{
    
    {
    
     currentPage }}</span>
        /
        <span id="page_count">{
    
    {
    
     totalPages }}</span></span
      >
    </div>
    <div
      :style="`margin:0 auto;width:${pdfWidth};`"
      v-loading="isLoading"
      element-loading-text="加载中..."
    >
      <canvas id="pdfCanvas"></canvas>
    </div>
  </div>
</template>
<script>
const PDFJS = require("pdfjs-dist");
PDFJS.GlobalWorkerOptions.workerSrc =
  "https://cdnjs.cloudflare.com/ajax/libs/pdf.js/2.5.207/pdf.worker.js";
export default {
    
    
  data() {
    
    
    return {
    
    
      totalPages: [], // 总页数
      currentPage: 1, // 当前页
      pageRendering: false, // 是否正在渲染
      pageNumPending: null, // 待处理页码
      pdfWidth: "", // 宽度
      pdfSrc: "", // 地址
      pdfDoc: null, // 文档内容
      pdfScale: 1.0, // 放大倍数
      isLoading: false // 文档是否正在加载
    };
  },
  mounted() {
    
    
    this.getPdfUrl();
  },
  watch: {
    
    
    pageRendering(newVal, old) {
    
    
      this.isLoading = newVal;
    }
  },
  methods: {
    
    
    getPdfUrl() {
    
    
      // todo 请求后台,获取pdf的url,注意这里不能是本地的pdf文件
      this.pdfSrc =
        "https://raw.githubusercontent.com/mozilla/pdf.js/ba2edeae/web/compressed.tracemonkey-pldi-09.pdf";
      this.loadFile(this.pdfSrc);
    },
    loadFile(url) {
    
    
      //通过promise获取页面
      let loadingTask = PDFJS.getDocument(url);
      this.pageRendering = true;
      loadingTask.promise.then(pdf => {
    
    
        this.pdfDoc = pdf;
        this.totalPages = pdf.numPages;
        this.$nextTick(() => {
    
    
          this.renderPage(1); // 初始/首页渲染
        });
      });
    },
    renderPage(num) {
    
    
      this.currentPage = num; // 更新当前页码
      this.pdfDoc.getPage(num).then(page => {
    
    
        let canvas = document.getElementById("pdfCanvas");
        let ctx = canvas.getContext("2d");
        let dpr = window.devicePixelRatio || 1;
        let bsr =
          ctx.webkitBackingStorePixelRatio ||
          ctx.mozBackingStorePixelRatio ||
          ctx.msBackingStorePixelRatio ||
          ctx.oBackingStorePixelRatio ||
          ctx.backingStorePixelRatio ||
          1;
        let ratio = dpr / bsr;
        let viewport = page.getViewport({
    
     scale: this.pdfScale });
        canvas.width = viewport.width * ratio;
        canvas.height = viewport.height * ratio;

        canvas.style.width = viewport.width + "px";

        this.pdfWidth = viewport.width + "px";

        canvas.style.height = viewport.height + "px";

        ctx.setTransform(ratio, 0, 0, ratio, 0, 0);
        // 将 PDF 页面渲染到 canvas 上下文中
        let renderContext = {
    
    
          canvasContext: ctx,
          viewport: viewport
        };
        let renderTask = page.render(renderContext);
        renderTask.promise.then(() => {
    
    
          this.pageRendering = false;
          if (this.pageNumPending === null) return;
          this.renderPage(this.pageNumPending);
          this.pageNumPending = null;
        });
      });
    },
    onPrePage() {
    
    
      // 上一页
      if (this.currentPage <= 1) return;
      this.currentPage--;
      this.queueRender(this.currentPage);
    },
    onNextPage() {
    
    
      // 下一页
      if (this.currentPage >= this.totalPages) return;
      this.currentPage++;
      this.queueRender(this.currentPage);
    },
    queueRender(num) {
    
    
      //渲染等待;如果正在进行另一个页面渲染,请等待渲染完成。 否则,立即执行渲染
      !this.pageRendering ? this.renderPage(num) : (this.pageNumPending = num);
    }
  }
};
</script>
<style lang="scss">
.preview-pdf {
    
    
  h1 {
    
    
    margin: 30px auto;
    text-align: center;
    font-family: "宋体";
    letter-spacing: 2px;
  }
}
</style>

Insira a descrição da imagem aqui

referência:

  1. exemplos de pdfjs
  2. 2020 pdfjs uso em vue

Acho que você gosta

Origin blog.csdn.net/ddx2019/article/details/111195706
Recomendado
Clasificación