Migration von Quick PDF Library und PdfiumViewer zu sgcPDF

Foxit hat Quick PDF Library am 13. Dezember 2021 eingestellt, und das PdfiumViewer-Repository ist seit dem 2. August 2019 schreibgeschützt. sgcPDF ersetzt beide: reines Pascal, das in Ihre Delphi-Exe kompiliert wird, und verwaltetes C# für WinForms, ohne PDF-DLL, die ausgeliefert werden muss. Dieses Kit ordnet die Funktionen von Quick PDF Library und die Klassen von PdfiumViewer sgcPDF zu, mit Code aus zwei Beispielen, die kompilieren und ihre Selbsttests bestehen.

Anwendungen auf einer PDF-Bibliothek, die nicht mehr weiterentwickelt wird

Zwei häufige Fälle: eine Delphi-Anwendung, die PDF-Dateien mit Quick PDF Library erstellt, zusammenführt, ausfüllt und rendert, und eine WinForms-Anwendung, die PDF-Dateien mit PdfiumViewer anzeigt.

Von Quick PDF Library (Delphi)

Quick PDF Library (Debenu Quick PDF Library, später Foxit Quick PDF Library) wird als DLL, ActiveX oder LIB mit einem Freischaltschlüssel ausgeliefert und arbeitet mit einem Objekt, in dem ein Dokument, eine Seite, eine Schrift und ein Bild "ausgewählt" sind. sgcPDF ist eine Sammlung von Pascal-Units mit einem Objektmodell: TsgcPDFDocument, TsgcPDFPage, TsgcPDFEditor und TsgcPDFAcroForm, von Delphi 7 bis Delphi 13.

Von PdfiumViewer (WinForms)

PdfiumViewer kapselt die native PDFium-Bibliothek in einem PdfViewer-Steuerelement, einem PdfRenderer und einem PdfDocument. Es zeigt PDF-Dateien an, durchsucht, rendert und druckt sie. sgcPDF ersetzt sie durch ein einziges verwaltetes Steuerelement, TsgcPDFViewerControl, und ergänzt, was PdfiumViewer nie hatte: PDF-Dateien erstellen, Formulare ausfüllen, Anmerkungen hinzufügen und Änderungen speichern.

Quick PDF Library. Die Foxit-Mitteilung (gelesen am 20.10.2026) lautet sinngemäß: "Ab dem 13. Dezember 2021 stellt Foxit die folgenden Produkte ein", und das erste Produkt der Liste ist Foxit Quick PDF Library (alle Plattformen). Kunden mit aktiven Wartungs- und Supportverträgen wurden bis zum 13. Dezember 2022 unterstützt: "Nach diesem Datum endet der Support für das Produkt, und Sie werden nicht mehr unterstützt." Als Ersatz nennt Foxit seine PDF-SDKs für Windows, Mac, Linux, Android und iOS, sein ActiveX-SDK und seine .NET-SDK-Suite.

PdfiumViewer. Das GitHub-Repository (gelesen am 20.10.2026) zeigt sinngemäß: "Dieses Repository wurde am 2. Aug. 2019 vom Eigentümer archiviert. Es ist jetzt schreibgeschützt." Die README erklärt: "Ich konnte seit langer Zeit keine echte Zeit mehr dafür aufwenden" und "Ich bin nicht in der Lage, dieses Projekt angemessen zu unterstützen." Außerdem steht dort: "Das PdfiumViewer-Steuerelement benötigt native PDFium-Bibliotheken. Diese sind nicht im NuGet-Paket von PdfiumViewer enthalten." Das NuGet-Paket wurde zuletzt am 6.11.2017 aktualisiert (Version 2.13.0) und zielt auf net20.

Eine PDF-Bibliothek, Quellcode inklusive

sgcPDF ist das PDF-Produkt von sgcUI. Es erstellt, bearbeitet, füllt, signiert, verschlüsselt, rendert und zeigt PDF-Dateien in Delphi und in .NET an.

Keine PDF-DLL auszuliefern

In Delphi werden die sgcPDF-Units in die Exe kompiliert: keine DLL, kein ActiveX und keine LIB, die ausgeliefert und registriert werden müssen, und kein Aufruf eines Freischaltschlüssels. In .NET ist sgcPDF verwalteter C#-Code, es gibt also keine pdfium.dll und kein natives x86- oder x64-Paket zur Auswahl: Das Beispiel läuft als AnyCPU.

Ein Objektmodell

Jeder Aufruf erhält das Seitenobjekt oder den Index, daher entfällt der "ausgewählte" Zustand von Quick PDF Library. Die Imposition nutzt vektorbasierte Form-XObjects (AddPageAsForm, DrawForm, DrawFormInRect), Formulare nutzen AcroForm, und die Verschlüsselung reicht bis AES-256 (emAES_256).

Ein Viewer, der bearbeitet

TsgcPDFViewerControl passt die Ansicht an Breite, Seite oder Höhe an, dreht die Ansicht, durchsucht und druckt mit Dialog, und in .NET liefert es ein PrintDocument wie PdfiumViewer. Es füllt außerdem Formularfelder (FormFilling), fügt Anmerkungen mit der Maus hinzu (AnnotationTool) und wählt Text aus. Seitenansichten: TsgcPDFThumbnailView, TsgcPDFOutlineView, TsgcPDFCommentsView.

sgcPDF wird einzeln verkauft, ab €249 für einen einzelnen Entwickler in Delphi und C++ Builder und ab €249 für .NET, mit vollständigem Quellcode und 1 Jahr Updates, und es ist Teil von sgcUI Enterprise und des All-Access-Bundles. Die .NET-Pakete gibt es außerdem als kostenlose Community-Pakete auf NuGet, esegece.sgcPDF.Community und esegece.sgcPDF.WinForms.Community, mit denselben Funktionen. Siehe die sgcPDF-Produktseite.

Funktionen von Quick PDF Library in sgcPDF

Die Units sind sgcPDF_Types, sgcPDF_Fonts und sgcPDF_Document, dazu bei Bedarf sgcPDF_Editor, sgcPDF_Encryption, sgcPDF_Renderer_GDI und sgcPDF_Export. Seitenindizes in sgcPDF beginnen bei 0.

Quick PDF Library sgcPDF
UnlockKeyim Code ist nichts aufzurufen
NewDocumentTsgcPDFDocument.Create, dann AddPage (ein neues Dokument hat keine Seite, bis Sie eine hinzufügen)
NewPage, SetPageDimensions, SetPageSizeTsgcPDFDocument.AddPage(AWidth, AHeight): TsgcPDFPage, InsertPage(AIndex, AWidth, AHeight)
LoadFromFile, LoadFromStringTsgcPDFDocument.LoadFromFile, LoadFromStream, LoadFromBytes
LoadFromFile mit PasswortTsgcPDFDocument.SetPassword(APassword) vor LoadFromFile
SaveToFile, SaveToStringTsgcPDFDocument.SaveToFile, SaveToStream, SaveIncremental
PageCountTsgcPDFDocument.PageCount; nur für eine Datei, sgcPDFGetPageCount(AFileName)
SelectPageTsgcPDFDocument.Pages[AIndex] (0-basiert, Standardeigenschaft), GetPage(AIndex)
SetInformationTsgcPDFDocument.Info.Title, .Author, .Subject, .Keywords, .Creator, .Producer
AddStandardFont + SelectFont + SetTextSize + DrawTextTsgcPDFPage.DrawText(AText, X, Y, AFont, AFontSize) mit einem TsgcPDFStandardFont (sfHelvetica, sfTimesRoman, sfCourier und ihre Varianten fett und kursiv)
SetTextColor + DrawTextTsgcPDFPage.DrawTextColor(AText, X, Y, AFont, AFontSize, R, G, B) (Komponenten von 0 bis 1)
AddTrueTypeFont + DrawTextTsgcPDFDocument.AddTrueTypeFont(AFontName, ABold, AItalic): Integer (oder AddTrueTypeFontFromFile), dann TsgcPDFPage.DrawTextTT
DrawLine, DrawBoxTsgcPDFPage.DrawLine(X1, Y1, X2, Y2, ALineWidth), DrawRectangle(X, Y, W, H, ALineWidth), DrawRectangleFill
AddImageFromFile + SelectImage + DrawImageTsgcPDFDocument.AddImage(AFileName): Integer + TsgcPDFPage.DrawImageFromIndex(AIndex, X, Y, W, H), oder DrawImageFile(AFileName, X, Y, W, H)
GetPageTextTsgcPDFDocument.ExtractTextW(APageIndex), ExtractText, FindText; TsgcPDFEditor.ExtractAllText, SearchText
AddToFileList + MergeFileListsgcPDFMergeFiles([...], AOutputFile)
MergeDocumentTsgcPDFDocument.AppendDocument(ADoc), TsgcPDFEditor.MergeFrom(AFileName)
ExtractPageRanges, ExtractFilePagessgcPDFExtractPages(AInputFile, AOutputFile, ARange) (1-basierte Bereichszeichenfolge wie '1,3,5-9'), TsgcPDFEditor.ExtractPages(ARange, AOutputFileName)
DeletePagesTsgcPDFDocument.DeletePages(ARange), DeletePage(AIndex)
RotatePageTsgcPDFEditor.RotatePage(AIndex, ADegrees)
SetTransparency + DrawText (Wasserzeichen)TsgcPDFEditor.AddWatermarkAllPages(TsgcPDFWatermarkOptions), AddWatermark, AddTransparentText
DrawText auf jeder Seite (Stempel, Kopfzeile, Fußzeile)TsgcPDFEditor.AddTextColor, AddHeaderText, AddFooterText, AddPageNumbers
RenderPageToDCTsgcPDFRendererGDI.RenderPage(ADC, ADocument.Parser, APage.PageDict, AWidth, AHeight); im VCL-Viewer TsgcPDFViewerControl.RenderPageToBitmap
RenderPageToFileTsgcPDFExporter.ExportPage(ADocument, APageIndex, AFileName) (BMP, PNG, JPEG), sgcPDFPageToImage(APDFFile, AImageFile, APageIndex, ADPI)
FormFieldCount, FindFormFieldByTitleTsgcPDFDocument.AcroForm.FieldCount, AcroForm.FindField(AName)
SetFormFieldValue, SetFormFieldValueByTitleAcroForm.FillField(AName, AValue), AcroForm.SetCheckBox(AName, AChecked), TsgcPDFEditor.FillFormField
GetFormFieldValueAcroForm.GetFieldValue(AName)
NewFormFieldAcroForm.AddTextField, AddCheckBox, AddComboBox, AddListBox, AddRadioGroup + AddRadioButton, AddButton, AddSignatureField
FlattenFormFieldAcroForm.FlattenFields, TsgcPDFEditor.FlattenForm
EncryptTsgcPDFDocument.SetEncryption(AMethod, AUserPassword, AOwnerPassword) mit emAES_256, emAES_128, emRC4_128 oder emRC4_40
CapturePageTsgcPDFDocument.AddPageAsForm(ASource, APageIndex): Integer (Überladungen mit einer Seitenbox, einem Rechteck oder Anmerkungen)
DrawCapturedPageTsgcPDFPage.DrawForm(AFormIndex, X, Y, AScaleX, AScaleY, ARotation), DrawFormInRect(AFormIndex, ATarget, AKeepAspect, ARotation), DrawFormMatrix
GetPageBoxTsgcPDFPage.GetPageBox(ABox) (ppbTrimBox, ppbBleedBox, ...), TsgcPDFDocument.GetFormBBox
NewOutlineTsgcPDFEditor.AddBookmark(ATitle, APageIndex), AddBookmarkChild
AddLinkToPageTsgcPDFEditor.AddLinkAnnotation(APageIndex, ALeft, ABottom, ARight, ATop, ADestPage)
AddNoteAnnotationTsgcPDFEditor.AddTextAnnotation(APageIndex, ALeft, ABottom, ARight, ATop, AText)
SignFileTsgcPDFEditor.SignDocument(AOutputFile, ACertSubjectName, AReason, ALocation)
PrintDocumentVCL-Viewer TsgcPDFViewerControl.Print(AFromPage, AToPage, ATitle) druckt ohne Dialog, PrintDialog(ATitle) zeigt den Druckerdialog (Seitenbereich, Kopien) und druckt. Der FireMonkey-Viewer TsgcPDFViewerFMX hat dieselben zwei Methoden unter Windows und macOS.
SetMeasurementUnits(0), SetOrigin(0)das Standard- und einzige Koordinatensystem: Punkte, Ursprung unten links; Hilfsfunktionen sgcPDFMMToPoints, sgcPDFRectMM

Ebenfalls in den Delphi-Viewern: Zoom auf Seitenhöhe (zmFitHeight bei TsgcPDFViewerControl, fzmFitHeight bei TsgcPDFViewerFMX, ZoomFitHeight bei TsgcPDFViewer) und Ansichtsdrehung (ViewRotation, RotateLeft, RotateRight), die die Ansicht dreht und das Dokument unverändert lässt.

Die gängigen Aufgaben von Quick PDF Library in sgcPDF

Jeder Ausschnitt stammt aus der Demo MigrateFromQuickPDF, die mit Delphi 7 (Win32) und Delphi 13 (Win32 und Win64) kompiliert und ihren Selbsttest besteht. Die Kommentare nennen die Aufrufe von Quick PDF Library, die jede Zeile ersetzt.

Die uses-Klausel

Die Importunit von Quick PDF Library und die DLL entfallen. Diese Units decken jede Aufgabe der Demo ab:

frmMain.pas
uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls, ExtCtrls, ShellAPI,
  // sgc
  sgcPDF_Types, sgcPDF_Fonts, sgcPDF_Document, sgcPDF_Encryption,
  sgcPDF_Editor, sgcPDF_Renderer_GDI;

Ein Dokument mit Text, Rechteck und Bild erstellen

Ersetzt NewDocument, SetInformation, AddStandardFont, SelectFont, SetTextSize, SetTextColor, DrawText, DrawBox, AddImageFromFile, SelectImage, DrawImage und SaveToFile.

frmMain.pas
oDoc := TsgcPDFDocument.Create;
try
  // SetInformation(1, ...) / SetInformation(2, ...)
  oDoc.Info.Title := 'Created with sgcPDF';
  oDoc.Info.Author := 'Migration sample';
  // NewDocument creates page 1, sgcPDF adds every page explicitly
  oPage := oDoc.AddPage(CS_A4_WIDTH, CS_A4_HEIGHT);
  // AddStandardFont(4) + SelectFont + SetTextSize(28) + DrawText
  oPage.DrawText('Hello from sgcPDF', 72, 760, sfHelveticaBold, 28);
  // SetTextColor(r, g, b) + DrawText
  oPage.DrawTextColor('No DLL, pure Pascal.', 72, 725, sfHelvetica, 14,
    0.1, 0.3, 0.7);
  // SetLineColor + SetLineWidth + DrawBox(x, y, w, h, 0)
  oPage.DrawRectangle(72, 520, 260, 120, 1.5);
  // AddImageFromFile + SelectImage + DrawImage(x, y, w, h)
  vImage := oDoc.AddImage(OutFile('logo.bmp'));
  oPage.DrawImageFromIndex(vImage, 102, 540, 200, 80);
  oDoc.SaveToFile(OutFile('created.pdf'));
finally
  oDoc.Free;
end;

Den Text einer Seite extrahieren

Ersetzt LoadFromFile, PageCount, SelectPage und GetPageText. Beachten Sie den 0-basierten Seitenindex.

frmMain.pas
oDoc.LoadFromFile(OutFile('input_a.pdf'));
Log('Extract text: input_a.pdf has ' + IntToStr(oDoc.PageCount) +
  ' pages');
// SelectPage(2) + GetPageText(0): sgcPDF page indexes are 0-based
vText := string(oDoc.ExtractTextW(1));
Log(vText);

Zusammenführen und teilen

Ersetzt AddToFileList mit MergeFileList sowie ExtractPageRanges oder ExtractFilePages. Bereichszeichenfolgen bleiben 1-basiert.

frmMain.pas
sgcPDFMergeFiles([OutFile('input_a.pdf'), OutFile('input_b.pdf')],
  OutFile('merged.pdf'));
frmMain.pas
// 1-based range string, the same syntax as Quick PDF Library
sgcPDFExtractPages(OutFile('merged.pdf'), OutFile('pages_2-3.pdf'), '2-3');
// one file per page: split
sgcPDFExtractPages(OutFile('merged.pdf'), OutFile('page_4.pdf'), '4');

Wasserzeichen und Stempel auf jeder Seite

Ersetzt SelectPage, SetTransparency, SetTextColor und DrawText in einer Schleife über die Seiten.

frmMain.pas
oEditor.LoadFromFile(OutFile('input_a.pdf'));
vOptions.Text := 'CONFIDENTIAL';
vOptions.Font := sfHelveticaBold;
vOptions.FontSize := 72;
vOptions.Rotation := 45;
vOptions.Opacity := 0.3;
vOptions.R := 0.8;
vOptions.G := 0.1;
vOptions.B := 0.1;
oEditor.AddWatermarkAllPages(vOptions);
// a stamp in the top right corner of every page
for i := 0 to oEditor.Document.PageCount - 1 do
  oEditor.AddTextColor(i, 'APPROVED', 440, 800, sfHelveticaBold, 16,
    0.0, 0.5, 0.0);
oEditor.SaveToFile(OutFile('watermarked.pdf'));

Eine Seite in einen Gerätekontext rendern

Ersetzt RenderPageToDC. Der Renderer übernimmt den Parser des geladenen Dokuments und das PageDict der Seite.

frmMain.pas
oDoc.LoadFromFile(OutFile('created.pdf'));
oPage := oDoc.Pages[0];
// 96 DPI: points are 1/72 inch
vScale := 96 / 72;
vW := Round(oPage.Width * vScale);
vH := Round(oPage.Height * vScale);
oBitmap.PixelFormat := pf24bit;
oBitmap.Width := vW;
oBitmap.Height := vH;
oBitmap.Canvas.Brush.Color := clWhite;
oBitmap.Canvas.FillRect(Rect(0, 0, vW, vH));
oRenderer.RenderPage(oBitmap.Canvas.Handle, oDoc.Parser, oPage.PageDict,
  vW, vH);
GdiFlush;
oBitmap.SaveToFile(OutFile('created_page1.bmp'));

Ein Formular ausfüllen

Ersetzt FormFieldCount, FindFormFieldByTitle und SetFormFieldValue.

frmMain.pas
oDoc.LoadFromFile(OutFile('form.pdf'));
Log('Fill form: form.pdf has ' + IntToStr(oDoc.AcroForm.FieldCount) +
  ' fields');
oDoc.AcroForm.FillField('Customer', 'ACME Corporation');
oDoc.AcroForm.FillField('Amount', '1250.00');
oDoc.AcroForm.SetCheckBox('Paid', True);
oDoc.SaveToFile(OutFile('form_filled.pdf'));

Mit AES-256 verschlüsseln und mit dem Passwort öffnen

Ersetzt Encrypt sowie LoadFromFile mit Passwort.

frmMain.pas
oDoc.LoadFromFile(OutFile('input_a.pdf'));
oDoc.SetEncryption(emAES_256, CS_USER_PASSWORD, CS_OWNER_PASSWORD);
oDoc.SaveToFile(OutFile('encrypted.pdf'));
frmMain.pas
oDoc.SetPassword(CS_USER_PASSWORD);
oDoc.LoadFromFile(OutFile('encrypted.pdf'));
vText := string(oDoc.ExtractTextW(0));

2-up-Imposition

Ersetzt CapturePage, NewPage, SetPageDimensions und DrawCapturedPage. AddPageAsForm behält jede Quellseite als Form-XObject, daher bleibt der Text vektorbasiert und auswählbar.

frmMain.pas
oSource.LoadFromFile(OutFile('merged.pdf'));
vHalf := CS_A4_HEIGHT / 2;
oSheet := nil;
for i := 0 to oSource.PageCount - 1 do
begin
  // a landscape A4 sheet for every 2 source pages
  if i mod 2 = 0 then
    oSheet := oTarget.AddPage(CS_A4_HEIGHT, CS_A4_WIDTH);
  // CapturePage
  vForm := oTarget.AddPageAsForm(oSource, i);
  // DrawCapturedPage, scaled to fit the left or the right half
  oSheet.DrawFormInRect(vForm, sgcPDFRect((i mod 2) * vHalf, 0,
    (i mod 2) * vHalf + vHalf, CS_A4_WIDTH), True);
end;
oTarget.SaveToFile(OutFile('imposed_2up.pdf'));

Klassen von PdfiumViewer in sgcPDF

Namespace esegece.sgcPDF, Paket esegece.sgcPDF.WinForms. Seitenindizes sind in beiden Bibliotheken 0-basiert.

PdfiumViewer sgcPDF .NET
PdfViewer (UserControl mit Symbolleiste und Lesezeichenbereich)TsgcPDFViewerControl; die Symbolleiste bauen Sie selbst, Lesezeichen in TsgcPDFOutlineView
PdfRenderer (PdfViewer.Renderer)dasselbe TsgcPDFViewerControl
PdfViewer.Document = PdfDocument.Load(path)TsgcPDFViewerControl.LoadFromFile(path) (der Viewer besitzt das Dokument), LoadFromStream, oder Document = vDoc (Sie geben es frei)
PdfDocument.Load(path, password)TsgcPDFDocument.SetPassword vor LoadFromFile, dann TsgcPDFViewerControl.Document = vDoc
PdfDocument.PageCountTsgcPDFViewerControl.PageCount (Eigenschaft), TsgcPDFDocument.PageCount() (Methode)
PdfDocument.PageSizesTsgcPDFDocument.GetPage(i).Width und .Height (Punkte)
PdfRenderer.PageTsgcPDFViewerControl.PageIndex, GotoPage, NextPage, PrevPage, FirstPage, LastPage, Ereignis OnPageChange
PdfViewerZoomMode.FitWidthZoomMode = TsgcPDFViewerZoomMode.zmFitWidth
PdfViewerZoomMode.FitHeightTsgcPDFViewerZoomMode.zmFitHeight
PdfViewerZoomMode.FitBestTsgcPDFViewerZoomMode.zmFitPage
Zoom (ein Faktor, 1.0 = 100 %)TsgcPDFViewerControl.Zoom (ein Prozentwert, 100 = 100 %, setzt zmCustom), ZoomIn, ZoomOut, zmActualSize, ZoomToRect
PdfRenderer.RotateLeft(), RotateRight()TsgcPDFViewerControl.RotateLeft(), RotateRight()
PdfRenderer.RotationTsgcPDFViewerControl.ViewRotation (TsgcPDFViewerRotation: pvr0, pvr90, pvr180, pvr270); PageRotation(i) liefert die angezeigte Drehung
PdfDocument.Search(text, matchCase, wholeWord) + PdfRenderer.MarkersTsgcPDFViewerControl.FindText(AText, ACaseSensitive, AWholeWord) (hebt hervor und scrollt), FindNext, FindPrevious, SearchResults, GetSearchMatch(i), ClearSearch
PdfDocument.CreatePrintDocument() + PrintDialog oder PrintPreviewDialogTsgcPDFViewerControl.CreatePrintDocument() liefert ein System.Drawing.Printing.PrintDocument für denselben PrintDialog und PrintPreviewDialog-Code. In einem Aufruf: PrintDialog(ATitle); ohne Dialog: Print(AFromPage, AToPage, ATitle)
PdfDocument.Render(page, dpiX, dpiY, forPrinting)TsgcPDFViewerControl.RenderPageToBitmap(APageIndex, ref Bitmap, AZoomPercent, ADPI); ohne Viewer sgcPDF_Export.sgcPDFPageToImage or TsgcPDFExporter.ExportPage
PdfDocument.GetPdfText(page)TsgcPDFDocument.ExtractTextW(APageIndex); mit Zeichenpositionen TsgcPDFViewerControl.PageText(i); Auswahl mit der Maus SelectedText, CopyToClipboard
PdfDocument.BookmarksTsgcPDFOutlineView
PdfViewer.LinkClickTsgcPDFViewerControl.OnLinkClick, OpenLinksInBrowser
PdfDocument.Save(path)TsgcPDFDocument.SaveToFile, SaveIncremental(AFileName) (behält die Originalbytes und hängt die Änderungen an)
keine Entsprechung: Formulare ausfüllenTsgcPDFViewerControl.FormFilling = true, OnFieldChange; im Code AcroForm.FillField, SetCheckBox, GetFieldValue, FindField
keine Entsprechung: AnmerkungenTsgcPDFDocument.Annotations.AddText, AddFreeText, AddHighlight, AddStamp, AddLine, AddSquare, AddCircle, dann AnnotationsChanged(); mit der Maus AnnotationTool und AnnotationEditing
keine Entsprechung: ein PDF erstellenTsgcPDFDocument.AddPage, TsgcPDFPage.DrawText, DrawRectangle, AcroForm.AddTextField, AddCheckBox, SaveToFile

Ein PdfiumViewer-Formular mit dem sgcPDF-Viewer

Jeder Ausschnitt stammt aus der Demo MigrateFromPdfiumViewer, die im Release-Modus kompiliert und ihren Selbsttest besteht. Die Kommentare zitieren den PdfiumViewer-Code, den jeder Block ersetzt.

Ein Steuerelement statt PdfViewer und PdfRenderer

MainForm.cs
// PdfiumViewer: PdfViewer (UserControl with toolbar) and its PdfRenderer (the page
// surface, PdfViewer.Renderer) -> one control, TsgcPDFViewerControl
private TsgcPDFViewerControl FViewer;
MainForm.cs
FViewer = new TsgcPDFViewerControl();
FViewer.Parent = pnlViewer;
FViewer.Dock = DockStyle.Fill;
// PdfiumViewer: PdfRenderer.DisplayRectangleChanged / polling PdfRenderer.Page -> OnPageChange
FViewer.OnPageChange = DoPageChange;
// PdfiumViewer: none, PdfiumViewer renders form fields but cannot edit them.
// sgcPDF: the user types into text fields and toggles check boxes in the viewer
FViewer.FormFilling = true;
FViewer.OnFieldChange = DoFieldChange;
// PdfiumViewer: none. sgcPDF: AnnotationTool adds notes, highlights, shapes, ink
// and stamps with the mouse; AnnotationEditing moves, resizes and deletes them
FViewer.AnnotationAuthor = "sgcPDF demo";

Eine Datei öffnen

MainForm.cs
// PdfiumViewer: pdfViewer1.Document = PdfDocument.Load(AFileName)
// sgcPDF: the viewer loads and owns the document; to share a document you load
// yourself, assign it: FViewer.Document = vDoc (you dispose it)
FViewer.LoadFromFile(AFileName);
// PdfiumViewer: PdfViewer.ZoomMode = PdfViewerZoomMode.FitWidth
FViewer.ZoomMode = TsgcPDFViewerZoomMode.zmFitWidth;
// PdfiumViewer: PdfDocument.PageCount -> TsgcPDFViewerControl.PageCount
// (or TsgcPDFDocument.PageCount(), a method)
Log("Opened " + Path.GetFileName(AFileName) + ", " + sgcPDF_RTL.IntToStr(FViewer.PageCount) + " pages");

Zoommodi und Ansichtsdrehung

Seitenbreite, Seite und Seitenhöhe lassen sich eins zu eins zuordnen. Der Zoom ist ein Prozentwert statt eines Faktors.

MainForm.cs
internal void FitWidth()
{
    // PdfiumViewer: PdfViewerZoomMode.FitWidth -> TsgcPDFViewerZoomMode.zmFitWidth
    FViewer.ZoomMode = TsgcPDFViewerZoomMode.zmFitWidth;
}

internal void FitPage()
{
    // PdfiumViewer: PdfViewerZoomMode.FitBest -> TsgcPDFViewerZoomMode.zmFitPage
    FViewer.ZoomMode = TsgcPDFViewerZoomMode.zmFitPage;
}

internal void FitHeight()
{
    // PdfiumViewer: PdfViewerZoomMode.FitHeight -> TsgcPDFViewerZoomMode.zmFitHeight
    FViewer.ZoomMode = TsgcPDFViewerZoomMode.zmFitHeight;
}

internal void RotateLeft()
{
    // PdfiumViewer: PdfRenderer.RotateLeft() -> TsgcPDFViewerControl.RotateLeft()
    // (ViewRotation turns the view only, the document is not changed)
    FViewer.RotateLeft();
}

internal void RotateRight()
{
    // PdfiumViewer: PdfRenderer.RotateRight() -> TsgcPDFViewerControl.RotateRight()
    FViewer.RotateRight();
}

internal void SetZoomPercent(double APercent)
{
    // PdfiumViewer: PdfRenderer.Zoom is a factor (1.0 = 100%);
    // TsgcPDFViewerControl.Zoom is a percentage (100 = 100%) and sets ZoomMode to zmCustom
    FViewer.Zoom = APercent;
}

Suchen

MainForm.cs
// PdfiumViewer: PdfDocument.Search(text, matchCase, wholeWord) returns PdfMatches
// and the app adds PdfMarker objects to PdfRenderer.Markers to highlight them.
// sgcPDF: FindText highlights every match and scrolls to the first one,
// FindNext / FindPrevious move between them, GetSearchMatch(i) gives page and chars
if (!FViewer.FindText(AText, false, false))
{
    Log("Not found: " + AText);
    return 0;
}
for (int i = 0; i < FViewer.SearchResults; i++)
{
    TsgcPDFViewerSearchMatch vMatch = FViewer.GetSearchMatch(i);
    Log("Match " + sgcPDF_RTL.IntToStr(i + 1) + ": page " + sgcPDF_RTL.IntToStr(vMatch.PageIndex + 1) +
      ", char " + sgcPDF_RTL.IntToStr(vMatch.FirstChar));
}
return FViewer.SearchResults;

Drucken mit CreatePrintDocument

Der Druckcode von PdfiumViewer behält seine Form: CreatePrintDocument() liefert ein PrintDocument für einen PrintDialog oder einen PrintPreviewDialog.

MainForm.cs
// PdfiumViewer: using (PrintDocument d = PdfDocument.CreatePrintDocument())
//   { PrintDialog dlg = new PrintDialog(); dlg.Document = d; if (dlg.ShowDialog() == OK) d.Print(); }
// sgcPDF: TsgcPDFViewerControl.CreatePrintDocument() returns the same kind of
// System.Drawing.Printing.PrintDocument, so the PdfiumViewer code stays as it is. It honours
// the page range (all, some pages, current page), copies and collate of its PrinterSettings.
// A shorter way: FViewer.PrintDialog(title) shows the dialog and prints in one call, and
// FViewer.Print(from, to, title) prints without a dialog (0-based pages, -1 = last page).
if (FViewer.PageCount == 0)
    return;
using (PrintDocument vDoc = FViewer.CreatePrintDocument())
using (PrintDialog vDialog = new PrintDialog())
{
    vDoc.DocumentName = "PdfiumViewer migration sample";
    vDialog.Document = vDoc;
    vDialog.AllowSomePages = true;
    vDialog.AllowCurrentPage = true;
    vDialog.UseEXDialog = true;
    vDoc.PrinterSettings.MinimumPage = 1;
    vDoc.PrinterSettings.MaximumPage = FViewer.PageCount;
    vDoc.PrinterSettings.FromPage = 1;
    vDoc.PrinterSettings.ToPage = FViewer.PageCount;
    if (vDialog.ShowDialog(this) == DialogResult.OK)
        vDoc.Print();
}
MainForm.cs
// PdfiumViewer: PrintPreviewDialog with PdfDocument.CreatePrintDocument()
// sgcPDF: the same with TsgcPDFViewerControl.CreatePrintDocument()
if (FViewer.PageCount == 0)
    return;
using (PrintDocument vDoc = FViewer.CreatePrintDocument())
using (PrintPreviewDialog vPreview = new PrintPreviewDialog())
{
    vPreview.Document = vDoc;
    vPreview.Width = 900;
    vPreview.Height = 700;
    vPreview.ShowDialog(this);
}

Eine Seite in eine Bitmap rendern

MainForm.cs
// PdfiumViewer: Image img = PdfDocument.Render(page, dpiX, dpiY, forPrinting)
// sgcPDF: RenderPageToBitmap(page, ref bitmap, zoomPercent, dpi); the bitmap passed
// in is disposed and replaced
Bitmap vBitmap = null;
FViewer.RenderPageToBitmap(APageIndex, ref vBitmap, 100, 150);
try
{
    vBitmap.Save(AFileName, ImageFormat.Png);
    Log("Page " + sgcPDF_RTL.IntToStr(APageIndex + 1) + " rendered at 150 dpi: " +
      sgcPDF_RTL.IntToStr(vBitmap.Width) + " x " + sgcPDF_RTL.IntToStr(vBitmap.Height) + " px, " +
      AFileName);
}
finally
{
    vBitmap.Dispose();
}
// without a viewer (server, batch): one call from file to image
sgcPDF_Export.sgcPDFPageToImage(FViewer.FileName, Path.ChangeExtension(AFileName, null) + "_file.png",
  APageIndex, 72);

Seitentext

MainForm.cs
// PdfiumViewer: PdfDocument.GetPdfText(page) returns the plain text of a page.
// sgcPDF: TsgcPDFDocument.ExtractTextW(page) is the same plain text, and
// TsgcPDFViewerControl.PageText(page) returns a TsgcPDFTextExtractor with the
// characters and their positions (GetTextWithPositions); the user can also select
// text with the mouse and copy it (SelectedText, CopyToClipboard)
string vText = FViewer.Document.ExtractTextW(APageIndex);
Log("Text of page " + sgcPDF_RTL.IntToStr(APageIndex + 1) + ": " + vText.Trim());
TsgcPDFTextExtractor vExtractor = FViewer.PageText(APageIndex);
if (vExtractor != null)
    Log("Characters with positions: " + sgcPDF_RTL.IntToStr(vExtractor.GetCharCount()));
return vText;

Über PdfiumViewer hinaus: ein Formular ausfüllen und eine Notiz hinzufügen

MainForm.cs
// PdfiumViewer: none (no AcroForm API). sgcPDF: AcroForm.FillField / SetCheckBox,
// then an incremental save keeps the original bytes and appends the change
TsgcPDFDocument vDoc = FViewer.Document;
if (vDoc.AcroForm.FindField("CustomerName") == null)
{
    Log("This document has no CustomerName field, open the generated sample");
    return;
}
vDoc.AcroForm.FillField("CustomerName", "ACME Ltd.");
vDoc.AcroForm.SetCheckBox("Approved", true);
FViewer.ClearCache();
FViewer.Invalidate();
vDoc.SaveIncremental(AFileName);
Log("Form filled and saved: " + AFileName);
MainForm.cs
// PdfiumViewer: none (annotations are only rendered). sgcPDF: the document's
// Annotations manager adds notes, free text, highlights, stamps, lines, shapes and
// ink; the viewer shows them after AnnotationsChanged
TsgcPDFDocument vDoc = FViewer.Document;
int vPage = FViewer.PageIndex;
TsgcPDFTextAnnotation vNote = vDoc.Annotations.AddText(vPage, 420, 760, 444, 784,
  "Migrated from PdfiumViewer to sgcPDF.");
vNote.Author = "sgcPDF demo";
vNote.SetColor(1.0, 0.9, 0.2);
vDoc.Annotations.AddHighlight(vPage, 72, 728, 330, 728, 72, 742, 330, 742);
FViewer.AnnotationsChanged();
vDoc.SaveIncremental(AFileName);
Log("Note and highlight added on page " + sgcPDF_RTL.IntToStr(vPage + 1) + ", saved: " + AFileName);

Schritt für Schritt

Portieren Sie jeweils eine Aufgabe oder ein Formular und vergleichen Sie die Ausgabedateien vorher und nachher.

Delphi: von Quick PDF Library

1

Units hinzufügen

Fügen Sie den Source-Ordner von sgcPDF oder das installierte Paket hinzu und ersetzen Sie den Import von Quick PDF Library durch sgcPDF_Types, sgcPDF_Fonts und sgcPDF_Document, dazu bei Bedarf sgcPDF_Editor, sgcPDF_Encryption und sgcPDF_Renderer_GDI.

2

DLL entfernen

Entfernen Sie die DLL oder das ActiveX aus der Auslieferung und den Aufruf von UnlockKey aus dem Code.

3

Ein Objekt pro Dokument

Ersetzen Sie das Objekt TQuickPDF durch ein TsgcPDFDocument pro Dokument oder ein TsgcPDFEditor für Aufgaben aus Laden, Bearbeiten und Speichern.

4

Seiten sind Objekte

Ersetzen Sie SelectPage und die Zeichenaufrufe durch Aufrufe auf dem TsgcPDFPage aus AddPage oder Pages[i], und ziehen Sie von jeder Seitenzahl 1 ab.

5

Aufrufe zuordnen

Verwenden Sie die Tabelle oben. Standardschriften sind ein Argument von DrawText; TrueType-Schriften werden einmal mit AddTrueTypeFont hinzugefügt und mit DrawTextTT gezeichnet.

6

Imposition

Ersetzen Sie CapturePage und DrawCapturedPage durch AddPageAsForm und DrawForm oder DrawFormInRect.

7

Ausgabe vergleichen

Führen Sie die umgestellte Aufgabe aus und prüfen Sie die Dateien. Der Selbsttest der Demo dient als Vorlage: Er öffnet jede Ausgabe erneut und prüft Seitenzahlen, Text und Formularwerte.

WinForms: von PdfiumViewer

1

Native Teile entfernen

Entfernen Sie das PdfiumViewer-Paket, jedes PdfiumViewer.Native.*-Paket und jede von Hand kopierte pdfium.dll, einschließlich der Ordner x86 und x64. Das Projekt kann zu AnyCPU zurückkehren.

2

sgcPDF hinzufügen

Fügen Sie esegece.sgcPDF.WinForms (oder esegece.sgcPDF.WinForms.Community) hinzu, das esegece.sgcPDF mitbringt, und ergänzen Sie using esegece.sgcPDF;.

3

Steuerelement austauschen

Ersetzen Sie PdfViewer oder PdfRenderer durch ein TsgcPDFViewerControl (Dock = Fill) und bauen Sie die verwendeten Symbolleistenschaltflächen als Aufrufe auf dem Steuerelement neu auf.

4

Dokument laden

Ersetzen Sie PdfDocument.Load und Document = durch LoadFromFile, oder laden Sie selbst ein TsgcPDFDocument und weisen Sie es Document zu.

5

Mitglieder zuordnen

Page wird zu PageIndex oder GotoPage, die Zoommodi werden auf TsgcPDFViewerZoomMode abgebildet, der Zoomfaktor wird mit 100 multipliziert, Search wird zu FindText, Render wird zu RenderPageToBitmap.

6

Druckcode beibehalten

Rufen Sie CreatePrintDocument() auf dem Viewer statt auf dem PdfiumViewer-Dokument auf; der Code mit PrintDialog und PrintPreviewDialog bleibt. Oder verwenden Sie PrintDialog(ATitle).

7

Neue Möglichkeiten aktivieren

Optional: FormFilling = true, AnnotationTool und SaveIncremental, was PdfiumViewer nicht bieten konnte.

Was sich nicht eins zu eins zuordnen lässt

Lesen Sie dies, bevor Sie den Umstieg planen.

Quick PDF Library

PdfiumViewer

MigrateFromQuickPDF und MigrateFromPdfiumViewer

Beide Demos erzeugen ihre eigenen Eingabedateien, daher wird keine externe PDF-Datei benötigt, und beide haben einen Selbsttest.

Delphi: Fundort

Der sgcUI-Installer legt sie unter Demos\PDF\Delphi\MigrateFromQuickPDF ab: sgcPDF_Demo_MigrateFromQuickPDF.dpr, frmMain.pas, frmMain.dfm und eine readme.html.

Delphi: So starten Sie sie

Öffnen Sie die Datei .dpr in einem beliebigen Delphi von 7 bis 13 (VCL, Win32 oder Win64), klicken Sie auf Generate sample inputs, dann auf eine beliebige Schaltfläche oder auf Run all. Die Ausgabe landet im Ordner output neben der Exe.

Delphi: Selbsttest

sgcPDF_Demo_MigrateFromQuickPDF.exe /selftest [folder] führt jede Aufgabe aus, prüft die Ergebnisse und schreibt selftest.log, die mit SELFTEST OK endet.

.NET: Fundort

In den sgcUI-.NET-Demos, Ordner PDF\MigrateFromPdfiumViewer der Projektmappe sgcUI_Demos.sln: sgcPDF_Demo_MigrateFromPdfiumViewer.csproj, Program.cs und MainForm.cs.

.NET: So starten Sie sie

dotnet run --project demos\PDF\MigrateFromPdfiumViewer (fügen Sie -p:SgcCommunity=true für die Community Edition hinzu), klicken Sie auf Generate sample, das output\sample.pdf schreibt und öffnet, dann auf eine beliebige Schaltfläche.

.NET: Selbsttest

sgcPDF_Demo_MigrateFromPdfiumViewer.exe /selftest [folder] öffnet das Beispiel, navigiert, zoomt, passt die Höhe an, dreht, durchsucht, rendert, zählt die Seiten einer Druckvorschau, extrahiert Text, füllt das Formular, fügt eine Notiz hinzu und öffnet die gespeicherten Dateien erneut. Es schreibt selftest.log, das mit SELFTEST OK endet.

Fairerweise gegenüber beiden Bibliotheken: Eine Anwendung auf Basis von Quick PDF Library oder PdfiumViewer läuft dort, wo sie heute ausgeliefert ist, weiter, und Foxit nennt seine eigenen PDF-SDKs als Nachfolger von Quick PDF Library. sgcPDF ist der Weg, wenn Sie den PDF-Code in Pascal- oder C#-Quellcode haben möchten, der in Ihre Anwendung kompiliert wird, ohne native PDF-Bibliothek auszuliefern, und mit einer API, die auch die Dateien erstellt, ausfüllt, mit Anmerkungen versieht, signiert und verschlüsselt, die Ihr Viewer anzeigt. Zu den Komponenten und Editionen siehe die sgcPDF-Produktseite.

Bestes Preis-Leistungs-Verhältnis: All-AccessAlle eSeGeCe-Produkte, inklusive Premium-Support, ab €1,059 pro Jahr.
All-Access-Preise ansehen

Portieren Sie noch heute Ihre erste PDF-Aufgabe

Laden Sie sgcUI mit sgcPDF herunter oder fügen Sie die kostenlosen Community-Pakete von NuGet hinzu und portieren Sie Ihre erste Aufgabe oder Ihr erstes Formular mit den Demos MigrateFromQuickPDF und MigrateFromPdfiumViewer daneben.