2015-04-13 7 views
6

Ich habe im Internet seit 2 Wochen gesucht und einige interessante Lösungen für mein Problem gefunden, aber nichts scheint mir die Antwort zu geben.iTextSharp Ersetzen Sie Text in bestehenden PDF ohne Formation zu verlieren

Mein Ziel ist die Folowing zu tun:

Wen möchte ich finden einen Text in einer statischen PDF-Datei und ersetzen Sie diesen Text durch einen anderen Text. Ich möchte das Design des Contents beibehalten. Ist es wirklich so schwer?

fand ich einen Weg, aber ich verlor die ganzen Informationen:

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

Der zweite Versuch ich besser war viel hatte, muss aber Felder, wo ich den Text nach innen ändern kann:

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

Diese behält die Formatierung des restlichen Textes und ändert nur meinen gesuchten Text. Ich brauche eine Lösung für Text, der NICHT in einem Textfeld ist.

danke für alle Ihre Antworten und Ihre Hilfe.

+2

"Ist es wirklich so schwer?" Ja, im Allgemeinen ist es so. Kennen Sie * Font-Subsetting *? Was passiert, wenn Sie ein Zeichen einfügen, das nicht in der vorhandenen Teilmenge enthalten ist? Sie müssten herausfinden, welche Schriftart ursprünglich verwendet wurde (nicht immer trivial) und dann * diese Schriftart auf Ihrem System haben. (Es gibt andere Probleme als dies - ich sehe, dass dies eine doppelte Frage ist.) – usr2564301

+0

Hallo Jongware, Ich weiß da gibt es schon einen Beitrag wie meins, aber ohne "Maybe" -Code und die Antwort "NEIN" mit ist nicht wirklich eine gute Antwort. =) Aber danke, für Ihren Kommentar. Ich hasse PDF –

+1

"Nein, es kann nicht getan werden" * ist * eine gute Antwort. Egal, wie lange Sie im Internet suchen, Sie können keine Methode finden, von Großbritannien nach Amerika zu gehen. – usr2564301

Antwort

4

Das allgemeine Problem besteht darin, dass Textobjekte eingebettete Schriftarten mit spezifischen Zeichen verwenden können, die bestimmten Buchstaben zugewiesen sind. I.e. Wenn Sie ein Textobjekt mit einem Text wie "abcdef" haben, dann enthält die eingebettete Schriftart möglicherweise nur Glyphen für diese Buchstaben ("abcdef"), nicht jedoch für andere Buchstaben. Wenn Sie also "abcdef" durch "xyz" ersetzen, wird die PDF diese "xyz" nicht anzeigen, da für diese Buchstaben keine Glyphen verfügbar sind.

So würde ich den folgenden Workflow berücksichtigen:

  • Iterate durch alle Textobjekte;
  • Add new text objects von Grund auf auf PDF-Datei erstellt und legen Sie die gleichen Eigenschaften (Schriftart, Position, etc.) aber mit einem anderen Text; In diesem Schritt müssen Sie möglicherweise dieselben Schriftarten wie in der ursprünglichen PDF-Datei installiert haben. Sie können jedoch nach installierten Schriftarten suchen und eine andere Schriftart für ein neues Textobjekt verwenden. Auf diese Weise wird iTextSharp oder ein anderes PDF-Werkzeug ein neues Schriftobjekt für ein neues Textobjekt einbetten.
  • Entfernen Sie das ursprüngliche Textobjekt, nachdem Sie ein dupliziertes Textobjekt erstellt haben.
  • Verarbeiten Sie jedes Textobjekt mit dem oben beschriebenen Workflow;
  • Speichern Sie das geänderte PDF-Dokument in einer neuen Datei.
+2

Amen dazu. Ich mag auch die Kommentare von @Jongware, weil sie klar erklären, warum das OP versucht, PDF für etwas zu verwenden, für das es verwendet werden sollte. Ich möchte eine Zeichenfolge durch eine andere in PDF ersetzen und alle Stile beibehalten und den Text umfliessen lassen, ist eine Frage, die klingt wie "Ich will auf meinem Radio fernsehen" und sagt wie "Ich hasse es Suppe mit einer Gabel zu essen". –

+0

Sehr gute, gründliche Erklärung! Ich denke, wir werden von nun an Duplikate auf diese Antwort umleiten! Wenn das OP es immer noch nicht mag, würde ich sie ermutigen, auf das Profil jedes Benutzers zu klicken, das bisher geantwortet hat, und sich ihre Tags anzusehen. Sie werden eine kombinierte Punktzahl von über 1.000 in den [pdf] Kategorien finden, also denke ich, dass sie eine sehr sachkundige Antwort erhalten haben. –

0

Ich habe an der gleichen Anforderung gearbeitet, und ich kann dies durch die folgenden Schritte erreichen.

Schritt 1: Beschaffen von Daten PDF-Datei und Zieldateipfad

Schritt 2: Lesen Quelle PDF-Datei und der Suche nach der Lage der Zeichenfolge, die wir

Schritt 3 ersetzt werden soll: Ersetzen der Zeichenfolge durch eine neue.

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

Wo "ersetzen" Sie? Insbesondere, wo entfernst du den Originaltext und wo fügst du neuen Text hinzu * benutze den gleichen Stil wie das Original *? – mkl

+0

cb = stamper.GetOverContent (Seite); cb2 = stamper.GetOverContent (Seite); hier cb wird den Textinhalt über PDF-Seite nehmen und cb2 wird den weißen Hintergrund der PDF-Seite nehmen ............. zuerst werden wir die Position der vorhandenen Zeichenfolge suchen und speichern in " MatchesFound "Variable und füllen Sie dann weiße Farbe auf die bestehende Zeichenfolge cb.SetColorFill (BaseColor.WHITE) .... Danach werden wir strings founded found Objekt und füllen Sie die neue Zeichenfolge in der gleichen Position der weiß bemalten Zeichenfolge ... hoffe, du bist bekomme ich ... –

+0

* fülle weiße Farbe auf die bestehende Zeichenfolge * - das ist nicht ** entfernen **, wie der Text noch kopiert und eingefügt werden kann. Solange das PDF nur gedruckt wird, ist das in Ordnung, aber wenn es noch elektronisch verteilt werden soll, kann das ein echter Hingucker sein. – mkl

Verwandte Themen