- 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
enInfo.plist
. - Web: PDF.js werkt direct met een externe URL zonder dat lokale opslag nodig is.