2015-04-13 54 views
6

Ho cercato Internet per 2 settimane e ho trovato alcune soluzioni interessanti per il mio problema, ma niente sembra darmi la risposta.iTextSharp Sostituisci testo nel PDF esistente senza perdere la formazione

Il mio obiettivo è quello di fare il folowing:

Voglio trovare un testo in un PDF statici e sostituire il testo con un nuovo testo. Mi piacerebbe mantenere il design del contenuto. E 'davvero così difficile?

ho trovato un modo, ma ho perso tutta l'informazione:

using (PdfReader reader = new PdfReader(path)) 
     { 

      StringBuilder text = new StringBuilder(); 
      for (int i = 1; i <= reader.NumberOfPages; i++) 
      { 
       text.Append(PdfTextExtractor.GetTextFromPage(reader, i)); 
       text.Replace(txt_SuchenNach.Text, txt_ErsetzenMit.Text); 
      } 

      return text.ToString(); 
     } 

Il secondo tentativo ho avuto è stato il modo migliore, ma ha bisogno di campi dove posso cambiare il testo all'interno:

string fileNameExisting =path; 
     string fileNameNew = @"C:\TEST.pdf"; 

     using (FileStream existingFileStream = new FileStream(fileNameExisting, FileMode.Open)) 
     using (FileStream newFileStream = new FileStream(fileNameNew, FileMode.Create)) 
     { 
      // PDF öffnen 
      PdfReader pdfReader = new PdfReader(existingFileStream); 


      PdfStamper stamper = new PdfStamper(pdfReader, newFileStream); 

      var form = stamper.AcroFields; 
      var fieldKeys = form.Fields.Keys; 
      foreach (string fieldKey in fieldKeys) 
      {      
       var value = pdfReader.AcroFields.GetField(fieldKey); 
       form.SetField(fieldKey, value.Replace(txt_SuchenNach.Text, txt_ErsetzenMit.Text)); 
      } 

      // Textfeld unbearbeitbar machen (sieht aus wie normaler text) 
      stamper.FormFlattening = true; 

      stamper.Close(); 
      pdfReader.Close(); 
     } 

Questo mantiene la formattazione del resto del testo e cambia solo il testo cercato. Ho bisogno di una soluzione per il testo che NON è in un campo di testo.

grazie per tutte le vostre risposte e il vostro aiuto.

+2

"È davvero così difficile?" Sì, generalmente lo è. Sei a conoscenza di * subsettings di caratteri *? Cosa succede se inserisci un personaggio che non si trova nel sottoinsieme esistente? Dovresti scoprire quale font è stato utilizzato in origine (non sempre banale) e quindi * avere * quel font sul tuo sistema. (Ci sono altri problemi oltre a questo - vedo che questa è una domanda doppia.) – usr2564301

+0

Hi Jongware, So che c'è già un post come il mio, ma senza alcun "Maybe" -Code e la risposta "NO" con non è davvero una buona risposta. =) Ma grazie, per il tuo commento. Io odio PDF –

+1

"No non può essere fatto" * è * una buona risposta. Non importa per quanto tempo cerchi su internet, non puoi trovare un metodo per andare dalla Gran Bretagna all'America. – usr2564301

risposta

4

Il problema generale è che gli oggetti di testo possono utilizzare caratteri incorporati con glifi specifici assegnati a lettere specifiche. Cioè se si dispone di un oggetto di testo con un testo come "abcdef", il carattere incorporato può contenere glifi per queste lettere ("abcdef") ma non per altre lettere. Quindi, se si sostituisce "abcdef" con "xyz", il PDF non visualizzerà questi "xyz" poiché non sono disponibili glifi per la visualizzazione di queste lettere.

Quindi vorrei prendere in considerazione il seguente flusso di lavoro:

  • scorrere tutti gli oggetti di testo;
  • Add new text objects creato da zero in cima al file PDF e impostato le stesse proprietà (font, posizione, ecc.) Ma con un testo diverso; Questo passaggio potrebbe richiedere di avere gli stessi caratteri installati sul tuo come erano usati nel PDF originale, ma puoi verificare la presenza di font installati e utilizzare un altro font per un nuovo oggetto di testo. In questo modo iTextSharp o un altro strumento PDF incorpora un nuovo oggetto font per un nuovo oggetto di testo.
  • Rimuovere l'oggetto di testo originale dopo aver creato un oggetto di testo duplicato;
  • Elaborare ogni oggetto di testo con il flusso di lavoro sopra descritto;
  • Salvare il documento PDF modificato in un nuovo file.
+2

Amen a quello. Mi piacciono anche i commenti di @Jongware perché spiegano chiaramente perché l'OP sta cercando di usare il PDF per qualcosa per cui dovrebbe essere usato. Voglio sostituire una stringa con un'altra in PDF e mantenere tutti gli stili e avere il testo che scorre, è una domanda che suona come "Voglio guardare la TV sulla mia radio" e osserva "Odio mangiare la zuppa con una forchetta". –

+0

Molto buona, una spiegazione completa davvero! Penso che reindirizzeremo i duplicati a questa risposta d'ora in poi! Se l'OP continua a non piacerli, li incoraggerei a fare clic sul profilo di ciascun utente che ha risposto finora e guardare i loro tag. Troveranno un punteggio combinato di oltre 1.000 nelle categorie [pdf], quindi penso che abbiano ricevuto una risposta molto competente. –

0

Ho lavorato allo stesso requisito e sono in grado di ottenere ciò con i seguenti passaggi.

Step1: Individuazione Fonte File Pdf e file di percorso di destinazione

Step2: file pdf Leggi Fonte e ricerca per la posizione di stringa che vogliamo sostituire

Fase 3: Sostituire la stringa con una nuova.

using iTextSharp.text; 
using iTextSharp.text.pdf; 
using iTextSharp.text.pdf.parser; 
using PDFExtraction;  
using System; 
using System.Collections.Generic; 
using System.IO; 
using System.Linq; 
using System.Web; 
using System.Web.UI; 
using System.Web.UI.WebControls; 

namespace PDFReplaceTextUsingItextSharp 
{ 
    public partial class ExtractPdf : System.Web.UI.Page 
    { 
     static iTextSharp.text.pdf.PdfStamper stamper = null; 
     protected void Page_Load(object sender, EventArgs e) 
     { 

     } 

     protected void Replace_Click(object sender, EventArgs e) 
     { 
      string ReplacingVariable = txtReplace.Text; 
      string sourceFile = "Source File Path"; 
      string descFile = "Destination File Path"; 
      PdfReader pReader = new PdfReader(sourceFile); 
      stamper = new iTextSharp.text.pdf.PdfStamper(pReader, new System.IO.FileStream(descFile, System.IO.FileMode.Create)); 
      PDFTextGetter("ExistingVariableinPDF", ReplacingVariable , StringComparison.CurrentCultureIgnoreCase, sourceFile, descFile); 
      stamper.Close(); 
      pReader.Close(); 
     } 


     /// <summary> 
     /// This method is used to search for the location words in pdf and update it with the words given from replacingText variable 
     /// </summary> 
     /// <param name="pSearch">Searchable String</param> 
     /// <param name="replacingText">Replacing String</param> 
     /// <param name="SC">Case Ignorance</param> 
     /// <param name="SourceFile">Path of the source file</param> 
     /// <param name="DestinationFile">Path of the destination file</param> 
     public static void PDFTextGetter(string pSearch, string replacingText, StringComparison SC, string SourceFile, string DestinationFile) 
     { 
      try 
      { 
       iTextSharp.text.pdf.PdfContentByte cb = null; 
       iTextSharp.text.pdf.PdfContentByte cb2 = null; 
       iTextSharp.text.pdf.PdfWriter writer = null; 
       iTextSharp.text.pdf.BaseFont bf = null; 

       if (System.IO.File.Exists(SourceFile)) 
       { 
        PdfReader pReader = new PdfReader(SourceFile); 


        for (int page = 1; page <= pReader.NumberOfPages; page++) 
        { 
         myLocationTextExtractionStrategy strategy = new myLocationTextExtractionStrategy(); 
         cb = stamper.GetOverContent(page); 
         cb2 = stamper.GetOverContent(page); 

         //Send some data contained in PdfContentByte, looks like the first is always cero for me and the second 100, 
         //but i'm not sure if this could change in some cases 
         strategy.UndercontentCharacterSpacing = (int)cb.CharacterSpacing; 
         strategy.UndercontentHorizontalScaling = (int)cb.HorizontalScaling; 

         //It's not really needed to get the text back, but we have to call this line ALWAYS, 
         //because it triggers the process that will get all chunks from PDF into our strategy Object 
         string currentText = PdfTextExtractor.GetTextFromPage(pReader, page, strategy); 

         //The real getter process starts in the following line 
         List<iTextSharp.text.Rectangle> MatchesFound = strategy.GetTextLocations(pSearch, SC); 

         //Set the fill color of the shapes, I don't use a border because it would make the rect bigger 
         //but maybe using a thin border could be a solution if you see the currect rect is not big enough to cover all the text it should cover 
         cb.SetColorFill(BaseColor.WHITE); 

         //MatchesFound contains all text with locations, so do whatever you want with it, this highlights them using PINK color: 

         foreach (iTextSharp.text.Rectangle rect in MatchesFound) 
         { 
          //width 
          cb.Rectangle(rect.Left, rect.Bottom, 60, rect.Height); 
          cb.Fill(); 
          cb2.SetColorFill(BaseColor.BLACK); 
          bf = BaseFont.CreateFont(BaseFont.HELVETICA_BOLD, BaseFont.CP1252, BaseFont.NOT_EMBEDDED); 

          cb2.SetFontAndSize(bf, 9); 

          cb2.BeginText(); 
          cb2.ShowTextAligned(0, replacingText, rect.Left, rect.Bottom, 0); 
          cb2.EndText(); 
          cb2.Fill(); 
         } 

        } 
       } 

      } 
      catch (Exception ex) 
      { 

      } 

     } 

    } 
} 
+0

Dove "sostituisci"? In particolare, dove rimuovi il testo originale e dove aggiungi un nuovo testo * usando lo stesso stile dell'originale *? – mkl

+0

cb = stamper.GetOverContent (pagina); cb2 = stamper.GetOverContent (pagina); qui cb prenderà il contenuto del testo nella pagina pdf e cb2 prenderà il fondo bianco della pagina pdf ............. prima cercheremo la posizione della stringa esistente e la memorizzeremo in " MatchesFound "variabile e quindi riempire il colore bianco sulla stringa esistente cb.SetColorFill (BaseColor.WHITE) .... dopodiché eseguiremo il loop matchfound dell'oggetto e riempiremo la nuova stringa nella stessa posizione della stringa dipinta di bianco ... spero che tu sia trovarmi ... –

+0

* riempire il colore bianco sulla stringa esistente * - che non è ** rimuovendo ** come il testo può ancora essere copiato e incollato. Finché il pdf deve essere stampato, va bene, ma se sarà ancora distribuito elettronicamente, ciò può essere un ostacolo alla presentazione. – mkl