استخراج النص هو واحدة من أكثر مهام معالجة ملفات PDF شيوعًا. سواء كنت تقوم ببناء محرك بحث عن المستندات، أو تطبيق لتنقيب البيانات، أو نظام لإدارة المحتوى، فإن القدرة على استخراج النص من ملفات PDF أمر ضروري. يغطي هذا البرنامج التعليمي استخراج النص مثال توضيحي، والذي يوضح كيفية استخراج محتوى النص من مستندات PDF باستخدام PDFium VCL.
نظرة عامة
يوضح المثال التوضيحي لاستخراج النص كيفية استخراج كل محتوى النص من مستند PDF وحفظه في ملف نصي. وهو يدعم تحديد نطاق الصفحات، والحفاظ على الفقرات، ويعالج الأحرف الخاصة بشكل صحيح.
الميزات الرئيسية
- استخراج المستند بالكامل - استخراج النص من جميع الصفحات مرة واحدة
- تحديد نطاق الصفحات - استخراج النص من صفحات محددة فقط
- اكتشاف الفقرات الحفاظ على هيكل الفقرات بناءً على مواقع الأحرف.
- معالجة الأحرف الخاصة. خيار لإزالة أحرف NUL من الإخراج.
- فواصل الصفحات. سطور فارغة اختيارية بين الصفحات.
- تتبع التقدم. شريط تقدم مرئي وتسجيل تفصيلي.
- إخراج بتنسيق UTF-8. نص مُرمّز بشكل صحيح للإخراج لتوثيق دولي.
- الوصول على مستوى الأحرف - الوصول إلى الأحرف الفردية لإجراء معالجة متقدمة.
متطلبات ملف PDFium DLL.
قبل تشغيل أي تطبيق PDFium VCL، تأكد من تثبيت ملفات PDFium DLL:
pdfium32.dll/pdfium64.dll– الإصدارات القياسية (حوالي 5-6 ميجابايت).pdfium32v8.dll/pdfium64v8.dll– مع محرك JavaScript V8 (حوالي 23-27 ميجابايت).
التثبيت: تشغيل PDFiumVCL\DLLs\CopyDlls.bat بصلاحيات المسؤول لنسخ ملفات DLL تلقائيًا إلى مجلدات نظام Windows.
استخراج النصوص الأساسي.
أبسط طريقة لاستخراج النص من صفحة 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; |
الاستخراج من جميع الصفحات.
التكرار عبر جميع الصفحات لاستخراج النص الكامل للمستند:
|
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; |
استخراج النص مع الحفاظ على هيكل الفقرات.
بالنسبة للمستندات التي يكون فيها هيكل الفقرات مهمًا، استخدم تحليل موضع الأحرف:
|
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; |
تنظيف النص المستخرج.
إزالة أحرف NUL وتوحيد النص:
|
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; |
استخراج النص من منطقة محددة.
استخراج النص من منطقة مستطيلة في الصفحة:
|
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; |
الوصول على مستوى الأحرف
لتحليل النص بدقة، قم بالوصول إلى الأحرف الفردية:
|
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; |
تحديد الحرف في موضع الشاشة
مفيد لاختيار النص والتفاعل معه:
|
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; |
معالجة الأخطاء والحالات الخاصة
|
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; |
اعتبارات الأداء
- استخراج النص صفحةً تلو الأخرى بدلاً من تحميل كل شيء في الذاكرة.
- استخدم إخراج الملفات المتدفقة للمستندات الكبيرة.
- استدعاء.
Application.ProcessMessagesفي الحلقات للحفاظ على استجابة واجهة المستخدم. - ضع في اعتبارك المعالجة الدفعية للمستندات المتعددة.
الخلاصة.
يوضح نموذج استخراج النص كيف يجعل مكون PDFium VCL استخراج النص بسيطًا وموثوقًا. سواء كنت بحاجة إلى استخراج نص أساسي أو معالجة متقدمة تدرك الفقرات، فإن هذا المكون يوفر جميع الأدوات التي تحتاجها.
يتيح الوصول على مستوى الأحرف تحليلًا متطورًا للنص، بينما البساطة. Text property 能够使用一行代码处理大多数常见用例.
开始构建. 您的文本提取解决方案. مكون PDFium VCL. اليوم.