Exis.PdfEditor logo

SDK buscar y reemplazar en PDF para .NET

Buscar y reemplazar texto en archivos PDF programáticamente con C#. Edición directa de flujos de contenido — sin conversión a DOCX, sin dependencias externas, sin pérdida de datos.

.NET CLI dotnet add package Exis.PdfEditor

PM Console Install-Package Exis.PdfEditor

Por qué Exis.PdfEditor

Cómo funcionan otras bibliotecas

La mayoría de las bibliotecas PDF .NET — IronPDF, Spire.PDF, Aspose, Syncfusion — reemplazan texto convirtiendo el PDF a un formato intermedio, redactando texto y dibujando nuevo texto encima, o reconstruyendo páginas desde cero.

Este enfoque daña:

  • Campos de formulario y casillas de verificación
  • Firmas digitales
  • Espaciado y kerning del texto
  • Diseño y posicionamiento de página
  • Marcadores y destinos de enlaces

Cómo funciona Exis.PdfEditor

Exis.PdfEditor analiza los flujos de contenido PDF directamente a nivel de bytes. Localiza texto en los operadores PDF reales, modifica solo los operandos de cadena seleccionados y escribe usando actualización incremental de PDF.

Todo lo que no se toca permanece idéntico byte por byte:

  • Campos de formulario y AcroForms: intactos
  • Firmas digitales en páginas no modificadas: preservadas
  • Espaciado y kerning del texto: preservados
  • Diseño y estructura de página: preservados
  • Marcadores, anotaciones, archivos incrustados: preservados

Otras bibliotecas

PDF
Convertir a formato intermedio
Modificar
Reconvertir a PDF
Salida (dañada)

Exis.PdfEditor

PDF
Analizar flujos de contenido
Reemplazar operandos de texto
Actualización incremental
Salida (idéntica excepto texto reemplazado)

Code Samples

Reemplazar texto en un PDF — 3 líneas de código

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.");

Múltiples reemplazos en un solo paso

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);

Reemplazo basado en patrones con expresiones regulares

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);

Activar su suscripción

// 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

Cómo se compara Exis.PdfEditor

Característica Exis.PdfEditor IronPDF Spire.PDF Aspose.PDF Syncfusion
Edición directa de flujos de contenido Renderizado HTML Superposición de redacción Reemplazo por fragmento Superposición de redacción
Preserva campos de formulario Parcial Parcial
Preserva firmas digitales Páginas no modificadas
Preserva espaciado/kerning del texto Parcial
Cero dependencias nativas .NET puro Motor Chromium
Tamaño de DLL < 500 KB ~250 MB ~20 MB ~40 MB ~15 MB
Reemplazo por lotes multi-par Paso único Bucle manual Bucle manual Bucle manual Bucle manual
.NET Framework 4.8 Solo .NET 6+
Multiplataforma
Soporte de regex
Precio (por desarrollador/año) $499 $749 $999 $1,175 $995*
Sede central 🇺🇸 USA 🇺🇸 USA 🇨🇳 China 🇦🇺 Australia 🇺🇸 USA

Comparación basada en documentación públicamente disponible de febrero de 2026. El soporte de características puede variar según la versión.
"Edición directa de flujos de contenido" significa que la biblioteca modifica los operadores de texto PDF en su lugar sin convertir, re-renderizar o superponer.

Características

Edición directa de PDF

Modifica operadores de flujo de contenido. Sin conversión intermedia.

Cero dependencias

Sin Ghostscript, sin LibreOffice, sin Chromium. .NET administrado puro.

Salida sin pérdidas

Formularios, firmas, anotaciones, marcadores — todo preservado.

Multi-objetivo

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

Procesamiento por lotes

Múltiples pares buscar/reemplazar ejecutados en un solo paso.

Expresiones regulares

Soporte completo de regex .NET para reemplazos basados en patrones.

Multiplataforma

Windows, Linux, macOS. Donde sea que .NET funcione.

Huella pequeña

DLL única, menos de 500 KB. Sin binarios nativos que desplegar.

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.

Precios

Annual Subscription
$499
auto-renews yearly / cancel anytime
  • Páginas ilimitadas
  • Archivos ilimitados
  • Todas las características incluidas
  • Soporte por correo electrónico
  • Automatic annual renewal

Instale el paquete NuGet y llame a ExisLicense.Initialize() — funcionalidad completa durante 14 días. Después del período de prueba, el modo evaluación procesa hasta 3 páginas por documento. Sin marcas de agua. Compre una clave de licencia en officefindreplace.com/Home/pdf-find-replace-csharp.

Precios en dólares estadounidenses. Una clave por desarrollador. Funciona en máquina de desarrollo, servidor de compilación y producción — sin límites por máquina o despliegue.

Cómo funciona la prueba

Prueba (Días 1–14)

  • Instalar el paquete NuGet
  • Llamar a ExisLicense.Initialize()
  • Acceso completo — páginas ilimitadas
  • Sin clave, sin registro, sin tarjeta de crédito

Evaluación (Después del día 14)

  • La prueba expira automáticamente
  • La biblioteca sigue funcionando
  • Limitado a 3 páginas por documento
  • Sin marcas de agua en la salida
  • Su código existente sigue funcionando

Con licencia

  • Comprar clave en officefindreplace.com/Home/pdf-find-replace-csharp
  • Llamar a ExisLicense.Initialize("su-clave")
  • Páginas ilimitadas, sin restricciones
  • Operación silenciosa — sin mensajes de consola

Su código no cambia entre el modo de prueba y el modo con licencia. Simplemente agregue su clave cuando esté listo.

Creado por Exis LLC

Hecho en EE.UU. — Exis LLC, New Jersey. Desarrollo y soporte en Estados Unidos.
Confianza gubernamental — El mismo motor PDF impulsa Global Office Find Replace Professional, utilizado por agencias federales de EE.UU. para el procesamiento de documentos.
Más de 35 años en software — 8 patentes en procesamiento de documentos, sensores, criptografía y automatización industrial.
Soporte receptivo — Acceso directo por correo electrónico al equipo de desarrollo. Sin cola de tickets.

Preguntas frecuentes

No. Exis.PdfEditor es una biblioteca .NET pura sin dependencias externas. No utiliza Office, Acrobat, Ghostscript, LibreOffice, Chromium ni ninguna otra herramienta externa.
IronPDF renderiza PDFs mediante un motor Chromium — recrea la página, destruyendo campos de formulario, espaciado y firmas. Aspose.PDF usa un enfoque de reemplazo de fragmentos de texto que puede desplazar el posicionamiento. Exis.PdfEditor opera directamente sobre los operadores de flujo de contenido PDF, preservando todo excepto el texto seleccionado.
Campos de formulario (AcroForms), casillas de verificación, botones de radio, firmas digitales (en páginas no modificadas), anotaciones, marcadores, archivos incrustados, hipervínculos y todo el diseño y espaciado. Solo se modifica el texto que usted selecciona.
Sí. La licencia por puesto de desarrollador cubre su máquina de desarrollo, servidor de compilación y despliegue en producción. Sin licencias por máquina o por despliegue.
La biblioteca entra en modo evaluación. Sigue funcionando pero limita el procesamiento a 3 páginas por documento. Sin excepciones, sin marcas de agua. Su código existente sigue funcionando. Agregue una clave de licencia cuando esté listo.
Sí. El paquete NuGet incluye un build .NET Standard 2.0 que funciona con .NET Framework 4.6.1 y posterior, incluyendo 4.8. También incluye un build optimizado para .NET 8.
Una clave de licencia por desarrollador. La clave reside en su código fuente. Funciona en su máquina de desarrollo, servidor de compilación, staging y producción sin límites por máquina. Para equipos, cada desarrollador necesita su propia clave. Sin fingerprinting de máquina ni servidores de activación.
Sí. PdfTextExtractor.ExtractText() devuelve el contenido de texto completo. PdfInspector.Inspect() devuelve metadatos del documento y número de páginas — PdfInspector no requiere licencia en absoluto.
Exis.PdfEditor funciona con PDFs basados en texto donde el texto está codificado en flujos de contenido. Para documentos escaneados donde el contenido es una imagen raster, necesitaría ejecutar OCR primero para producir una capa de texto.
La biblioteca resuelve automáticamente las codificaciones de fuentes — ToUnicode CMaps, WinAnsiEncoding, MacRomanEncoding, diccionarios de codificación personalizados con /Differences y fuentes compuestas (CID/Type0) para texto CJK.

Inicie su prueba gratuita de 14 días

dotnet add package Exis.PdfEditor

Iniciar prueba gratuita Sample App on GitHub

¿Preguntas? Envíe un correo a support@exisone.com — recibirá respuesta de un desarrollador, no de un bot.