1. Installeer Vereiste Packages Voeg de benodigde libraries toe aan je project:
npm install pdfjs-dist @capacitor/filesystem @capacitor-community/http

2. Component Code (Web en Mobile)
Voeg de volgende code toe als component in je Ionic Vue-project:

<template>
  <ion-page>
    <ion-header>
      <ion-toolbar>
        <ion-title>PDF Viewer</ion-title>
      </ion-toolbar>
    </ion-header>
    <ion-content class="ion-padding">
      <ion-button @click="downloadAndRenderPdf">Download PDF</ion-button>
      <!-- PDF.js rendering container -->
      <div v-if="pdfUrl">
        <canvas ref="pdfCanvas" style="width: 100%;"></canvas>
      </div>
    </ion-content>
  </ion-page>
</template>

<script>
import { defineComponent, watch } from "vue";
import { IonPage, IonHeader, IonToolbar, IonTitle, IonContent, IonButton } from "@ionic/vue";
import { Filesystem, Directory } from "@capacitor/filesystem";
import { CapacitorHttp } from "@capacitor/core";
import * as pdfjsLib from 'pdfjs-dist/legacy/build/pdf';

// Set the workerSrc to the imported worker
pdfjsLib.GlobalWorkerOptions.workerSrc = new URL(
  "pdfjs-dist/build/pdf.worker.min.mjs",
  import.meta.url
).toString();

import { Capacitor } from '@capacitor/core';

// Add detailed platform and path logging
const platform = Capacitor.getPlatform();
console.log('Platform detection:', {
  platform,
  isAndroid: platform === 'android',
  isWeb: platform === 'web'
});

export default defineComponent({
  name: "TestpdfPage",
  components: {
    IonPage,
    IonHeader,
    IonToolbar,
    IonTitle,
    IonContent,
    IonButton,
  },
  data() {
    return {
      pdfUrl: null, // URL of the PDF to be rendered
    };
  },
  methods: {
    // Method to download and render the PDF
    async downloadAndRenderPdf() {
      try {
        console.log("Starting PDF download process...");

        const pdfUrl = "https://example.com/sample.pdf";
        const fileName = "temp.pdf";
        const dirPath = "downloaded";
        const savedFilePath = `${dirPath}/${fileName}`;

        console.log("Downloading PDF using CapacitorHttp from:", pdfUrl);

        // Clean up the existing directory
        try {
          await Filesystem.rmdir({
            path: dirPath,
            directory: Directory.Data,
            recursive: true,
          });
          console.log("Cleaned up existing directory");
        } catch (e) {
          console.log("No existing directory to clean up");
        }

        // Download PDF using native HTTP
        const response = await CapacitorHttp.get({
          url: pdfUrl,
          responseType: "arraybuffer",
        });

        console.log("Download response:", response);

        // Check if response.data is a string (Base64) or an ArrayBuffer
        let base64Data;
        if (typeof response.data === 'string') {
          // Data is already Base64-encoded
          base64Data = response.data;
          console.log("Received data is a Base64 string");
        } else {
          // Convert ArrayBuffer to Base64
          base64Data = this.arrayBufferToBase64(response.data);
          console.log("Converted ArrayBuffer to Base64");
        }

        console.log("Base64 data length:", base64Data.length);

        // Save to device storage
        try {
          await Filesystem.mkdir({
            path: dirPath,
            directory: Directory.Data,
            recursive: true,
          });
          console.log("Created directory for PDF");

          await Filesystem.writeFile({
            path: savedFilePath,
            data: base64Data,
            directory: Directory.Data,
          });

          console.log("File saved locally");

          // Check if the file exists and get its size
          const fileStat = await Filesystem.stat({
            path: savedFilePath,
            directory: Directory.Data,
          });

          console.log("File exists:", fileStat.uri);
          console.log("File size in bytes:", fileStat.size);

          if (fileStat.size === 0) {
            console.error("Downloaded file is empty.");
            return;
          }

          // Set the PDF URL to display it
          this.pdfUrl = "data:application/pdf;base64," + base64Data;
        } catch (fsError) {
          console.error("Filesystem Error:", fsError);
          throw fsError;
        }
      } catch (error) {
        console.error("Operation Failed:", error);
      }
    },
    // Method to render the PDF on a canvas
    async renderPdf() {
      console.log("Starting PDF rendering process...");

      const canvas = this.$refs.pdfCanvas;
      if (!canvas) {
        console.error("Canvas element not found");
        return;
      }
      console.log("Canvas element found");

      const ctx = canvas.getContext("2d");
      if (!ctx) {
        console.error("Failed to get 2D context");
        return;
      }
      console.log("2D context obtained");

      try {
        const pdf = await pdfjsLib.getDocument(this.pdfUrl).promise;
        console.log("PDF document fetched successfully");

        const page = await pdf.getPage(1);
        console.log("Page 1 of PDF document fetched successfully");

        const viewport = page.getViewport({ scale: 1.5 });
        console.log("Viewport created with scale 1.5");

        canvas.width = viewport.width;
        canvas.height = viewport.height;
        console.log("Canvas dimensions set to width:", viewport.width, "height:", viewport.height);

        const renderContext = {
          canvasContext: ctx,
          viewport: viewport,
        };

        console.log("Starting PDF page render");
        await page.render(renderContext).promise;
        console.log("PDF rendered successfully");
      } catch (error) {
        console.error("Error rendering PDF:", JSON.stringify(error, Object.getOwnPropertyNames(error)));
      }
    },
    // Helper method to convert ArrayBuffer to Base64
    arrayBufferToBase64(buffer) {
      let binary = "";
      const bytes = new Uint8Array(buffer);
      const len = bytes.byteLength;
      for (let i = 0; i < len; i++) {
        binary += String.fromCharCode(bytes[i]);
      }
      return btoa(binary);
    },
  },
  watch: {
    // Watcher to render the PDF when the URL changes
    pdfUrl(newUrl) {
      if (newUrl) {
        this.$nextTick(() => {
          this.renderPdf();
        });
      }
    }
  }
});
</script>

3. Toelichting

  • HTTP Plugin: Hiermee download je bestanden veilig en effectief op mobiele apparaten.
  • Filesystem Plugin: Hiermee sla je bestanden lokaal op in de Documents-directory, essentieel voor Android/iOS.
  • PDF.js: Verantwoordelijk voor het renderen van PDF's in een canvas-element.

4. Compatibiliteit

  • Android/iOS: Zorg ervoor dat je permissies instelt voor bestandstoegang in je AndroidManifest.xml en Info.plist.
  • Web: PDF.js werkt direct met een externe URL zonder dat lokale opslag nodig is.