Versiones comparadas

Clave

  • Se ha añadido esta línea.
  • Se ha eliminado esta línea.
  • El formato se ha cambiado.

...

Bloque de código
languagejs
return apiRequest({ url, responseType: "arraybuffer" });

El otro caso posible es que dicho array de bytes sea parte de un objeto, sólo un campo entre otros. Para transformarlo al formato de arraybuffer que queremos es más complicado. Para ello, podemos utilizar unas funciones auxiliares que hay definidas en este archivo: pdfUtil.js. Además, también se incluyen los métodos para devolver un objeto con el formato del visor de pdfs, y para descargarlo.

Este archivo lo podemos colocar en nuestro proyecto en src/util/pdfUtil.js. Contiene el siguiente código.Una vez recibido, para descargarlo podemos utilizar el código de la siguiente función, pasándole el pdf y el nombre del archivo a descargar:

Bloque de código
languagejs
export default {
  // Descargar un pdf (arraybuffer)
  descargarPdf(pdfArrayBuf, nombre) {
    const blob = new Blob([pdfArrayBuf], {
      type: 'application/pdf',
    });
    // IE doesn't allow using a blob object directly as link href
    // instead it is necessary to use msSaveOrOpenBlob
    if (window.navigator && window.navigator.msSaveOrOpenBlob) {
      window.navigator.msSaveOrOpenBlob(blob);
      return;
    }
    // For other browsers:
    // Create a link pointing to the ObjectURL containing the blob.
    const data = window.URL.createObjectURL(blob);
    const link = document.createElement('a');
    link.href = data;
    link.download = nombre;
    link.click();
    setTimeout(() => {
      // For Firefox it is necessary to delay revoking the ObjectURL
      window.URL.revokeObjectURL(data);
    }, 100);
  },

  // Pasar un arraybuffer a un objeto con el fomato para el visor vue-pdf
  pdfVisor(pdfArrayBuf) {
    return {
      data: pdfArrayBuf,
    };
  },

  // Pasar de base 64 a array de bytes - Si viene como string en base 64,
  // por ejemplo dentro de un objeto,tendremos que transformarlo
  base64DecToArr(sBase64, nBlocksSize) {
    const sB64Enc = sBase64.replace(/[^A-Za-z0-9+/]/g, '');
    const nInLen = sB64Enc.length;
    const nOutLen = nBlocksSize
    // eslint-disable-next-line no-bitwise
      ? Math.ceil(((nInLen * 3 + 1) >> 2) / nBlocksSize) * nBlocksSize
      // eslint-disable-next-line no-bitwise
      : (nInLen * 3 + 1) >> 2;
    const taBytes = new Uint8Array(nOutLen);

    for (let nMod3, nMod4, nUint24 = 0, nOutIdx = 0, nInIdx = 0; nInIdx < nInLen; nInIdx += 1) {
      // eslint-disable-next-line no-bitwise
      nMod4 = nInIdx & 3;
      // eslint-disable-next-line no-bitwise
      nUint24 |= this.b64ToUint6(sB64Enc.charCodeAt(nInIdx)) << (18 - 6 * nMod4);
      if (nMod4 === 3 || nInLen - nInIdx === 1) {
        for (nMod3 = 0; nMod3 < 3 && nOutIdx < nOutLen; nMod3 += 1, nOutIdx += 1) {
          // eslint-disable-next-line no-bitwise
          taBytes[nOutIdx] = (nUint24 >>> ((16 >>> nMod3) & 24)) & 255;
        }
        nUint24 = 0;
      }
    }

    return taBytes;
  },

  // Función auxiliar para la anterior
  base64ToUint6(nChr) {
    if (nChr > 64 && nChr < 91) {
      return nChr - 65;
    }
    if (nChr > 96 && nChr < 123) {
      return nChr - 71;
    }
    if (nChr > 47 && nChr < 58) {
      return nChr + 4;
    }
    if (nChr === 43) {
      return 62;
    }
    if (nChr === 47) {
      return 63;
    }
    return 0;
  },
};

Para utilizarlo en nuestros componentes, sólo tendríamos que importarlo y ya podríamos usarlo con pdfUtil.metodo(), así:

Bloque de código
languagejs
<script>
import pdfUtil from "@/util/pdfUtil.js";

export default {
  ...
  computed: {
    // Para el visor de pdf
    pdfVisor: function() {
      if(this.objConPdf) {
        return pdfUtil.pdfVisor(this.objConPdf.pdf)
      }
      return null
    }
  },
  methods: {
    getObjConPdf() {
      this.servicioRest.getPdf().then((response) => {
        if (response.status == 200) {
          this.objConPdf = response.data;
          this.objConPdf.pdf = pdfUtil.base64DecToArr(this.objConPdf.pdf).buffer;
        }
      });
    },
	// Mapeamos el método del pdfUtil a uno del componente, pues desde el <template> no se pueden acceder a los métodos importados
    descargarPdf: pdfUtil.descargarPdf,
  },
};
</script>

Visor de PDF

Para Vue tenemos disponible vue-pdf, que podemos descargar con:

Bloque de código
npm i vue-pdf

Y Este componente requiere un objeto con un campo data que contenga el pdf,  y lo utilizaríamos de esta forma:

Bloque de código
languagexml
<div class="visorPdf" style="width: 60%; margin-left:auto; margin-right:auto">
  <pdf v-if="objConPdf" :src="pdfVisorobjConPdf" style="border: solid 1px grey" />
</div>

...