Récupérer un PDF zippé à partir d’une URL et le convertir en texte brut – Angular

Si vous voulez récupérer un fichier PDF côté client avec Angular, cela nécessite l’utilisation de bibliothèques JavaScript adaptées pour télécharger, extraire et lire les fichiers PDF. Voici un guide pour faire cela avec Angular :

Étapes générales :

  1. Télécharger le fichier ZIP depuis l’URL.
  2. Décompresser le fichier ZIP pour accéder au PDF.
  3. Lire et convertir le PDF en texte brut.

Bibliothèques nécessaires :

  • file-saver : pour gérer le téléchargement de fichiers.
  • jszip : pour décompresser les fichiers ZIP.
  • pdfjs-dist : pour lire les fichiers PDF.

Installez-les avec npm :

npm install file-saver jszip pdfjs-dist

Exemple de code Angular :

Voici un service et un composant pour réaliser cette tâche.


1. Service Angular :

Créez un service pour gérer le processus.

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import * as JSZip from 'jszip';
import * as pdfjsLib from 'pdfjs-dist';

@Injectable({
  providedIn: 'root',
})
export class FileService {
  constructor(private http: HttpClient) {}

  // Étape 1 : Télécharger le fichier ZIP
  downloadZip(url: string): Promise<Blob> {
    return this.http.get(url, { responseType: 'blob' }).toPromise();
  }

  // Étape 2 : Extraire le PDF du ZIP
  async extractPdfFromZip(zipBlob: Blob): Promise<Blob> {
    const zip = new JSZip();
    const zipContent = await zip.loadAsync(zipBlob);
    const pdfFileName = Object.keys(zipContent.files).find((fileName) =>
      fileName.endsWith('.pdf')
    );

    if (!pdfFileName) {
      throw new Error('Aucun fichier PDF trouvé dans le ZIP.');
    }

    const pdfFile = await zip.file(pdfFileName)?.async('blob');
    if (!pdfFile) {
      throw new Error('Impossible de lire le fichier PDF.');
    }

    return pdfFile;
  }

  // Étape 3 : Convertir le PDF en texte brut
  async pdfToText(pdfBlob: Blob): Promise<string> {
    const pdfArrayBuffer = await pdfBlob.arrayBuffer();
    const pdfDocument = await pdfjsLib.getDocument({ data: pdfArrayBuffer }).promise;
    let text = '';

    for (let i = 0; i < pdfDocument.numPages; i++) {
      const page = await pdfDocument.getPage(i + 1);
      const content = await page.getTextContent();
      text += content.items.map((item: any) => item.str).join(' ');
    }

    return text;
  }
}

2. Composant Angular :

Utilisez le service dans un composant pour traiter les fichiers.

import { Component } from '@angular/core';
import { FileService } from './file.service';

@Component({
  selector: 'app-file-handler',
  template: `
    <button (click)="processFile()">Télécharger et Traiter le Fichier</button>
    <pre>{{ extractedText }}</pre>
  `,
})
export class FileHandlerComponent {
  extractedText: string = '';

  constructor(private fileService: FileService) {}

  async processFile() {
    const zipUrl = 'URL_DU_FICHIER_ZIP'; // Remplacez par l'URL réelle

    try {
      // Télécharger le fichier ZIP
      const zipBlob = await this.fileService.downloadZip(zipUrl);
      // Extraire le PDF
      const pdfBlob = await this.fileService.extractPdfFromZip(zipBlob);
      // Convertir le PDF en texte brut
      this.extractedText = await this.fileService.pdfToText(pdfBlob);
      console.log('Texte extrait :', this.extractedText);
    } catch (error) {
      console.error('Erreur:', error);
    }
  }
}

3. Explications des étapes :

  1. Téléchargement du ZIP : Utilise HttpClient pour récupérer le fichier en tant que Blob.
  2. Décompression du ZIP : JSZip est utilisé pour analyser et extraire les fichiers dans l’archive.
  3. Lecture du PDF : pdfjs-dist extrait le texte page par page.

4. Configuration dans Angular :

Ajoutez HttpClientModule dans le fichier app.module.ts :

import { HttpClientModule } from '@angular/common/http';

@NgModule({
  declarations: [...],
  imports: [
    ...,
    HttpClientModule
  ],
  providers: [...],
  bootstrap: [AppComponent]
})
export class AppModule {}

Avec ce code, vous pouvez facilement télécharger un fichier ZIP contenant un PDF, extraire son contenu et convertir le PDF en texte brut dans une application Angular.


BONUS

Si vous ne souhaitez pas télécharger le fichier localement et préférez traiter le fichier directement en mémoire (sans l’enregistrer sur le disque), vous pouvez toujours utiliser Angular pour effectuer les étapes nécessaires. Voici comment procéder en gardant tout le processus en mémoire :

Étapes :

  1. Récupérer le fichier ZIP depuis l’URL en mémoire (Blob).
  2. Extraire le fichier PDF du ZIP en mémoire.
  3. Lire et convertir le PDF en texte brut à partir de la mémoire.

Exemple de Code Angular :

1. Service Angular :

Modifiez le service pour gérer le fichier en mémoire.

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import * as JSZip from 'jszip';
import * as pdfjsLib from 'pdfjs-dist';

@Injectable({
  providedIn: 'root',
})
export class FileService {
  constructor(private http: HttpClient) {}

  // Étape 1 : Récupérer le fichier ZIP directement en mémoire
  fetchZipFromUrl(url: string): Promise<Blob> {
    return this.http.get(url, { responseType: 'blob' }).toPromise();
  }

  // Étape 2 : Extraire le fichier PDF directement depuis le ZIP
  async extractPdfFromZip(zipBlob: Blob): Promise<Uint8Array> {
    const zip = new JSZip();
    const zipContent = await zip.loadAsync(zipBlob);
    const pdfFileName = Object.keys(zipContent.files).find((fileName) =>
      fileName.endsWith('.pdf')
    );

    if (!pdfFileName) {
      throw new Error('Aucun fichier PDF trouvé dans le ZIP.');
    }

    // Lire le fichier PDF en tant que tableau binaire (Uint8Array)
    return await zip.file(pdfFileName)?.async('uint8array')!;
  }

  // Étape 3 : Convertir le PDF en texte brut
  async pdfToText(pdfData: Uint8Array): Promise<string> {
    const pdfDocument = await pdfjsLib.getDocument({ data: pdfData }).promise;
    let extractedText = '';

    for (let i = 0; i < pdfDocument.numPages; i++) {
      const page = await pdfDocument.getPage(i + 1);
      const content = await page.getTextContent();
      extractedText += content.items.map((item: any) => item.str).join(' ');
    }

    return extractedText;
  }
}

2. Composant Angular :

Le composant utilise le service pour traiter le fichier directement en mémoire.

import { Component } from '@angular/core';
import { FileService } from './file.service';

@Component({
  selector: 'app-file-handler',
  template: `
    <button (click)="processFile()">Traiter le Fichier</button>
    <pre>{{ extractedText }}</pre>
  `,
})
export class FileHandlerComponent {
  extractedText: string = '';

  constructor(private fileService: FileService) {}

  async processFile() {
    const zipUrl = 'URL_DU_FICHIER_ZIP'; // Remplacez par l'URL de votre fichier ZIP

    try {
      // Récupérer le fichier ZIP
      const zipBlob = await this.fileService.fetchZipFromUrl(zipUrl);
      // Extraire le PDF
      const pdfData = await this.fileService.extractPdfFromZip(zipBlob);
      // Lire le texte du PDF
      this.extractedText = await this.fileService.pdfToText(pdfData);
      console.log('Texte extrait :', this.extractedText);
    } catch (error) {
      console.error('Erreur:', error);
    }
  }
}

Détails importants :

  1. Téléchargement en mémoire :
    • Le fichier ZIP est récupéré en mémoire en tant que Blob via HttpClient avec l’option { responseType: 'blob' }.
  2. Décompression du ZIP en mémoire :
    • JSZip traite le fichier ZIP sans l’enregistrer localement et extrait le PDF en tant que tableau binaire (Uint8Array).
  3. Conversion du PDF en texte :
    • pdfjs-dist utilise le contenu binaire pour lire directement le fichier PDF et extraire le texte page par page.

Avantages de ce processus :

  • Pas de téléchargement local : Tout le traitement se fait directement en mémoire.
  • Efficace pour les applications web modernes : Idéal pour des systèmes front-end où le traitement doit être rapide et non intrusif.