Versiones comparadas

Clave

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


Advertencia
titleEN REVISIÓN

Ahora mismo este código da problemas, lo estamos revisando, actualizaremos la guía en cuanto lo tengamos solucionado.

Tabla de contenidos

...

Recibir PDF y darle el formato necesario

...

Bloque de código
languagejs
return axios.getapiRequest({ 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
// Descargar un pdf (arraybuffer)
Bloque de código
languagejs
export default {
  b64ToUint6(nChr) {
    return nChr > 64 && nChr < 91 ? nChr - 65 : nChr > 96 && nChr < 123 ? nChr - 71 : nChr > 47 && nChr < 58 ? nChr + 4 : nChr === 43 ? 62 : nChr === 47 ? 63 : 0;
  },
  base64DecToArr(sBase64, nBlocksSize) {
    var sB64Enc = sBase64.replace(/[^A-Za-z0-9\+\/]/g, ""),
      nInLen = sB64Enc.length,
      nOutLen = nBlocksSize ? Math.ceil(((nInLen * 3 + 1) >> 2) / nBlocksSize) * nBlocksSize : (nInLen * 3 + 1) >> 2,
      taBytes = new Uint8Array(nOutLen);

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

    return taBytes;
  },
  descargarPdf(pdfArrayBuf, nombre) {
    varconst 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);
    varconst link = document.createElement("'a"');
    link.href = data;
    link.download = nombre;
    link.click();
    setTimeout(function() => {
      // For Firefox it is necessary to delay revoking the ObjectURL
      window.URL.revokeObjectURL(data);
    }, 100);
  },
  pdfVisor(pdfArrayBuf},

Si lo que queremos es abrirlo en otra pestaña del navegador, lo podemos hacer con esta otra función:

Bloque de código
languagejs
abrirPdf() {
      const blob =  returnnew Blob([this.matriculaPdf], { datatype: pdfArrayBuf'application/pdf' });
  }
};

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: {
    // IE doesn't allow using a blob object directly as link href
      // instead it Parais elnecessary visorto deuse pdfmsSaveOrOpenBlob
     pdfVisor: if function((window.navigator && window.navigator.msSaveOrOpenBlob) {
      if(this.objConPdf) {  window.navigator.msSaveOrOpenBlob(blob);
        return pdfUtil.pdfVisor(this.objConPdf.pdf);
      }
      // return null
For other browsers:
      }
// Create },
a link methods:pointing {
to the ObjectURL containing getObjConPdf() {
the blob.
      const data this= window.servicioRestURL.getPdfcreateObjectURL().then((response) => {
blob);
      // window.open(data, '_blank');
  if (response.status == 200) {
const link = document.createElement('a');
       thislink.objConPdfhref = response.data;
      link.target = '_blank';
   this.objConPdf.pdf  = pdfUtillink.base64DecToArrclick(this.objConPdf.pdf).buffer;
      setTimeout(() => }{
      });
    },
	// MapeamosFor Firefox elit métodois delnecessary pdfUtilto adelay unorevoking delthe componente,ObjectURL
 pues desde el <template> no se pueden acceder a los métodos importados
    descargarPdf: pdfUtil.descargarPdf,
 window.URL.revokeObjectURL(data);
      }, 100);
    },
};
</script>


Visor de PDF

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

Bloque de código
npm i vue-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="pdfVisor" style="border: solid 1px grey" />
    </div>

Hay algunos componentes Vue de visor de pdf disponibles, pero estos son bastante limitados, pues muestran el pdf "a pelo", no proporcionan ningún tipo de interfaz para navegar o ejecutar acciones como guardar el pdf. Por lo tanto, la mejor opción que tenemos es mostrar el pdf en un iframe, de modo que se utilice el visor nativo del navegador:

Bloque de código
<iframe :src="pdf" />

En la propiedad src podemos pasarle el pdf en base64, precedido por "data:application/pdf;base64,". Si recibimos el pdf a mostrar como array de bytes, podemos transformarlo así:

Bloque de código
this.pdf = `data:application/pdf;base64, ${btoa(String.fromCharCode.apply(null, new Uint8Array(arraybuffer)),)}`;

Siendo la variable arraybuffer el array de bytes del pdf que hemos recibidoEn el parámetro src le tenemos que indicar un objeto con una estructura, que podemos obtener con pdfUtil.pdfVisor(pdfArrayBuffer).