Saltar al contenido

En esta entrada vamos a ver cómo podemos desarrollar un visor de PDF con Vuejs 2 para renderizar los archivos PDF  directamente en tu aplicación. Este tipo de funcionalidades están más solicitadas de lo que parece y siempre es útil no alejar a los usuarios de nuestras aplicaciones ya que es justamente donde nosotros queremos que estén.

Desarrollar un visor de PDF con Vuejs 2

Si te interesa aprender a desarrollar este tipo de funcionalidades y no quieres perder tiempo en tener que encontrar la forma te invito a que te suscribas a la plataforma y puedas acceder al contenido completo de esta entrada.

Instalar VuePdf

Lo primero que debemos hacer es instalar la dependencia vue-pdf en nuestro proyecto con el siguiente comando:

npm install --save vue-pdf 

Crear nuestro visor de PDF

Una vez instalada simplemente deberemos generar un componente como el siguiente, el cual hará todo lo que necesitamos:

<template>
  <v-layout row justify-center>
    <v-dialog
      v-model="showPdfViewer"
      fullscreen
      hide-overlay
      transition="dialog-bottom-transition"
    >
      <v-card>
        <v-toolbar dark color="primary">
          <v-toolbar-title>Visor de PDF con Vuejs 2</v-toolbar-title>
          <v-flex class="text-xs-right">
            <v-btn icon fab @click="$emit('closePdfViewer')" align-end>
              <v-icon>close</v-icon> {{ $t("actions.close") }}
            </v-btn>
          </v-flex>
        </v-toolbar>

        <v-container fluid grid-list-md text-xs-center pa-4 mt-1>
          <v-layout row wrap>
            <v-flex xs12 pl-2 pr-3 pb-0>
              <pdf
                :src="src"
                :page="currentPage"
                @num-pages="pageCount = $event"
                @page-loaded="currentPage = $event"
                :style="{
                  width: $vuetify.breakpoint.smAndDown ? '110%' : '45%'
                }"
              >
                <template slot="loading">
                  {{ $t("pdf.loading") }}
                </template>
              </pdf>
            </v-flex>
          </v-layout>
        </v-container>
      </v-card>
      <v-footer class="justify-center text-xs-center pl-0" inset app>
        <v-layout row wrap>
          <v-flex xs2>
            <v-btn
              class="primary"
              block
              :disabled="noPrevPage"
              @click="prevPage"
              >{{
                $vuetify.breakpoint.smAndDown ? "<<" : $t("pdf.prev")
              }}</v-btn
            >
          </v-flex>

          <v-flex xs8 mt-3>{{ currentPage }} / {{ pageCount }}</v-flex>

          <v-flex xs2>
            <v-btn
              class="primary"
              block
              :disabled="noNextPage"
              @click="nextPage"
              >{{
                $vuetify.breakpoint.smAndDown ? ">>" : $t("pdf.next")
              }}</v-btn
            >
          </v-flex>
        </v-layout>
      </v-footer>
    </v-dialog>
  </v-layout>
</template>

<script>
import pdf from "vue-pdf";
export default {
  name: "PdfViewer",
  props: ["pdfPath", "showPdfViewer"],
  components: {
    pdf
  },
  mounted() {
    this.src = pdf.createLoadingTask(this.$props.pdfPath);
  },
  data() {
    return this.initialData();
  },
  computed: {
    noPrevPage() {
      return this.currentPage <= 1;
    },
    noNextPage() {
      return this.currentPage === this.pageCount;
    }
  },
  methods: {
    initialData() {
      return {
        currentPage: 1,
        pageCount: 0,
        src: null,
        zoom: 100
      };
    },
    prevPage() {
      this.currentPage--;
    },
    nextPage() {
      this.currentPage++;
    }
  },
  beforeDestroy() {
    Object.assign(this.$data, this.initialData());
  }
};
</script>

En mi caso yo estoy haciendo uso de Vuetify, pero tú puedes adaptar el visor a tus necesidades fácilmente.

Para utilizar nuestro visor de PDF simplemente debemos importarlo en el componente en el que deseemos hacer uso de él y definirlo de la siguiente forma:

<pdf-viewer
  @closePdfViewer="closePdfViewer"
  :show-pdf-viewer="showPdfViewer"
  :pdf-path="selectedPdf"
  v-if="selectedPdf"
/>

La clave es la prop pdf-path, la cual debe ser la ruta de tu archivo PDF, puede ser relativa a tu sistema o una url completa haciendo uso del protocolo http/https, creo que el protocolo file no funciona en este caso pero no estoy seguro.

Rutas de aprendizaje