Ekstrakcja tekstu jest jednym z najczęstszych zadań przetwarzania PDF. Niezależnie od tego, czy tworzysz wyszukiwarkę dokumentów, aplikację do eksploracji danych, czy system zarządzania treścią, możliwość wyodrębnienia tekstu z plików PDF jest niezbędna. W tym samouczku opisano Wyodrębnij tekst , które pokazuje, jak wyodrębnić treść tekstową z dokumentów PDF za pomocą PDFium VCL.
Przegląd
Demo wyodrębnienia tekstu demonstruje, jak wyodrębnić całą zawartość tekstową z dokumentu PDF i zapisać ją w pliku tekstowym. Obsługuje wybór zakresu stron, zachowanie akapitów i poprawnie obsługuje znaki specjalne.
Kluczowe funkcje
- Pełna ekstrakcja dokumentów – Wyodrębnij tekst ze wszystkich stron jednocześnie
- Wybór zakresu stron – Wyodrębnij tekst tylko z określonych stron
- Wykrywanie akapitu – Zachowaj strukturę akapitu w oparciu o pozycje znaków
- Obsługa znaków specjalnych – Opcja usuwania znaków NUL z wyjścia
- Separatory stron – Opcjonalne puste linie pomiędzy stronami
- Śledzenie postępu – Wizualny pasek postępu i szczegółowe rejestrowanie
- Wyjście UTF-8 – Prawidłowo zakodowany tekst wyjściowy dla dokumentów międzynarodowych
- Dostęp na poziomie znaku – Dostęp do poszczególnych znaków w celu zaawansowanego przetwarzania
PDFium Wymagania DLL
Przed uruchomieniem jakiejkolwiek aplikacji PDFium VCL upewnij się, że są zainstalowane pliki DLL PDFium:
pdfium32.dll/pdfium64.dll– Wersje standardowe (~5-6 MB)pdfium32v8.dll/pdfium64v8.dll– Z silnikiem V8 JavaScript (~23-27 MB)
Instalacja: Uruchom PDFiumVCL\DLLs\CopyDlls.bat jako Administrator, aby automatycznie kopiować biblioteki DLL do katalogów systemu Windows.
Podstawowe wyodrębnianie tekstu
Najprostszy sposób wyodrębnienia tekstu ze strony PDF:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
procedure ExtractSimpleText; var Pdf: TPdf; PageText: string; begin Pdf := TPdf.Create(nil); try Pdf.FileName := 'document.pdf'; Pdf.Active := True; // Extract text from page 1 Pdf.PageNumber := 1; PageText := Pdf.Text; // Use the extracted text Memo1.Lines.Text := PageText; finally Pdf.Active := False; Pdf.Free; end; end; |
Wyodrębnianie ze wszystkich stron
Przejdź przez wszystkie strony w pętli, aby wyodrębnić pełny tekst dokumentu:
|
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 |
procedure TFormMain.ButtonExtractClick(Sender: TObject); var I, StartPage, EndPage: Integer; PageText: string; FileStream: TFileStream; Text: UTF8String; begin Pdf.FileName := EditPdfFile.Text; Pdf.PageNumber := 0; Pdf.Active := True; try // Determine page range if RadioButtonAllPages.Checked then begin StartPage := 1; EndPage := Pdf.PageCount; end else begin StartPage := StrToInt(EditFromPage.Text); EndPage := StrToInt(EditToPage.Text); end; // Create output file FileStream := TFileStream.Create(EditOutputFile.Text, fmCreate); try for I := StartPage to EndPage do begin Pdf.PageNumber := I; PageText := Pdf.Text; // Convert to UTF-8 and write Text := UTF8Encode(PageText); if Length(Text) > 0 then FileStream.WriteBuffer(Text[1], Length(Text)); // Add page separator if enabled if CheckBoxPageSeparator.Checked and (I < EndPage) then begin Text := UTF8Encode(#13#10#13#10#13#10); FileStream.WriteBuffer(Text[1], Length(Text)); end; ProgressBar.Position := I - StartPage + 1; Application.ProcessMessages; end; finally FileStream.Free; end; finally Pdf.Active := False; end; end; |
Wyodrębnianie tekstu z zachowaniem akapitu
W przypadku dokumentów, w których ważna jest struktura akapitów, użyj analizy pozycji znaków:
|
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 |
function ExtractTextWithParagraphs(Pdf: TPdf): string; var CharIndex: Integer; CurrentChar: WideChar; CurrentY, PrevY: Double; LineHeight, YGap: Double; ResultText, LineBuffer: string; MinLineHeight: Double; begin ResultText := ''; LineBuffer := ''; PrevY := -1; MinLineHeight := 999999; // First pass: determine typical line height for CharIndex := 0 to Pdf.CharacterCount - 1 do begin CurrentY := Pdf.CharacterOrigin[CharIndex].Y; if PrevY >= 0 then begin YGap := Abs(CurrentY - PrevY); if (YGap > 0) and (YGap < MinLineHeight) then MinLineHeight := YGap; end; PrevY := CurrentY; end; LineHeight := MinLineHeight; if LineHeight <= 0 then LineHeight := 12; // Default fallback // Second pass: build text with paragraph detection PrevY := -1; for CharIndex := 0 to Pdf.CharacterCount - 1 do begin CurrentChar := Pdf.Character[CharIndex]; CurrentY := Pdf.CharacterOrigin[CharIndex].Y; // Skip NUL characters if Ord(CurrentChar) = 0 then Continue; // Check for line break based on Y position change if PrevY >= 0 then begin YGap := Abs(CurrentY - PrevY); if YGap > LineHeight * 1.2 then begin // Add current line to result if LineBuffer <> '' then begin ResultText := ResultText + LineBuffer + #13#10; LineBuffer := ''; end; // Check if this is a paragraph break (larger gap) if YGap > LineHeight * 2.5 then ResultText := ResultText + #13#10; // Extra line for paragraph end; end; LineBuffer := LineBuffer + CurrentChar; PrevY := CurrentY; end; // Add final line if LineBuffer <> '' then ResultText := ResultText + LineBuffer; Result := ResultText; end; |
Czyszczenie wyodrębnionego tekstu
Usuń znaki NUL i znormalizuj tekst:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
function CleanAndFormatText(const RawText: string): UTF8String; var I: Integer; CleanText: string; begin CleanText := ''; for I := 1 to Length(RawText) do begin // Skip NUL characters but keep all other characters if Ord(RawText[I]) <> 0 then CleanText := CleanText + RawText[I]; end; Result := UTF8Encode(CleanText); end; |
Wyodrębnianie tekstu z określonego regionu
Wyodrębnij tekst z prostokątnego obszaru strony:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
procedure ExtractTextFromRegion; var Pdf: TPdf; RegionText: string; begin Pdf := TPdf.Create(nil); try Pdf.FileName := 'document.pdf'; Pdf.Active := True; Pdf.PageNumber := 1; // Extract text from specific rectangle // Parameters: Left, Top, Right, Bottom (in PDF coordinates) RegionText := Pdf.TextInRectangle(100, 700, 500, 600); ShowMessage('Text in region: ' + RegionText); finally Pdf.Active := False; Pdf.Free; end; end; |
Dostęp na poziomie znaku
Aby uzyskać precyzyjną analizę tekstu, uzyskaj dostęp do poszczególnych znaków:
|
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 |
procedure AnalyzeCharacters; var Pdf: TPdf; I: Integer; Char: WideChar; Origin: TPdfPoint; Rect: TPdfRectangle; FontSize: Double; begin Pdf := TPdf.Create(nil); try Pdf.FileName := 'document.pdf'; Pdf.Active := True; Pdf.PageNumber := 1; // Access each character for I := 0 to Pdf.CharacterCount - 1 do begin Char := Pdf.Character[I]; Origin := Pdf.CharacterOrigin[I]; Rect := Pdf.CharacterRectangle[I]; FontSize := Pdf.FontSize[I]; // Check character properties if Pdf.CharacterGenerated[I] then // Character was generated (e.g., hyphenation) Continue; if Pdf.CharacterMapError[I] then // Character couldn't be mapped to Unicode Continue; // Process character with position and size info Memo1.Lines.Add(Format('Char: %s at (%.2f, %.2f) size: %.2f', [Char, Origin.X, Origin.Y, FontSize])); end; finally Pdf.Active := False; Pdf.Free; end; end; |
Znajdowanie postaci w pozycji na ekranie
Przydatne przy zaznaczaniu tekstu i interakcji:
|
1 2 3 4 5 |
function GetCharacterAtPosition(Pdf: TPdf; X, Y: Double): Integer; begin // Get character index at position with tolerance Result := Pdf.CharacterIndexAtPos(X, Y, 5.0, 5.0); end; |
Obsługa błędów i przypadków Edge
|
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 |
procedure TFormMain.SafeExtractText; begin try Pdf.FileName := EditPdfFile.Text; Pdf.PageNumber := 0; Pdf.Active := True; except on E: Exception do begin LogMessage('Failed to load PDF: ' + E.Message); Exit; end; end; try for I := StartPage to EndPage do begin try Pdf.PageNumber := I; PageText := Pdf.Text; // Process text... except on E: Exception do begin // Log error but continue with next page LogMessage('Error on page ' + IntToStr(I) + ': ' + E.Message); end; end; end; finally Pdf.Active := False; end; end; |
Względy wydajności
- Wyodrębnij tekst strona po stronie, zamiast ładować wszystko do pamięci
- Użyj strumieniowego przesyłania plików wyjściowych w przypadku dużych dokumentów
- Zadzwoń
Application.ProcessMessagesw pętlach w celu zapewnienia responsywności interfejsu użytkownika - Rozważ przetwarzanie wsadowe wielu dokumentów
Wniosek
Demo wyodrębnienia tekstu pokazuje, jak PDFium VCL sprawia, że wyodrębnianie tekstu jest proste i niezawodne. Niezależnie od tego, czy potrzebujesz podstawowej ekstrakcji tekstu, czy zaawansowanego przetwarzania z uwzględnieniem akapitów, komponent zapewnia wszystkie potrzebne narzędzia.
Dostęp na poziomie znaków pozwala na zaawansowaną analizę tekstu, a jednocześnie jest prosty Text obsługuje najczęstsze przypadki użycia za pomocą jednej linii kodu.
Rozpocznij budowanie Twoje rozwiązanie do ekstrakcji tekstu PDFium VCL Komponent dzisiaj.