2015-04-13 26 views
6

Tôi đã tìm kiếm trên Internet trong 2 tuần và tìm thấy một số giải pháp thú vị cho vấn đề của tôi, nhưng dường như không có câu trả lời.iTextSharp Thay thế văn bản trong PDF hiện tại mà không mất hình thành

Mục tiêu của tôi là để làm folowing:

Tôi muốn tìm một văn bản trong một tĩnh PDF-File và thay thế văn bản này với văn bản khác. Tôi muốn giữ thiết kế nội dung. Nó có thực sự khó không?

Tôi tìm thấy một cách nhưng tôi bị mất toàn bộ thông tin:

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

Các thử thứ hai tôi đã có được cách tốt hơn, nhưng cần các lĩnh vực nơi tôi có thể thay đổi nội dung bên trong:

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

này giữ định dạng của phần còn lại của văn bản và chỉ thay đổi văn bản tìm kiếm của tôi. Tôi cần một giải pháp cho văn bản KHÔNG ở trong một Textfield.

cảm ơn tất cả các câu trả lời của bạn và sự trợ giúp của bạn.

+2

"Có thực sự khó không?" Có, nói chung nó là. Bạn có biết về * font subsetting *? Điều gì sẽ xảy ra nếu bạn chèn một ký tự không nằm trong tập hợp con hiện có? Bạn sẽ cần tìm ra phông chữ nào được sử dụng ban đầu (không phải lúc nào cũng tầm thường) và sau đó * có * phông chữ đó trên hệ thống của bạn. (Có những vấn đề khác hơn thế này - tôi thấy đây là một câu hỏi trùng lặp.) – usr2564301

+0

Hi Jongware, Tôi biết đã có một bài đăng như tôi, nhưng không có bất kỳ "Có thể" -Code và câu trả lời "KHÔNG" với câu trả lời không thực sự là một câu trả lời hay. =) Nhưng cảm ơn bạn, đã bình luận của bạn. Tôi ghét PDF –

+1

"Không thể thực hiện được" * là * một câu trả lời hay. Bất kể bạn tìm kiếm trên internet bao lâu, bạn không thể tìm thấy một phương pháp để đi bộ từ Anh sang Mỹ. – usr2564301

Trả lời

4

Vấn đề chung là đối tượng văn bản có thể sử dụng phông chữ được nhúng với các ký tự cụ thể được gán cho các chữ cái cụ thể. I E. nếu bạn có một đối tượng văn bản với một số văn bản như "abcdef" thì phông chữ được nhúng có thể chứa glyphs cho những chữ cái này (không phải chữ cái abcdef) mà không chứa các chữ cái khác. Vì vậy, nếu bạn thay thế "abcdef" bằng "xyz" thì tệp PDF sẽ không hiển thị "xyz" này vì không có glyph nào có sẵn để hiển thị các chữ cái này.

Vì vậy, tôi sẽ xem xét các công việc sau:

  • Duyệt qua tất cả các đối tượng văn bản;
  • Add new text objects được tạo từ đầu trên đầu tệp PDF và đặt cùng thuộc tính (phông chữ, vị trí, v.v.) nhưng có văn bản khác; Bước này có thể yêu cầu bạn phải có cùng một phông chữ được cài đặt trên của bạn như đã được sử dụng trong PDF gốc nhưng bạn có thể kiểm tra phông chữ đã cài đặt và sử dụng phông chữ khác cho một đối tượng văn bản mới. Bằng cách này, iTextSharp hoặc một công cụ PDF khác sẽ nhúng một đối tượng phông chữ mới cho một đối tượng văn bản mới.
  • Xóa đối tượng văn bản gốc khi bạn đã tạo đối tượng văn bản trùng lặp;
  • Xử lý mọi đối tượng văn bản bằng quy trình công việc được mô tả ở trên;
  • Lưu tài liệu PDF đã sửa đổi vào một tệp mới.
+2

Amen to that. Tôi cũng thích các bình luận của @Jongware bởi vì họ giải thích rõ ràng tại sao OP lại cố gắng sử dụng PDF cho một cái gì đó mà nó nên được sử dụng cho. Tôi muốn thay thế một String khác bằng PDF và giữ tất cả các kiểu và có văn bản reflow, là một câu hỏi có vẻ như "Tôi muốn xem TV trên đài phát thanh của tôi" và nhận xét như "Tôi ghét ăn súp với một ngã ba". –

+0

Rất tốt, giải thích kỹ lưỡng thực sự! Tôi nghĩ chúng tôi sẽ chuyển hướng các bản sao đến câu trả lời này từ bây giờ! Nếu OP vẫn không thích nó, tôi khuyến khích họ nhấp vào hồ sơ của mỗi người dùng được trả lời cho đến nay và nhìn vào thẻ của họ. Họ sẽ tìm thấy một số điểm tổng hợp hơn 1.000 trong các danh mục [pdf] vì vậy tôi nghĩ rằng họ đã nhận được một phản hồi rất am hiểu. –

0

Tôi đã làm việc theo cùng một yêu cầu và tôi có thể đạt được điều này bằng các bước sau.

Bước 1: Định vị Nguồn Pdf File và tập tin Destination Đường dẫn

Bước 2: Đọc Nguồn tập tin Pdf và tìm kiếm các vị trí của chuỗi mà chúng ta muốn thay thế

Bước 3: Thay thế chuỗi với cái mới.

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

Nơi nào bạn "thay thế"? Cụ thể, bạn xóa văn bản gốc ở đâu và bạn thêm văn bản mới * bằng cách sử dụng cùng kiểu với bản gốc *? – mkl

+0

cb = stamper.GetOverContent (trang); cb2 = stamper.GetOverContent (trang); ở đây cb sẽ lấy nội dung văn bản trên trang pdf và cb2 sẽ lấy mặt đất màu trắng của trang pdf ............. đầu tiên chúng ta sẽ tìm kiếm vị trí của chuỗi hiện có và lưu trữ nó trong " MatchesFound "biến và sau đó điền vào màu trắng trên chuỗi hiện có cb.SetColorFill (BaseColor.WHITE) .... sau đó chúng tôi sẽ lặp đối tượng matchfound và điền vào chuỗi mới trong cùng một postion của chuỗi sơn màu trắng ... hy vọng bạn là nhận được tôi ... –

+0

* tô màu trắng trên chuỗi hiện tại * - đó không phải là ** xóa ** vì văn bản vẫn có thể được sao chép và dán. Miễn là bản pdf chỉ được in, điều đó là OK, nhưng nếu nó vẫn được phân phối bằng điện tử, thì đó có thể là một nút hiển thị. – mkl

Các vấn đề liên quan