IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Delphi Discussion :

PDF : recherche du contenu par mot clé


Sujet :

Delphi

  1. #1
    Membre confirmé
    Homme Profil pro
    Enseignant
    Inscrit en
    Août 2008
    Messages
    666
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Algérie

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Août 2008
    Messages : 666
    Points : 643
    Points
    643
    Par défaut PDF : recherche du contenu par mot clé
    Bonjour,

    Dans le cadre d'un projet, je recherche des composants vcl pour faire une recherche par contenu (par mot ou expression) dans les fichiers PDF , du genre 'DocFetcher''. Ce genre de composants existent-ils?
    Je suis preneur à toutes suggestions.

    Merci.

  2. #2
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 043
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 67
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15 043
    Points : 40 957
    Points
    40 957
    Billets dans le blog
    62
    Par défaut
    Bonjour Nabil,

    deux suggestions : voir ce que Paul Toth a fait avec la bibliothèque pdfium https://github.com/tothpaul/PDFiumReader, je ne sais pas si la recherche de texte en fait partie.
    Sinon en investissant un peu de € la bibliothèque winsoft.pdffium, un wrapper de la bibliothèque pdfium
    j'ai la Version 4.8 FMX qui me permet d'afficher mes PDF.
    J'y ai vu des fonctions comme FindFirst(<texte>) , FindNext (que je n'ai pas encore testées) qui me semblent correspondre à ton besoin

    [Edit] Je confirme, après avoir fait un petit programme test, ces deux fonctions semblent être ce que tu veux

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
     
    procedure TForm29.btnOccurencesClick(Sender: TObject);
    // Recherche du mot "Firedac" dans toutes les pages du pdf  
    var i,p : integer;
    begin
      i:=0;
      for p := 1 to fpdf1.PageCount do
      begin
       Fpdf1.PageNumber:=p;
       if Fpdf1.FindFirst('Firedac')>0 then    // insensible à la casse 
       begin
         inc(i);
         while fpdf1.FindNext>0 do inc(i);
       end;
      end;
      Showmessage(i.ToString+' Occurence(s)');
    end;
    dans le fichier joint il me trouve 29 occurrences (nb. une de plus que le visionneur d'internet explorer qui en a oublié une dans un titre mais en adéquation avec Adobe Acrobat Reader)
    Images attachées Images attachées
    MVP Embarcadero
    Delphi installés : D3,D7,D2010,XE4,XE7,D10 (Rio, Sidney), D11 (Alexandria), D12 (Athènes)
    SGBD : Firebird 2.5, 3, SQLite
    générateurs États : FastReport, Rave, QuickReport
    OS : Window Vista, Windows 10, Windows 11, Ubuntu, Androïd

  3. #3
    Membre confirmé
    Homme Profil pro
    Enseignant
    Inscrit en
    Août 2008
    Messages
    666
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Algérie

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Août 2008
    Messages : 666
    Points : 643
    Points
    643
    Par défaut
    Bonjour Serge,
    Merci pour ton aide.
    J'utilise Quick PDF Library.

    Peut-être bien je n'ai pas bien expliqué mon soucis:
    Dans mon application, je veux rechercher un mot dans plusieurs fichiers PDF en même temps sans les ouvrir(c'est cela qui est important). Je désigne le répertoire dans lequel on va faire la recherche de ce mot et l'application va le rechercher et afficher le(s) résultat(s) de recherche.
    Exemple : dans le répertoire de recherche, j'ai 100000 fichiers PDF. Je veux rechercher le mot ''facture'' et afficher le résultat : ''facture'' a été retrouvé dans :
    Fichier ''a'', fichier ''b'', ...

    Y a -t-il un moyen de le faire svp?

    Merci et bonne journée.

  4. #4
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 043
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 67
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15 043
    Points : 40 957
    Points
    40 957
    Billets dans le blog
    62
    Par défaut
    re,

    sans ouvrir les fichiers cela me parait impossible, il faut bien au moins lire le contenu. Une recherche dans les fichiers pdf surtout s'ils sont compressés (je parle du contenu)

    D'ailleurs si le composant ouvre les fichiers, il ne les visualise pas (c'est un autre composant de la suite qui s'occupe de l'affichage)

    Y a -t-il un moyen de le faire svp?
    AMHA Oui
    MVP Embarcadero
    Delphi installés : D3,D7,D2010,XE4,XE7,D10 (Rio, Sidney), D11 (Alexandria), D12 (Athènes)
    SGBD : Firebird 2.5, 3, SQLite
    générateurs États : FastReport, Rave, QuickReport
    OS : Window Vista, Windows 10, Windows 11, Ubuntu, Androïd

  5. #5
    Membre confirmé
    Homme Profil pro
    Enseignant
    Inscrit en
    Août 2008
    Messages
    666
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Algérie

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Août 2008
    Messages : 666
    Points : 643
    Points
    643
    Par défaut
    Re,

    Oui Serge, je suis de ton avis : il faut lire les fichiers et faire de la recherche par la suite c'est logique. Ce qui me tracasse c'est j'ai un nombre très important de fichiers sur lesquels on va faire des recherches, cela peut facilement dépasser 200000 fichiers. Si on les ouvre un par un, ça va consommer beaucoup de ressources non ?

  6. #6
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 043
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 67
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15 043
    Points : 40 957
    Points
    40 957
    Billets dans le blog
    62
    Par défaut
    Re,
    Ce qui me tracasse c'est j'ai un nombre très important de fichiers sur lesquels on va faire des recherches, cela peut facilement dépasser 200000 fichiers.
    rien n'empêche de coller ça dans des Threads, parce que je pense que par "ressources" tu voulais plutôt écrire que ça allait bloquer l'exécution


    Pour en revenir à ta question voilà avec FMX une recherche dans un répertoire (sans thread parce qu'écrit avant ta dernière réponse, sans recherche dans des sous-répertoires)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
     
    procedure TForm29.btnOccurencesClick(Sender: TObject);
    var i,p : integer;
        Files : TArray<String>;
    begin
    Files:=TDirectory.GetFiles(repertoire.text,'*.pdf');
    for i:= Low(Files) to High(Files)  do
     begin
      Fpdf1.FileName:=Files[i];
      Fpdf1.Active:=True;
      for p := 1 to fpdf1.PageCount do
      begin
       Fpdf1.PageNumber:=p;
       if Fpdf1.FindFirst('facture')>0 then
        begin
         Memo1.Lines.Add(Files[i]);
         Break;
        end;
       end;
      Fpdf1.Active:=False;
    end;
     
    end;
    MVP Embarcadero
    Delphi installés : D3,D7,D2010,XE4,XE7,D10 (Rio, Sidney), D11 (Alexandria), D12 (Athènes)
    SGBD : Firebird 2.5, 3, SQLite
    générateurs États : FastReport, Rave, QuickReport
    OS : Window Vista, Windows 10, Windows 11, Ubuntu, Androïd

  7. #7
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 043
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 67
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15 043
    Points : 40 957
    Points
    40 957
    Billets dans le blog
    62
    Par défaut
    Pour "finir" voici un "jus" qui ne bloquerait pas le poste, j'utilise au max les possibilités de Rio

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    unit Unit29;
     
    interface
     
    uses
      System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
      System.Threading,  System.IOUtils,
      FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, FMX.Edit,
      FMX.StdCtrls, FMX.Controls.Presentation,
      FMX.ScrollBox, FMX.Memo, Winsoft.FireMonkey.PDFium;
     
    type
      TForm29 = class(TForm)
        btnOccurences: TButton;
        Texte: TEdit;
        Label1: TLabel;
        FichierPdf: TEdit;
        EllipsesEditButton1: TEllipsesEditButton;
        OpenDialog1: TOpenDialog;
        Memo1: TMemo;
        AniIndicator1: TAniIndicator;
        procedure EllipsesEditButton1Click(Sender: TObject);
        procedure btnOccurencesClick(Sender: TObject);
      private
        { Déclarations privées }
        function isTexteinPDF(Texte : String; PdfFileName : TFileName): Boolean;
      public
        { Déclarations publiques }
      end;
     
     
    var
      Form29: TForm29;
     
    implementation
     
    {$R *.fmx}
     
     
    procedure TForm29.btnOccurencesClick(Sender: TObject);
    var dir, Cherche : String;
    begin
     Dir:=FichierPdf.Text;
     Cherche:= Texte.text;
     // Début d'une animation
     Aniindicator1.Visible:=True;
     AniIndicator1.Enabled:=True;
     
     TTask.Run(
       procedure
        var
         PdfFileName : TFileName;
         Files : TArray<String>;
       begin
        Files:=TDirectory.GetFiles(dir,'*.pdf');
        for PdfFileName in Files do
         begin
           // fait défiler tous les pdf
           TThread.Synchronize(nil,
             procedure
             begin
               Memo1.Lines.Add(PdfFileName);
               Memo1.Repaint;
             end
            );
     
         if isTexteinPDF(Cherche,PdfFileName) then
           // occurrence trouvée
           TThread.Synchronize(nil,
             procedure
             begin
               Memo1.Lines.Add(Cherche+' trouvé dans '+PdfFileName);
               Memo1.Repaint;
             end
            );
         end;
         // arrêt d'une animation
            TThread.Synchronize(nil,
             procedure
             begin
               AniIndicator1.Enabled:=False;
               AniIndicator1.Visible:=False;
             end
            );
       end);
    end;
     
     
    procedure TForm29.EllipsesEditButton1Click(Sender: TObject);
    begin
    if Opendialog1.Execute then
     begin
       FichierPdf.Text:=ExtractFileDir(OpenDialog1.FileName);
      end;
    end;
     
    function TForm29.isTexteinPDF(Texte: String; PdfFileName: TFileName): Boolean;
       var aFpdf : TFPdf;
          p : integer;
        begin
         result:=False;
         AFpdf := TFPDF.Create(nil);
         try
           AFPdf.FileName:=PdfFileName;
           try
             AFPdf.Active:=True;
           except
             Exit(False);  // au cas où le format serait invalide (taille pdf = 0 Ko par exemple)
           end;
          for p := 1 to Afpdf.PageCount do
          begin
            AFpdf.PageNumber:=p;
            if AFpdf.FindFirst(Texte)>0 then
             begin
              result:=true;
              Break;
             end;
           end;
          AFpdf.Active:=False;
         finally
           AFpdf.Free;
         end;
    end;
     
    end.
    NB. Là c'est le piège inverse, le programme principal n'est pas bloqué il faudrait songer à empêcher l'utilisateur de fermer le programme avant que la recherche soit terminée


    [Edit] NOTE : pour une recherche dans les sous-répertoires il suffit de rajouter l'option de recherche ligne 55 Files:=TDirectory.GetFiles(dir,'*.pdf',System.IOUtils.TSearchOption.soAllDirectories);
    MVP Embarcadero
    Delphi installés : D3,D7,D2010,XE4,XE7,D10 (Rio, Sidney), D11 (Alexandria), D12 (Athènes)
    SGBD : Firebird 2.5, 3, SQLite
    générateurs États : FastReport, Rave, QuickReport
    OS : Window Vista, Windows 10, Windows 11, Ubuntu, Androïd

  8. #8
    Expert confirmé
    Avatar de anapurna
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2002
    Messages
    3 420
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Mai 2002
    Messages : 3 420
    Points : 5 819
    Points
    5 819
    Par défaut
    salut

    sinon avec AcrobatReader

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
         c := '/A '+Format('"search=%s" ',[MotsCherche])+'"' + Nomfichier + '"';
         ShellExecute( hinstance, 'open', PChar('AcroRd32.exe'),Pchar(c), Nil,SW_SHOWNORMAL);
    Nous souhaitons la vérité et nous trouvons qu'incertitude. [...]
    Nous sommes incapables de ne pas souhaiter la vérité et le bonheur, et sommes incapables ni de certitude ni de bonheur.
    Blaise Pascal
    PS : n'oubliez pas le tag

  9. #9
    Membre confirmé
    Homme Profil pro
    Enseignant
    Inscrit en
    Août 2008
    Messages
    666
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Algérie

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Août 2008
    Messages : 666
    Points : 643
    Points
    643
    Par défaut
    Citation Envoyé par SergioMaster Voir le message
    rien n'empêche de coller ça dans des Threads, parce que je pense que par "ressources" tu voulais plutôt écrire que ça allait bloquer l'exécution
    Je veux dire par ''ressources'' consommer de la mémoire + grosse occupation du cpu.

    Merci beaucoup pour cette jolie démonstration Serge. Je testerai cela le soir et je te tiendrai au courant.

    @ Anapurma: je vous remercie pour votre intervention. Pour ce projet, on ne veut pas utiliser Acrobat Reader, mais je trouve que c'est une solution très intéressante.

    Bonne journée

  10. #10
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 043
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 67
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15 043
    Points : 40 957
    Points
    40 957
    Billets dans le blog
    62
    Par défaut
    Pendant que j'y suis, je pense que tu n'auras pas besoin de la version payante, la version de démo devrait suffire car le bandeau ne s'affiche qu'avec le TPdfView associé
    MVP Embarcadero
    Delphi installés : D3,D7,D2010,XE4,XE7,D10 (Rio, Sidney), D11 (Alexandria), D12 (Athènes)
    SGBD : Firebird 2.5, 3, SQLite
    générateurs États : FastReport, Rave, QuickReport
    OS : Window Vista, Windows 10, Windows 11, Ubuntu, Androïd

  11. #11
    Membre confirmé
    Homme Profil pro
    Enseignant
    Inscrit en
    Août 2008
    Messages
    666
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Algérie

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Août 2008
    Messages : 666
    Points : 643
    Points
    643
    Par défaut
    Bonsoir,

    En testant ton exemple Serge, je me suis aperçu que le TTask (System.Threading) est apparu sous XE7. Malheureusement, j'ai mon vieux XE5. Donc pas moyen de le faire en multi-thread à moins d'utiliser une bibliothèque qui gère ce genre technique.

    Merci.

  12. #12
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 043
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 67
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15 043
    Points : 40 957
    Points
    40 957
    Billets dans le blog
    62
    Par défaut
    Bonjour,

    Je ne savais pas que TTask n'était apparu qu'avec XE7, mais je me doutais un peu du problème c'est d'ailleurs pour cela que j'avais commencé à mettre la fonction isTexteinPDF à part

    il va donc falloir passer par TThread ,technique que je maitrise moins (TTask est tellement plus "élégant")
    Alors avant de me lancer dans cette aventure, je vais revisionner cette super vidéo de Olaf Monien lors BootCamps 2018 et que l'on peut retrouvée https://www.embarcaderoacademy.com (semaine 7)
    MVP Embarcadero
    Delphi installés : D3,D7,D2010,XE4,XE7,D10 (Rio, Sidney), D11 (Alexandria), D12 (Athènes)
    SGBD : Firebird 2.5, 3, SQLite
    générateurs États : FastReport, Rave, QuickReport
    OS : Window Vista, Windows 10, Windows 11, Ubuntu, Androïd

  13. #13
    Rédacteur/Modérateur
    Avatar de Andnotor
    Inscrit en
    Septembre 2008
    Messages
    5 694
    Détails du profil
    Informations personnelles :
    Localisation : Autre

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 694
    Points : 13 130
    Points
    13 130
    Par défaut
    Citation Envoyé par SergioMaster Voir le message
    TTask est tellement plus "élégant"
    Disons que c'est surtout plus court à écrire
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     TThread.CreateAnonymousThread(procedure
                                   begin
                                     ...
                                   end).Start;
    Le thread est créé dans l'état suspendu, ne pas oublier Start !

  14. #14
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 043
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 67
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15 043
    Points : 40 957
    Points
    40 957
    Billets dans le blog
    62
    Par défaut
    Re, après visionnage pour être sûr de moi voilà ce que ça donne :
    j'ai gardé l'ancienne unité déjà proposée (avec quelques modifications) et rajouté une unité spécifique pour le thread
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    unit Unit29;
    
    interface
    
    uses
      System.SysUtils, System.Types, System.UITypes, System.Classes,
      System.Variants,
      System.Threading, System.IOUtils,
      FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, FMX.Edit,
      FMX.StdCtrls, FMX.Controls.Presentation,
      FMX.ScrollBox, FMX.Memo;
    
    type
      TForm29 = class(TForm)
        btnOccurences: TButton;
        Texte: TEdit;
        Label1: TLabel;
        FichierPdf: TEdit;
        EllipsesEditButton1: TEllipsesEditButton;
        OpenDialog1: TOpenDialog;
        Memo1: TMemo;
        AniIndicator1: TAniIndicator;
        btnThread: TButton;
        procedure EllipsesEditButton1Click(Sender: TObject);
        procedure btnOccurencesClick(Sender: TObject);
        procedure btnThreadClick(Sender: TObject);
      private
        { Déclarations privées }
      public
        { Déclarations publiques }
        procedure UpdateMemo(aLine: String);
        procedure FinThread;
      end;
    
    var
      Form29: TForm29;
    
    implementation
    
    {$R *.fmx}
    
    uses Unit30;
    
    procedure TForm29.btnOccurencesClick(Sender: TObject);
    var
      dir, Cherche: String;
    begin
      dir := FichierPdf.Text;
      Cherche := Texte.Text;
      // Début d'une animation
      AniIndicator1.Visible := True;
      AniIndicator1.Enabled := True;
    
      TTask.Run(
        procedure
        var
          PdfFileName: TFileName;
          Files: TArray<String>;
        begin
          Files := TDirectory.GetFiles(dir, '*.pdf',
            System.IOUtils.TSearchOption.soAllDirectories);
          for PdfFileName in Files do
          begin
            // fait défiler tous les pdf
            TThread.Synchronize(nil,
              procedure
              begin
               UpdateMemo(PdfFileName);
              end);
    
            if isTexteinPDF(Cherche, PdfFileName) then
              // occurrence trouvée
              TThread.Synchronize(nil,
                procedure
                begin
                  UpdateMemo(Cherche + ' trouvé dans ' + PdfFileName);
                end);
          end;
          // arrêt d'une animation
          TThread.Synchronize(nil,
            procedure
            begin
              FinThread;
            end);
        end);
    end;
    
    // Utilisation via un Thread "métier"
    procedure TForm29.btnThreadClick(Sender: TObject);
    var
      SThread: TSearchInPDFFiles;
    begin
      AniIndicator1.Visible:=True;
      AniIndicator1.Enabled:=True;
      SThread := TSearchInPDFFiles.Create;
      SThread.dir := FichierPdf.Text;
      SThread.Texte := Texte.Text;
      SThread.UpdateResult := procedure(AFile: String)
        begin
          UpdateMemo(AFile);
        end;
      SThread.EndOfThread := procedure
        begin
          FinThread;
        end;
      SThread.Start;
    end;
    
    procedure TForm29.EllipsesEditButton1Click(Sender: TObject);
    begin
      if OpenDialog1.Execute then
      begin
        FichierPdf.Text := ExtractFileDir(OpenDialog1.FileName);
      end;
    end;
    
    // pour pouvoir les utiliser dans le thread
    procedure TForm29.FinThread;
    begin
      AniIndicator1.Enabled := False;
      AniIndicator1.Visible := False;
    end;
    
    procedure TForm29.UpdateMemo(aLine: String);
    begin
      Memo1.Lines.Add(aLine);
      Memo1.Repaint;
    end;
    
    end.
    L'unité métier
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
     
    unit Unit30;
     
    interface
     
    uses System.SysUtils, System.Classes,
      Winsoft.FireMonkey.PDFium;
     
    type
     
      TSearchInPDFFiles = class(TThread)
      private
        FDir: String;
        FTexte: String;
        FUpdateResult: TProc<String>;
        FEndOfThread: TProc;
        procedure SetEndOfThread(const Value: TProc);
      protected
        procedure SetUpdateResult(const Value: TProc<String>);
        procedure SetDir(const Value: String);
        procedure SetTexte(const Value: String);
        procedure Execute; override;
        procedure FindPdfFiles;
      public
        constructor Create;
        property Dir: String read FDir write SetDir;
        property Texte: String read FTexte write SetTexte;
        property UpdateResult: TProc<String> read FUpdateResult
          write SetUpdateResult;
        property EndOfThread: TProc read FEndOfThread write SetEndOfThread;
      end;
     
    function isTexteinPDF(Texte: String; PdfFileName: TFileName): Boolean;
     
    implementation
     
    uses System.Types, System.IOUtils;
     
    function isTexteinPDF(Texte: String; PdfFileName: TFileName): Boolean;
    var
      aFpdf: TFPdf;
      p: integer;
    begin
      aFpdf := TFPdf.Create(nil);
      try
        aFpdf.FileName := PdfFileName;
        try
          AFPdf.Active:=True;
        except
         Exit(False)
        end;
        aFpdf.Active := True;
        result := False;
        for p := 1 to aFpdf.PageCount do
        begin
          aFpdf.PageNumber := p;
          if aFpdf.FindFirst(Texte) > 0 then
          begin
            result := True;
            Break;
          end;
        end;
        aFpdf.Active := False;
      finally
        aFpdf.Free;
      end;
    end;
     
    { TSearchInPDFFiles }
     
    constructor TSearchInPDFFiles.Create;
    begin
      inherited Create(True);
      FreeOnTerminate := True;
    end;
     
    procedure TSearchInPDFFiles.Execute;
    begin
      FindPdfFiles;
      // fin de thread
      if Assigned(FEndOfThread) then
        Synchronize(nil,
          procedure
          begin
            FEndOfThread;
          end)
    end;
     
    procedure TSearchInPDFFiles.FindPdfFiles;
    var
      PdfFileName: TFileName;
      Files: TArray<String>;
    begin
      Files := TDirectory.GetFiles(FDir, '*.pdf',
        System.IOUtils.TSearchOption.soAllDirectories);
      for PdfFileName in Files do
        begin
          // montre chaque fichier pdf trouvé (optionnel)
          Synchronize(nil,
            procedure
            begin
              FUpdateResult(PdfFileName);
            end);
         // texte (i.e. 'facture') trouvé 
        if isTexteinPDF(FTexte, PdfFileName) then
          Synchronize(nil,
            procedure
            begin
              FUpdateResult('Trouvé dans '+PdfFileName);
            end);
        end;
    end;
     
    procedure TSearchInPDFFiles.SetDir(const Value: String);
    begin
      FDir := Value;
    end;
     
    procedure TSearchInPDFFiles.SetEndOfThread(const Value: TProc);
    begin
      FEndOfThread := Value;
    end;
     
    procedure TSearchInPDFFiles.SetTexte(const Value: String);
    begin
      FTexte := Value;
    end;
     
    procedure TSearchInPDFFiles.SetUpdateResult(const Value: TProc<String>);
    begin
      FUpdateResult := Value;
    end;
     
    end.
    MVP Embarcadero
    Delphi installés : D3,D7,D2010,XE4,XE7,D10 (Rio, Sidney), D11 (Alexandria), D12 (Athènes)
    SGBD : Firebird 2.5, 3, SQLite
    générateurs États : FastReport, Rave, QuickReport
    OS : Window Vista, Windows 10, Windows 11, Ubuntu, Androïd

  15. #15
    Membre confirmé
    Homme Profil pro
    Enseignant
    Inscrit en
    Août 2008
    Messages
    666
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Algérie

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Août 2008
    Messages : 666
    Points : 643
    Points
    643
    Par défaut
    Bonjour,

    Je vous remercie pour vos interventions.

    Serge, sous XE5, je reçois toujours l'erreur sur le "Task" (voir en couleur rouge) dans la partie :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    TTask.Run(
        procedure
        var
          PdfFileName: TFileName;
          Files: TArray<String>;
        begin
          Files := TDirectory.GetFiles(dir, '*.pdf',
            System.IOUtils.TSearchOption.soAllDirectories);
    Pour le
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    System.IOUtils.TSearchOption.soAllDirectories
    il y a une incompatibilité entre :
    E2010 Types incompatibles : 'System.TArray<System.string>' et 'TStringDynArray'

    Merci.

  16. #16
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 043
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 67
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15 043
    Points : 40 957
    Points
    40 957
    Billets dans le blog
    62
    Par défaut
    Bonjour,

    Nabil, c'est normal, j'ai laissé l'ancien code pour voir les différences entre un TTask et un TThread il faut bien évidemment que tu supprimes la procedure TForm29.btnOccurencesClick.
    Il faut te concentrer sur la seconde procédure et surtout l'unité métier associée qui n'utilise pas TTask.
    MVP Embarcadero
    Delphi installés : D3,D7,D2010,XE4,XE7,D10 (Rio, Sidney), D11 (Alexandria), D12 (Athènes)
    SGBD : Firebird 2.5, 3, SQLite
    générateurs États : FastReport, Rave, QuickReport
    OS : Window Vista, Windows 10, Windows 11, Ubuntu, Androïd

  17. #17
    Membre confirmé
    Homme Profil pro
    Enseignant
    Inscrit en
    Août 2008
    Messages
    666
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Algérie

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Août 2008
    Messages : 666
    Points : 643
    Points
    643
    Par défaut
    Re,
    merci, reste juste le soucis du Files := TDirectory.GetFiles(FDir, '*.pdf', TSearchOption.soAllDirectories);

    "" 'System.TArray<System.string>' et 'TStringDynArray'""
    T'as une idée comment leur compatibilitée stp?

    [EDIT] j'ai remplacé "TArray<System.string>" par "TStringDynArray"

    C'est OK.
    Merci beaucoup pour cette jolie démonstration.

  18. #18
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 043
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 67
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15 043
    Points : 40 957
    Points
    40 957
    Billets dans le blog
    62
    Par défaut
    Ligne 92 , remplace Files: TArray<String>; par Files: TStringDynArray;

    seulement après, ligne 96 la boucle for PdfFileName in Files do risque d'être à changer
    en quelque chose comme for i:=Low(Files) to High(Files) do pdfFileName étant remplacé par Files[i]

    Désolé, pas le temps de tester, j'assiste aux premiers pas de mon petit fils avant d'aller faire quelques courses (pharmacie) dans le bourg
    MVP Embarcadero
    Delphi installés : D3,D7,D2010,XE4,XE7,D10 (Rio, Sidney), D11 (Alexandria), D12 (Athènes)
    SGBD : Firebird 2.5, 3, SQLite
    générateurs États : FastReport, Rave, QuickReport
    OS : Window Vista, Windows 10, Windows 11, Ubuntu, Androïd

  19. #19
    Membre confirmé
    Homme Profil pro
    Enseignant
    Inscrit en
    Août 2008
    Messages
    666
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Algérie

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Août 2008
    Messages : 666
    Points : 643
    Points
    643
    Par défaut
    Citation Envoyé par SergioMaster Voir le message
    Ligne 92 , remplace Files: TArray<String>; par Files: TStringDynArray;

    seulement après, ligne 96 la boucle for PdfFileName in Files do risque d'être à changer
    en quelque chose comme for i:=Low(Files) to High(Files) do pdfFileName étant remplacé par Files[i]

    Désolé, pas le temps de tester, j'assiste aux premiers pas de mon petit fils avant d'aller faire quelques courses (pharmacie) dans le bourg
    Un grand MERCI pour ton intervention fructueuse comme d'habitude.

    Toutes mes félicitations pour ses premiers pas . Ton petit fils risque dorénavant de vous faire des ravages à la maison .

    Bon courage.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Afficher fichier pdf suite à une recherche par mot clé
    Par Tibao2b dans le forum EDI, CMS, Outils, Scripts et API
    Réponses: 0
    Dernier message: 17/05/2013, 12h11
  2. [Tableaux] Moteur de recherche par mot clés
    Par Nee dans le forum Langage
    Réponses: 4
    Dernier message: 20/01/2006, 11h30
  3. [Base de documents] Upload et Recherche par mots clé
    Par yascov dans le forum Décisions SGBD
    Réponses: 3
    Dernier message: 30/12/2005, 18h59
  4. recherche par mot clé
    Par seb59dk dans le forum Access
    Réponses: 3
    Dernier message: 06/09/2005, 14h26
  5. Recherche par mots clés
    Par legillou dans le forum Algorithmes et structures de données
    Réponses: 4
    Dernier message: 17/06/2005, 10h56

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo