proyecto vue, use pdfjs en modo de instalación npm


前言:

npmAcerca del PDF.jspaquete tiene dos, pdf.jsy pdfjs-dist; se usa en este artículo pdfjs-dist; PDF.js proporciona una página de vista previa viewer.htmlpara lograr la vista previa en línea del pdf; pdf.js se puede descargar al proyecto como un recurso estático, simplemente cambie la dirección de el servidor donde se almacena el archivo pdf puede realizar la visualización en línea de pdf en el proyecto vue.

Use pdf.js en el modo de instalación npm: debe escribir sus propios estilos de acuerdo con sus necesidades para implementar funciones relacionadas.

Formas de recursos estáticos: descargue el pdf a un proyecto local a la manera de recursos estáticos, pdf.jssiempre viewer.htmlque se muestre el archivo pdf en el servidor de archivos, sin necesidad de configurar su propio estilo (conjunto completo de estilos y funciones relacionadas de pdf.js existente, no Cuando sea necesario, puede eliminarlo usted mismo cambiando el código fuente, etc.)

Uno, instale el complemento

yarn add pdfjs-dist

En segundo lugar, pruebe si la introducción es exitosa en el componente.

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

Resultado de la impresión:
Inserte la descripción de la imagen aquí

Tres, pisa la colección de boxes

1. WorkerSrc debe configurarse manualmente

El mensaje de error es el siguiente: Uncaught SyntaxError: Unexpected token '<' Cannot read property 'WorkerMessageHandler' of undefined
Inserte la descripción de la imagen aquí
注意:Aquí, la versión de pdf.js aplicada en el proyecto es 2.5.207

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

Solución: es necesario configurar 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: Después de actualizar la versión pdf.js, su getDocumentmétodo devuelve unpromise

Consulte el código original escrito en el ejemplo anterior:

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

TypeError: loadingTask.then is not a functionMensaje de error ::
Inserte la descripción de la imagen aquí
Solución: Nota promise:

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

En cuarto lugar, obtenga una vista previa del ejemplo completo del documento de archivo 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>

El efecto del código anterior es el siguiente (la parte en inglés es el contenido del archivo pdf):

Inserte la descripción de la imagen aquí

Cinco, página anterior, página siguiente, ejemplo

<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>

Inserte la descripción de la imagen aquí

referencia:

  1. pdfjs: ejemplos
  2. Uso de pdfjs 2020 en vue

Supongo que te gusta

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