Exis.PdfEditor logo

SDK trova e sostituisci testo nei PDF per .NET

Trova e sostituisci testo nei file PDF programmaticamente con C#. Modifica diretta dei content stream — senza conversione in DOCX, senza dipendenze esterne, senza perdita di dati.

.NET CLI dotnet add package Exis.PdfEditor

PM Console Install-Package Exis.PdfEditor

Perché Exis.PdfEditor

Come funzionano le altre librerie

La maggior parte delle librerie PDF .NET — IronPDF, Spire.PDF, Aspose, Syncfusion — sostituiscono il testo convertendo il PDF in un formato intermedio, oscurando il testo e disegnando nuovo testo sopra, o ricostruendo le pagine da zero.

Questo approccio danneggia:

  • Campi modulo e caselle di controllo
  • Firme digitali
  • Spaziatura e crenatura del testo
  • Layout e posizionamento della pagina
  • Segnalibri e destinazioni dei link

Come funziona Exis.PdfEditor

Exis.PdfEditor analizza i content stream PDF direttamente a livello di byte. Localizza il testo negli operatori PDF reali, modifica solo gli operandi stringa mirati e scrive utilizzando l'aggiornamento incrementale PDF.

Tutto ciò che non viene toccato rimane identico byte per byte:

  • Campi modulo e AcroForms: intatti
  • Firme digitali sulle pagine non modificate: preservate
  • Spaziatura e crenatura del testo: preservate
  • Layout e struttura della pagina: preservati
  • Segnalibri, annotazioni, file incorporati: preservati

Altre librerie

PDF
Convertire in formato intermedio
Modificare
Riconvertire in PDF
Output (danneggiato)

Exis.PdfEditor

PDF
Analizzare i content stream
Sostituire operandi di testo
Aggiornamento incrementale
Output (identico tranne il testo sostituito)

Code Samples

Sostituire testo in un PDF — 3 righe di codice

using Exis.PdfEditor;
using Exis.PdfEditor.Licensing;

ExisLicense.Initialize();  // Free 14-day trial - no key needed

var result = PdfFindReplace.Execute(
    "contract.pdf",
    "contract-updated.pdf",
    "Acme Corporation",
    "Globex Industries");

Console.WriteLine($"Replaced {result.TotalReplacements} occurrences " +
                  $"across {result.PagesModified} pages.");

Sostituzioni multiple in un singolo passaggio

var pairs = new[]
{
    new FindReplacePair("2025", "2026"),
    new FindReplacePair("Draft", "Final"),
    new FindReplacePair("CONFIDENTIAL", "PUBLIC"),
};

var result = PdfFindReplace.Execute(
    "report.pdf",
    "report-final.pdf",
    pairs);

Sostituzione basata su pattern con espressioni regolari

var options = new PdfFindReplaceOptions { UseRegex = true };

// Replace all US phone numbers with a placeholder
var result = PdfFindReplace.Execute(
    "document.pdf",
    "redacted.pdf",
    @"\(\d{3}\)\s?\d{3}-\d{4}",
    "[PHONE REDACTED]",
    options);

Attivare il tuo abbonamento

// Purchase at officefindreplace.com/Home/pdf-find-replace-csharp - $499/developer/year
ExisLicense.Initialize("XXXX-XXXX-XXXX-XXXX");

// Unlimited pages, no restrictions, no console messages
var result = PdfFindReplace.Execute("large-doc.pdf", "output.pdf", "old", "new");

Text Fitting Options

var options = new PdfFindReplaceOptions
{
    CaseSensitive = true,
    WholeWordOnly = false,
    UseRegex = false,
    UseIncrementalUpdate = true,
    TextFitting = TextFittingMode.Adaptive,  // Best quality text fitting
    MinHorizontalScale = 70,                 // Minimum Tz percentage (50-100)
    MaxFontSizeReduction = 1.5               // Max font size reduction in points
};

var result = PdfFindReplace.Execute(
    "contract.pdf", "updated.pdf",
    "Short Name", "A Much Longer Replacement Name That Needs Fitting",
    options);

Font Color & Highlight

// Color replacement text and add a highlight background
var result = PdfFindReplace.Execute(
    "input.pdf", "output.pdf",
    "old text", "new text",
    new PdfFindReplaceOptions
    {
        ReplacementTextColor = PdfColor.Red,         // Font color of replaced text
        ReplacementHighlightColor = PdfColor.Yellow   // Background highlight behind text
    });

Merge PDFs

// Merge multiple PDFs into one, preserving page dimensions and resources
byte[] merged = PdfMerger.Merge(new[] { "cover.pdf", "report.pdf", "appendix.pdf" });
File.WriteAllBytes("combined.pdf", merged);

// Or write directly to a file
PdfMerger.MergeToFile(new[] { "file1.pdf", "file2.pdf" }, "merged.pdf");

// Merge with page range selection
byte[] selected = PdfMerger.Merge(new[]
{
    new PdfMergeInput(File.ReadAllBytes("doc1.pdf"), new[] { 1, 3, 5 }),
    new PdfMergeInput(File.ReadAllBytes("doc2.pdf"))  // all pages
});

Split PDFs

// Split into individual pages
List<byte[]> pages = PdfSplitter.Split("input.pdf");

// Extract specific pages (1-based)
byte[] subset = PdfSplitter.ExtractPages("input.pdf", new[] { 1, 3, 5 });

// Split to individual files with naming pattern
PdfSplitter.SplitToFiles("input.pdf", "page_{0}.pdf");

Build PDFs from Scratch

byte[] pdf = PdfBuilder.Create()
    .WithMetadata(m => m.Title("Report").Author("Exis"))
    .AddPage(page => page
        .Size(PdfPageSize.A4)
        .AddText("Hello, World!", x: 72, y: 750, fontSize: 24,
            options: o => o.Font("Helvetica").Bold().Color(0, 0, 0.8))
        .AddText("Generated with Exis.PdfEditor", x: 72, y: 720, fontSize: 12)
        .AddLine(72, 710, 523, 710, strokeWidth: 1)
        .AddRectangle(72, 600, 200, 80, fill: true,
            fillRed: 0.95, fillGreen: 0.95, fillBlue: 1.0)
        .AddImage(jpegBytes, x: 300, y: 400, width: 200, height: 150))
    .AddPage(page => page
        .Size(PdfPageSize.Letter)
        .AddText("Page 2", x: 72, y: 700, fontSize: 14))
    .Build();

File.WriteAllBytes("output.pdf", pdf);

Extract Text

// Extract all text from a PDF
PdfTextResult text = PdfTextExtractor.ExtractText("input.pdf");
Console.WriteLine(text.FullText);

// Extract from specific pages only
PdfTextResult partial = PdfTextExtractor.ExtractText("input.pdf", new[] { 1, 3 });

// Structured extraction with position and font data
PdfStructuredTextResult structured = PdfTextExtractor.ExtractStructured("input.pdf");
foreach (var block in structured.Pages[0].TextBlocks)
    Console.WriteLine($"[{block.X:F0},{block.Y:F0}] {block.Text} " +
        $"(font={block.FontName}, size={block.FontSize})");

Inspect Document (No License Required)

PdfDocumentInfo info = PdfInspector.Inspect("input.pdf");

Console.WriteLine($"Pages: {info.PageCount}");
Console.WriteLine($"Title: {info.Title}");
Console.WriteLine($"Fonts: {string.Join(", ", info.FontsUsed)}");
Console.WriteLine($"Encrypted: {info.IsEncrypted}");
Console.WriteLine($"Form fields: {info.FormFieldCount}");

Image Replacement

// Find all images in a PDF
var found = PdfImageEditor.FindImages("input.pdf");
foreach (var img in found.Images)
    Console.WriteLine($"Image #{img.Index}: {img.PixelWidth}x{img.PixelHeight} " +
        $"{img.ColorSpace} {img.Format} on page(s) {string.Join(", ", img.PageNumbers)}");

// Replace all images with a new one
byte[] newLogo = File.ReadAllBytes("new-logo.jpg");
var result = PdfImageEditor.ReplaceAll("input.pdf", "output.pdf", newLogo);
Console.WriteLine($"Replaced {result.ImagesReplaced} of {result.ImagesFound} images");

// Replace specific images by index or page range
var selective = PdfImageEditor.Replace("input.pdf", "output.pdf", newLogo,
    new PdfImageReplaceOptions { ImageIndices = new[] { 0, 2 } });

Auto-Layout Document Builder

byte[] pdf = PdfDocumentBuilder.Create()
    .PageSize(PdfPageSize.A4)
    .Margins(72)
    .WithMetadata(m => m.Title("Report").Author("Exis"))
    .Header(h => h
        .AddText("Quarterly Report", PdfHorizontalAlignment.Center, 12, o => o.Bold())
        .AddLine())
    .Footer(f => f
        .AddLine()
        .AddPageNumber())  // "Page 1 of 3"
    .AddParagraph("Introduction", 18, o => o.Bold())
    .AddSpacing(8)
    .AddParagraph("This report covers Q1 results.")
    .AddSpacing(12)
    .AddTable(t => t
        .Columns(2, 1, 1)
        .AlternatingRowBackground(0.95, 0.95, 1.0)
        .HeaderRow(r => r.AddCell("Product").AddCell("Units").AddCell("Revenue"))
        .AddRow(r => r.AddCell("Widget A").AddCell("1,200").AddCell("$24,000"))
        .AddRow(r => r.AddCell("Widget B").AddCell("850").AddCell("$17,000")))
    .AddPageBreak()
    .AddParagraph("Appendix", 14, o => o.Bold())
    .Build();

Form Filling

// Read form fields
List<PdfFormField> fields = PdfFormFiller.GetFields("form.pdf");
foreach (var field in fields)
    Console.WriteLine($"{field.Name} ({field.FieldType}) = {field.CurrentValue}");

// Fill fields
var result = PdfFormFiller.Fill("form.pdf", "filled.pdf", new Dictionary<string, string>
{
    { "FirstName", "John" },
    { "LastName", "Doe" },
    { "State", "CA" },
    { "AgreeToTerms", "Yes" }  // checkbox
});
Console.WriteLine($"Filled {result.FieldsFilled} fields");

// Flatten form (merge field appearances, remove interactive fields)
PdfFormFiller.Flatten("filled.pdf", "flattened.pdf");

Redaction

var result = PdfRedactor.Redact("input.pdf", "redacted.pdf", new[]
{
    // Text-based redaction
    new PdfRedaction { Text = "CONFIDENTIAL" },

    // Regex pattern (e.g., SSN)
    new PdfRedaction { Text = @"\d{3}-\d{2}-\d{4}", IsRegex = true },

    // Replace with alternative text
    new PdfRedaction { Text = "SECRET", ReplaceWith = "[REDACTED]" },

    // Area-based redaction on specific page
    new PdfRedaction { PageNumber = 3, Area = new PdfRect(100, 200, 300, 50) }
});
Console.WriteLine($"Applied {result.RedactionsApplied} redactions");

Optimization

var result = PdfOptimizer.Optimize("input.pdf", "optimized.pdf", new PdfOptimizeOptions
{
    CompressStreams = true,
    RemoveDuplicateObjects = true,
    RemoveMetadata = false,
    DownsampleImages = true,
    MaxImageDpi = 150
});
Console.WriteLine($"Saved {result.BytesSaved} bytes ({result.ReductionPercent:F1}%)");
Console.WriteLine($"Images downsampled: {result.ImagesDownsampled}");

Digital Signatures (.NET 8, 9, 10+)

using System.Security.Cryptography.X509Certificates;

// Sign a PDF
var cert = new X509Certificate2("certificate.pfx", "password");
PdfSigner.Sign("input.pdf", "signed.pdf", new PdfSignOptions
{
    Certificate = cert,
    Reason = "Approved",
    Location = "New York",
    ContactInfo = "admin@example.com"
});

// Verify a signed PDF
PdfSignatureInfo info = PdfSigner.Verify("signed.pdf");
Console.WriteLine($"Signed: {info.IsSigned}");
Console.WriteLine($"Valid: {info.IsValid}");
Console.WriteLine($"Signer: {info.SignerName}");
Console.WriteLine($"Certificate: {info.CertificateSubject}");
Console.WriteLine($"Issuer: {info.CertificateIssuer}");
Console.WriteLine($"Timestamp: {info.HasTimestamp}");

// Verify all signatures in a multi-signed document
List<PdfSignatureInfo> all = PdfSigner.VerifyAll("multi-signed.pdf");
foreach (var sig in all)
    Console.WriteLine($"{sig.SignerName}: valid={sig.IsValid}");

PDF/A Compliance

// Validate (no license required)
// Levels: PdfA1b, PdfA2b, PdfA2u, PdfA3b, PdfA3u
PdfAValidationResult result = PdfAConverter.Validate("input.pdf", PdfALevel.PdfA2b);
Console.WriteLine($"Compliant: {result.IsCompliant}");
foreach (var v in result.Violations)
    Console.WriteLine($"  [{v.Code}] {v.Message} (auto-fix: {v.CanAutoFix})");

// Convert to PDF/A
byte[] pdfa = PdfAConverter.Convert("input.pdf", PdfALevel.PdfA2b);
File.WriteAllBytes("output-pdfa.pdf", pdfa);

Async API

// All I/O operations have async overloads with CancellationToken support
byte[] merged = await PdfMerger.MergeAsync(inputPaths, cancellationToken);
PdfTextResult text = await PdfTextExtractor.ExtractTextAsync(stream, cancellationToken);
var info = await PdfInspector.InspectAsync(path, cancellationToken);
var result = await PdfOptimizer.OptimizeAsync(data, options, cancellationToken);
var sigs = await PdfSigner.VerifyAllAsync(path, cancellationToken);

// Pattern: ClassName.MethodNameAsync(...) on all classes

Come si confronta Exis.PdfEditor

Funzionalità Exis.PdfEditor IronPDF Spire.PDF Aspose.PDF Syncfusion
Modifica diretta dei content stream Rendering HTML Sovrapposizione di oscuramento Sostituzione per frammento Sovrapposizione di oscuramento
Preserva i campi modulo Parziale Parziale
Preserva le firme digitali Pagine non modificate
Preserva spaziatura/crenatura del testo Parziale
Zero dipendenze native .NET puro Motore Chromium
Dimensione DLL < 500 KB ~250 MB ~20 MB ~40 MB ~15 MB
Sostituzione batch multi-coppia Singolo passaggio Loop manuale Loop manuale Loop manuale Loop manuale
.NET Framework 4.8 Solo .NET 6+
Multipiattaforma
Supporto regex
Prezzo (per sviluppatore/anno) $499 $749 $999 $1,175 $995*
Sede centrale 🇺🇸 USA 🇺🇸 USA 🇨🇳 China 🇦🇺 Australia 🇺🇸 USA

Confronto basato sulla documentazione pubblicamente disponibile di febbraio 2026. Il supporto delle funzionalità può variare per versione.
"Modifica diretta dei content stream" significa che la libreria modifica gli operatori di testo PDF sul posto senza convertire, ri-renderizzare o sovrapporre.

Funzionalità

Modifica diretta dei PDF

Modifica gli operatori dei content stream. Nessuna conversione intermedia.

Zero dipendenze

Nessun Ghostscript, nessun LibreOffice, nessun Chromium. .NET gestito puro.

Output senza perdite

Moduli, firme, annotazioni, segnalibri — tutto preservato.

Multi-target

.NET 8, 9, 10+ e .NET Standard 2.0 (.NET Framework 4.6.1+, .NET Core 2.0+, .NET 5-7).

Elaborazione batch

Coppie multiple trova/sostituisci eseguite in un singolo passaggio.

Espressioni regolari

Supporto completo regex .NET per sostituzioni basate su pattern.

Multipiattaforma

Windows, Linux, macOS. Ovunque .NET funzioni.

Impronta ridotta

Singola DLL, sotto 500 KB. Nessun binario nativo da distribuire.

PDF Merge

Combine multiple PDFs into one document, preserving page dimensions and resources.

PDF Split

Extract individual pages or page ranges into separate PDFs. Split to files with naming patterns.

PDF Builder

Create PDFs from scratch with a fluent API. Add text, images, lines, and rectangles with full formatting control.

Text Extraction

Pull text content from PDF pages. Extract from all pages or specific page ranges.

Document Inspector

Read metadata, fonts, page dimensions, and form field counts. Works without any license.

Image Replacement

Find, analyze, and replace images in PDFs. Swap logos or graphics by index or page range with JPEG/PNG.

Auto-Layout Builder

Create reports with auto-pagination, text wrapping, tables, headers/footers, and page numbers.

Form Filling

Read and fill AcroForm fields including text, checkbox, and dropdown. Lossless form preservation.

Redaction

Text-based, regex pattern, or area-based redaction. Permanently remove sensitive content from PDFs.

Optimization

Compress streams, remove duplicate objects, and reduce file size while preserving document quality.

Digital Signatures

Sign PDFs with X.509 certificates and verify existing signatures. Available on .NET 8, 9, 10+.

PDF/A Compliance

Validate and convert to PDF/A (1b, 2b, 2u, 3b, 3u) for long-term archival. Validation works without a license.

Async API

All I/O operations have async overloads with CancellationToken support for scalable applications.

Prezzi

Annual Subscription
$499
auto-renews yearly / cancel anytime
  • Pagine illimitate
  • File illimitati
  • Tutte le funzionalità incluse
  • Supporto via e-mail
  • Automatic annual renewal

Installa il pacchetto NuGet e chiama ExisLicense.Initialize() — funzionalità completa per 14 giorni. Dopo la prova, la modalità valutazione elabora fino a 3 pagine per documento. Senza filigrane. Acquista una chiave di licenza su officefindreplace.com/Home/pdf-find-replace-csharp.

Prezzi in dollari USA. Una chiave per sviluppatore. Funziona su macchina di sviluppo, server di build e produzione — nessun limite per macchina o distribuzione.

Come funziona la prova

Prova (Giorni 1–14)

  • Installare il pacchetto NuGet
  • Chiamare ExisLicense.Initialize()
  • Accesso completo — pagine illimitate
  • Nessuna chiave, nessuna registrazione, nessuna carta di credito

Valutazione (Dopo il giorno 14)

  • La prova scade automaticamente
  • La libreria continua a funzionare
  • Limitato a 3 pagine per documento
  • Nessuna filigrana nell'output
  • Il tuo codice esistente continua a funzionare

Con licenza

  • Acquista chiave su officefindreplace.com/Home/pdf-find-replace-csharp
  • Chiama ExisLicense.Initialize("tua-chiave")
  • Pagine illimitate, senza restrizioni
  • Operazione silenziosa — nessun messaggio console

Il tuo codice non cambia tra modalità prova e modalità con licenza. Aggiungi semplicemente la tua chiave quando sei pronto.

Creato da Exis LLC

Made in USA — Exis LLC, New Jersey. Sviluppo e supporto negli Stati Uniti.
Fiducia governativa — Lo stesso motore PDF alimenta Global Office Find Replace Professional, utilizzato dalle agenzie federali USA per l'elaborazione dei documenti.
Oltre 35 anni nel software — 8 brevetti nell'elaborazione documenti, sensori, crittografia e automazione industriale.
Supporto reattivo — Accesso diretto via e-mail al team di sviluppo. Nessuna coda di ticket.

Domande frequenti

No. Exis.PdfEditor è una libreria .NET pura senza dipendenze esterne. Non utilizza Office, Acrobat, Ghostscript, LibreOffice, Chromium o qualsiasi altro strumento esterno.
IronPDF renderizza i PDF tramite un motore Chromium — ricrea la pagina, distruggendo campi modulo, spaziatura e firme. Aspose.PDF usa un approccio di sostituzione per frammenti di testo che può spostare il posizionamento. Exis.PdfEditor opera direttamente sugli operatori dei content stream PDF, preservando tutto tranne il testo mirato.
Campi modulo (AcroForms), caselle di controllo, pulsanti di opzione, firme digitali (sulle pagine non modificate), annotazioni, segnalibri, file incorporati, collegamenti ipertestuali e tutto il layout e la spaziatura. Solo il testo mirato viene modificato.
Sì. La licenza per posto sviluppatore copre la macchina di sviluppo, il server di build e la distribuzione in produzione. Nessuna licenza per macchina o per distribuzione.
La libreria entra in modalità valutazione. Continua a funzionare ma limita l'elaborazione a 3 pagine per documento. Nessuna eccezione, nessuna filigrana. Il tuo codice esistente continua a funzionare. Aggiungi una chiave di licenza quando sei pronto.
Sì. Il pacchetto NuGet include un build .NET Standard 2.0 che funziona con .NET Framework 4.6.1 e successivi, incluso 4.8. Include anche un build ottimizzato per .NET 8.
Una chiave di licenza per sviluppatore. La chiave risiede nel codice sorgente. Funziona sulla macchina di sviluppo, server di build, staging e produzione senza limiti per macchina. Per i team, ogni sviluppatore necessita della propria chiave. Nessun fingerprinting della macchina o server di attivazione.
Sì. PdfTextExtractor.ExtractText() restituisce il contenuto testuale completo. PdfInspector.Inspect() restituisce metadati del documento e conteggio pagine — PdfInspector non richiede alcuna licenza.
Exis.PdfEditor funziona con PDF basati su testo dove il testo è codificato nei content stream. Per documenti scansionati dove il contenuto è un'immagine raster, sarebbe necessario eseguire prima l'OCR per produrre un livello di testo.
La libreria risolve automaticamente le codifiche dei font — ToUnicode CMaps, WinAnsiEncoding, MacRomanEncoding, dizionari di codifica personalizzati con /Differences e font compositi (CID/Type0) per testo CJK.

Inizia la tua prova gratuita di 14 giorni

dotnet add package Exis.PdfEditor

Inizia la prova gratuita Sample App on GitHub

Domande? Invia un'e-mail a support@exisone.com — riceverai risposta da uno sviluppatore, non da un bot.