html Używanie PDFium VCL w Delphi do bezpośredniego porównywania dokumentów PDF | losLab Software Development Blog

Artykuł techniczny

Używanie PDFium VCL w Delphi do bezpośredniego porównywania dokumentów PDF

· Programowanie PDF

Porównywanie wielu dokumentów PDF obok siebie jest niezbędne do przeglądu wersji, kontroli jakości i weryfikacji dokumentów. The Widok podzielony pokazuje, jak wyświetlić dwa lub trzy dokumenty PDF jednocześnie przy użyciu PDFium VCL.

Przegląd

To zaawansowane demo wyświetla wiele dokumentów PDF w zsynchronizowanych widokach, umożliwiając użytkownikom wizualne porównywanie dokumentów. Obsługuje zarówno dwukierunkowe, jak i trójstronne tryby porównania, z niezależną nawigacją i sterowaniem powiększaniem dla każdego widoku.

Kluczowe funkcje

  • Tryb dwóch paneli – Porównaj dwa dokumenty obok siebie
  • Tryb trzech paneli – Porównaj trzy dokumenty jednocześnie
  • Niezależna nawigacja – Nawiguj niezależnie po każdym dokumencie
  • Zsynchronizowane powiększenie – Zastosuj powiększenie do wszystkich widoków lub indywidualnie
  • Wybór tekstu – Wybierz i skopiuj tekst z dowolnego panelu
  • Zapisz jako obraz – Eksportuj bieżący widok jako obraz
  • Aktywne podświetlanie panelu – Wizualna sygnalizacja aktywnego panelu

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.

Konfigurowanie wielu widoków

Zakreślacz składni Urvanov v2.9.1
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
type
  TFormMain = class(TForm)
    // Three PDF components
    Pdf1: TPdf;
    Pdf2: TPdf;
    Pdf3: TPdf;
    
    // Three view components
    PdfView1: TPdfView;
    PdfView2: TPdfView;
    PdfView3: TPdfView;
    
    // Container panels
    ScrollBox1: TScrollBox;
    ScrollBox2: TScrollBox;
    ScrollBox3: TScrollBox;
    
    // Splitters for resizing
    Splitter1: TSplitter;
    Splitter2: TSplitter;
    
  private
    FActivePdfView: TPdfView;  // Currently active view
    FAllViewsMode: Boolean;    // Apply actions to all views
    ThreeViewMode: Boolean;    // Three-panel mode enabled
  end;
[Czas formatowania: 0,0007 sekundy]

Przełączanie pomiędzy trybami widoku

Zakreślacz składni Urvanov v2.9.1
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
procedure TFormMain.SpeedButtonThreeViewClick(Sender: TObject);
begin
  ThreeViewMode := not ThreeViewMode;
  SpeedButtonThreeView.Down := ThreeViewMode;
  UpdateLayout;
end;
 
procedure TFormMain.UpdateLayout;
var
  TotalWidth: Integer;
begin
  if ThreeViewMode then
  begin
    // Three view mode: equal thirds
    ScrollBox1.Align := alNone;
    ScrollBox2.Align := alNone;
    ScrollBox3.Align := alNone;
    
    Splitter1.Visible := False;
    Splitter2.Visible := False;
    
    TotalWidth := ClientWidth;
    
    ScrollBox1.Left := 0;
    ScrollBox1.Width := TotalWidth div 3;
    ScrollBox1.Height := ClientHeight - PanelButtons.Height;
    
    ScrollBox2.Left := ScrollBox1.Width;
    ScrollBox2.Width := TotalWidth div 3;
    ScrollBox2.Height := ClientHeight - PanelButtons.Height;
    
    ScrollBox3.Left := ScrollBox2.Left + ScrollBox2.Width;
    ScrollBox3.Width := TotalWidth - ScrollBox3.Left;
    ScrollBox3.Height := ClientHeight - PanelButtons.Height;
    ScrollBox3.Visible := True;
    
    SpeedButtonOpenPdf3.Visible := True;
  end
  else
  begin
    // Two view mode: equal halves
    ScrollBox3.Visible := False;
    Splitter2.Visible := False;
    
    TotalWidth := ClientWidth;
    
    ScrollBox1.Left := 0;
    ScrollBox1.Width := TotalWidth div 2;
    ScrollBox1.Height := ClientHeight - PanelButtons.Height;
    
    ScrollBox2.Left := ScrollBox1.Width;
    ScrollBox2.Width := TotalWidth - ScrollBox2.Left;
    ScrollBox2.Height := ClientHeight - PanelButtons.Height;
    
    SpeedButtonOpenPdf3.Visible := False;
  end;
end;
[Czas formatowania: 0,0008 sekundy]

Otwieranie plików PDF w każdym panelu

Zakreślacz składni Urvanov v2.9.1
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
procedure TFormMain.OpenPdfFile(PdfComponent: TPdf;
  PdfViewComponent: TPdfView; const Title: string);
var
  Password: string;
begin
  if OpenDialog.Execute then
  begin
    PdfComponent.Active := False;
    PdfComponent.FileName := OpenDialog.FileName;
    PdfComponent.Password := '';
    
    try
      PdfViewComponent.Active := True;
    except
      on Error: EPdfError do
        if Error.Message = 'Password required or incorrect password' then
        begin
          if InputQuery('Enter Password', 'Password: ', Password) then
          begin
            PdfComponent.Password := Password;
            PdfViewComponent.Active := True;
          end
          else
            raise;
        end
        else
          raise;
    end;
    
    SetActivePdfView(PdfViewComponent);
    UpdateControlsState;
  end;
end;
 
procedure TFormMain.SpeedButtonOpenPdf1Click(Sender: TObject);
begin
  OpenPdfFile(Pdf1, PdfView1, 'PDF 1');
end;
 
procedure TFormMain.SpeedButtonOpenPdf2Click(Sender: TObject);
begin
  OpenPdfFile(Pdf2, PdfView2, 'PDF 2');
end;
 
procedure TFormMain.SpeedButtonOpenPdf3Click(Sender: TObject);
begin
  OpenPdfFile(Pdf3, PdfView3, 'PDF 3');
end;
[Czas formatu: 0,0005 sekundy]

Zarządzanie aktywnym panelem

Zakreślacz składni Urvanov v2.9.1
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
procedure TFormMain.SetActivePdfView(PdfView: TPdfView);
begin
  FActivePdfView := PdfView;
  
  // Visual feedback for active panel
  if PdfView = PdfView1 then
  begin
    ScrollBox1.Color := clHighlight;
    ScrollBox2.Color := clWindow;
    ScrollBox3.Color := clWindow;
  end
  else if PdfView = PdfView2 then
  begin
    ScrollBox1.Color := clWindow;
    ScrollBox2.Color := clHighlight;
    ScrollBox3.Color := clWindow;
  end
  else if PdfView = PdfView3 then
  begin
    ScrollBox1.Color := clWindow;
    ScrollBox2.Color := clWindow;
    ScrollBox3.Color := clHighlight;
  end;
  
  UpdateControlsState;
end;
 
procedure TFormMain.PdfView1Click(Sender: TObject);
begin
  SetActivePdfView(PdfView1);
end;
 
procedure TFormMain.PdfView2Click(Sender: TObject);
begin
  SetActivePdfView(PdfView2);
end;
 
procedure TFormMain.PdfView3Click(Sender: TObject);
begin
  SetActivePdfView(PdfView3);
end;
[Czas formatowania: 0,0004 sekundy]

Stosowanie akcji do aktywnych lub wszystkich widoków

Zakreślacz składni Urvanov v2.9.1
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
procedure TFormMain.ApplyToAllViews(const Operation: string);
begin
  if FAllViewsMode then
  begin
    // Apply to all active views
    if PdfView1.Active then
      ApplyOperation(PdfView1, Operation);
    if PdfView2.Active then
      ApplyOperation(PdfView2, Operation);
    if PdfView3.Active and ThreeViewMode then
      ApplyOperation(PdfView3, Operation);
  end
  else
  begin
    // Apply only to active view
    if Assigned(FActivePdfView) then
      ApplyOperation(FActivePdfView, Operation);
  end;
end;
 
procedure TFormMain.SpeedButtonZoomInClick(Sender: TObject);
begin
  ApplyToAllViews('ZoomIn');
end;
 
procedure TFormMain.SpeedButtonZoomOutClick(Sender: TObject);
begin
  ApplyToAllViews('ZoomOut');
end;
[Czas formatowania: 0,0003 sekundy]

Zsynchronizowana nawigacja strony (opcjonalnie)

Zakreślacz składni Urvanov v2.9.1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
procedure TFormMain.SynchronizePages(SourceView: TPdfView);
var
  PageNum: Integer;
begin
  if not chkSynchronize.Checked then
    Exit;
    
  PageNum := SourceView.PageNumber;
  
  // Apply to other views
  if (SourceView <> PdfView1) and PdfView1.Active then
    if PageNum <= PdfView1.PageCount then
      PdfView1.PageNumber := PageNum;
      
  if (SourceView <> PdfView2) and PdfView2.Active then
    if PageNum <= PdfView2.PageCount then
      PdfView2.PageNumber := PageNum;
      
  if (SourceView <> PdfView3) and PdfView3.Active and ThreeViewMode then
    if PageNum <= PdfView3.PageCount then
      PdfView3.PageNumber := PageNum;
end;
[Czas formatowania: 0,0004 sekundy]

Niezależne sterowanie zoomem

Zakreślacz składni Urvanov v2.9.1
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
procedure TFormMain.DoZoom1;
begin
  if PdfView1.Active and (PdfView1.PageNumber > 0) then
  begin
    case ComboBoxZoom.ItemIndex of
      0: PdfView1.Zoom := 0.5;
      1: PdfView1.Zoom := 0.75;
      2: PdfView1.Zoom := 1.0;
      3: PdfView1.Zoom := 1.5;
      4: PdfView1.Zoom := 2.0;
      5: PdfView1.Zoom := PdfView1.PageWidthZoom[PdfView1.PageNumber];
      6: PdfView1.Zoom := PdfView1.PageZoom[PdfView1.PageNumber];
    end;
  end;
end;
 
procedure TFormMain.DoZoom2;
begin
  if PdfView2.Active and (PdfView2.PageNumber > 0) then
  begin
    // Same zoom logic for view 2
  end;
end;
 
procedure TFormMain.DoZoom3;
begin
  if PdfView3.Active and (PdfView3.PageNumber > 0) then
  begin
    // Same zoom logic for view 3
  end;
end;
[Czas formatowania: 0,0004 sekundy]

Zapisywanie bieżącego widoku jako obrazu

Zakreślacz składni Urvanov v2.9.1
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
procedure TFormMain.MenuItemSaveAsImage1Click(Sender: TObject);
begin
  SaveViewAsImage(PdfView1, Pdf1);
end;
 
procedure TFormMain.SaveViewAsImage(PdfView: TPdfView; Pdf: TPdf);
var
  Bitmap: TBitmap;
  JpegImage: TJpegImage;
begin
  if not PdfView.Active then
  begin
    ShowMessage('No document loaded in this view.');
    Exit;
  end;
  
  SavePictureDialog.FileName := 'page_' + IntToStr(PdfView.PageNumber) + '.jpg';
  
  if SavePictureDialog.Execute then
  begin
    Pdf.PageNumber := PdfView.PageNumber;
    
    Bitmap := Pdf.RenderPage(
      0, 0,
      Round(Pdf.PageWidth * 2),  // 2x resolution
      Round(Pdf.PageHeight * 2),
      PdfView.Rotation, [], clWhite
    );
    
    try
      JpegImage := TJpegImage.Create;
      try
        JpegImage.Assign(Bitmap);
        JpegImage.CompressionQuality := 90;
        JpegImage.SaveToFile(SavePictureDialog.FileName);
        ShowMessage('Image saved successfully.');
      finally
        JpegImage.Free;
      end;
    finally
      Bitmap.Free;
    end;
  end;
end;
[Czas formatu: 0,0005 sekundy]

Wybór tekstu w każdym panelu

Zakreślacz składni Urvanov v2.9.1
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
procedure TFormMain.PdfView1MouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
  SetActivePdfView(PdfView1);
  
  if Button = mbLeft then
  begin
    Selecting := True;
    SelectionStart := PdfView1.CharacterIndexAtPos(X, Y, 5.0, 5.0);
    SelectionEnd := SelectionStart;
  end;
end;
 
procedure TFormMain.PdfView1MouseMove(Sender: TObject; Shift: TShiftState;
  X, Y: Integer);
begin
  if Selecting then
  begin
    SelectionEnd := PdfView1.CharacterIndexAtPos(X, Y, 5.0, 5.0);
    PdfView1.Invalidate;
  end;
end;
 
procedure TFormMain.PdfView1MouseUp(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
  Selecting := False;
end;
[Czas formatowania: 0,0004 sekundy]

Przypadki użycia

  • Przegląd wersji dokumentu – Porównaj dokumenty oryginalne i poprawione
  • Kontrola jakości – Zweryfikuj produkcję względem szablonów
  • Przegląd prawny – Porównaj wersje umów
  • Weryfikacja tłumaczenia – Wyświetl dokumenty źródłowe i przetłumaczone
  • Dokumenty wielojęzyczne – Wyświetl tę samą treść w różnych językach

Wniosek

Demo Split View prezentuje elastyczność PDFium VCL w tworzeniu zaawansowanych narzędzi do porównywania dokumentów. Dzięki obsłudze wielu niezależnych widoków, zsynchronizowanej nawigacji i kontrolom na panelu możesz tworzyć profesjonalne aplikacje porównawcze.

Możliwość otwierania różnych plików PDF w każdym panelu i porównywania ich wizualnie jest nieoceniona w przepływach pracy związanych z przeglądaniem wersji i kontrolą jakości.

Twórz potężne narzędzia do porównywania dokumentów z Delphi PDFium VCL Komponent.