여러 PDF 문서를 나란히 비교하는 것은 수정 검토, 품질 관리 및 문서 확인에 필수적입니다. 분할 보기 데모는 PDFium VCL을 사용하여 두 개 또는 세 개의 PDF 문서를 동시에 표시하는 방법을 보여줍니다.
개요
이 고급 데모는 여러 PDF 문서를 동기화된 보기로 표시하여 사용자가 시각적으로 문서를 비교할 수 있도록 합니다. 이 데모는 양방향 및 삼방향 비교 모드를 모두 지원하며, 각 보기마다 독립적인 탐색 및 확대/축소 컨트롤을 제공합니다.
주요 기능
- 2분할 모드 – 두 개의 문서를 나란히 비교
- 세 패널 모드 – 세 개의 문서를 동시에 비교합니다.
- 독립적인 탐색 – 각 문서를 독립적으로 탐색합니다.
- 동기화 확대/축소 – 모든 보기 또는 개별적으로 확대/축소 기능을 적용합니다.
- 텍스트 선택 – 모든 패널에서 텍스트를 선택하고 복사합니다.
- 이미지로 저장 – 현재 보기를 이미지로 내보내기
- 활성 패널 강조 표시 – 활성 패널의 시각적 표시
PDFium DLL 요구 사항
PDFium VCL 애플리케이션을 실행하기 전에, PDFium DLL 파일이 설치되어 있는지 확인하십시오.
pdfium32.dll/pdfium64.dll– 표준 버전 (약 5-6 MB)pdfium32v8.dll/pdfium64v8.dll– V8 JavaScript 엔진 포함 (약 23-27 MB)
설치: 실행 PDFiumVCL\DLLs\CopyDlls.bat 관리자 권한으로 실행하여 DLL 파일을 Windows 시스템 디렉터리에 자동으로 복사합니다.
여러 보기 설정
|
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; |
보기 모드 전환
|
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; |
각 패널에서 PDF 파일 열기
|
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; |
활성 패널 관리
|
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; |
활성 또는 모든 보기에서 작업 적용
|
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; |
동기화된 페이지 탐색 (선택 사항)
|
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; |
독립적인 확대/축소 컨트롤
|
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; |
현재 보기 저장 (이미지 형식)
|
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; |
각 패널에서의 텍스트 선택
|
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; |
사용 사례
- 문서 수정 검토 – 원본 문서와 수정된 문서 비교
- 품질 관리 – 템플릿과 실제 결과물을 비교 검토합니다.
- 법률 검토 – 계약서 버전 비교
- 번역 검증 – 원본 문서 및 번역된 문서를 확인합니다.
- 다국어 문서 – 동일한 콘텐츠를 여러 언어로 확인합니다.
결론
Split View 데모는 PDFium VCL의 유연성을 보여주며, 이를 통해 고급 문서 비교 도구를 개발할 수 있습니다. 여러 개의 독립적인 뷰, 동기화된 탐색, 패널별 제어 기능을 지원하여 전문적인 비교 애플리케이션을 만들 수 있습니다.
각 패널에서 서로 다른 PDF 파일을 열고 시각적으로 비교하는 기능은 수정 검토 및 품질 관리 워크플로우에 매우 유용합니다.
강력한 문서 비교 도구를 개발하세요. Delphi PDFium VCL 컴포넌트를 사용하여. Delphi PDFium VCL 컴포넌트..