2013-03-05 29 views
31

Có thể sử dụng iTextSharp để xóa khỏi một đối tượng tài liệu PDF không hiển thị (hoặc ít nhất không được hiển thị) không?Xóa các đối tượng vô hình PDF bằng iTextSharp

Thông tin chi tiết:

1) nguồn của tôi là một trang PDF có chứa hình ảnh và văn bản (có thể một số bản vẽ vectơ) và phông chữ nhúng.

2) Có giao diện để thiết kế nhiều 'hộp cắt'.

3) Tôi phải tạo một tệp PDF mới chỉ chứa những gì nằm trong các hộp cắt. Bất cứ điều gì khác phải được loại bỏ khỏi kết quả tài liệu (thực sự tôi có thể chấp nhận nội dung đó là một nửa bên trong và một nửa bên ngoài, nhưng điều này không phải là lý tưởng và nó không nên xuất hiện anyway).

Giải pháp của tôi cho đến nay:

tôi đã phát triển thành công một giải pháp mà tạo ra văn bản tạm thời mới, mỗi người có chứa các nội dung của mỗi hộp cây trồng (sử dụng writer.GetImportedPage và contentByte.AddTemplate đến một trang đó là chính xác kích thước của hộp cắt). Sau đó, tôi tạo tài liệu cuối cùng và lặp lại quy trình, sử dụng phương thức AddTemplate làm vị trí cho mỗi "trang được cắt" trong trang cuối cùng.

Giải pháp này có 2 nhược điểm lớn:

  • kích thước của tài liệu là [kích thước ban đầu] * [số hộp cây trồng], kể từ khi toàn bộ trang là có tên, đóng dấu nhiều lần! (vô hình, nhưng ở đó)
  • văn bản vô hình vẫn có thể được truy cập bằng cách chọn tất cả (CTRL + A) trong Reader và dán.

Vì vậy, tôi nghĩ rằng tôi cần phải lặp qua các đối tượng PDF, phát hiện xem nó có hiển thị hay không và xóa nó. Tại thời điểm viết bài, tôi đang cố gắng sử dụng pdfReader.GetPdfObject.

Cảm ơn sự giúp đỡ.

+3

Do iText cung cấp API cấp thấp cho phép bạn thao tác gần như mọi thứ trong tài liệu, ** có thể **. Đó là ** không ** để nói rằng nó là ** dễ dàng **, mặc dù, vì bạn sẽ phải tự viết mã để xác định cho mỗi phần tử trong nội dung trang cho dù có hiển thị hay không, và bạn sẽ phải cùng nhau dán các phần còn lại của nội dung. Bạn có thể giảm kích thước tài liệu kết quả trong giải pháp hiện tại của mình, tuy nhiên, nếu bạn sử dụng lại mẫu trang đã nhập nếu nhiều phần của nó được hiển thị. Công việc thú vị trong nhiều tuần ... – mkl

+0

Hãy thử sử dụng lớp 'PdfStamper' để cắt xén: http://itextpdf.com/examples/iia.php?id=231 –

+0

Tôi không phải là 100 phần trăm về điều này như xa như iTextSharp là có liên quan nhưng iPdfSharp có khả năng hiển thị từ biểu mẫu. ý tưởng là bạn mở trang của bạn, rằng bạn đang cắt xén, bên trong một biểu mẫu và sau đó chỉ hiển thị các phần bạn cần vào một tài liệu mới. Bạn sẽ không tạo nhiều bản sao và các phần được hiển thị (cắt) sẽ là hình ảnh. Hãy thử để xem nếu đây là một tùy chọn dưới api IText. – Alex

Trả lời

0

Bạn đã thử sử dụng một IRenderListener chưa? Bạn có thể chọn lọc chỉ thêm những phần tử đó vào pdf mới nằm trong vùng cắt bằng cách kiểm tra StartPoint và EndPoint hoặc Vùng của đối tượng TextRenderInfo hoặc ImageRenderInfo.

1

Nếu tệp PDF bạn đang thử là mẫu/được xác định trước/cố định thì bạn có thể xóa đối tượng đó bằng cách gọi RemoveField.

PdfReader pdfReader = new PdfReader(../Template_Path.pdf")); 
PdfStamper pdfStamperToPopulate = new PdfStamper(pdfReader, new FileStream(outputPath, FileMode.Create)); 
AcroFields pdfFormFields = pdfStamperToPopulate.AcroFields; 
pdfFormFields.RemoveField("fieldNameToBeRemoved"); 
+0

OP không nói về các trường biểu mẫu. Ông đã ném đi tất cả các trường biểu mẫu trong 'writer.GetImportedPage' và' contentByte.AddTemplate' anyways nếu có bất kỳ trường nào bắt đầu. – mkl

1
PdfReader pdfReader = new PdfReader(../Template_Path.pdf")); 
PdfStamper pdfStamperToPopulate = new PdfStamper(pdfReader, new FileStream(outputPath, FileMode.Create)); 
AcroFields pdfFormFields = pdfStamperToPopulate.AcroFields; 
pdfFormFields.RemoveField("fieldNameToBeRemoved"); 
1

Có, đó là có thể. Bạn cần phải phân tích cú pháp nội dung trang pdf thành PdfObjects, lưu chúng vào bộ nhớ, xóa nội dung PdfObject không mong muốn, xây dựng nội dung Pdf từ byte nội dung pdf của PdfObject, thay thế nội dung trang trong PdfReader ngay trước khi bạn nhập trang qua PdfWriter.

tôi sẽ khuyên bạn nên kiểm tra này: http://habjan.blogspot.com/2013/09/proof-of-concept-converting-pdf-files.html

mẫu từ các liên kết thực hiện Pdf byte nội dung phân tích, xây dựng lại từ PdfObjec của, thay thế trang PdfReader nội dung byte ...

1

Dưới đây là ba giải pháp tôi thấy, nếu nó có thể giúp một người nào đó (sử dụng iTextSharp, Amyuni hoặc Tracker-Software, như @Hetote nói trong các ý kiến ​​ông đang tìm kiếm một thư viện):

Sử dụng iTextSharp

Như answered by @martinbuberl in another question:

public static void CropDocument(string file, string oldchar, string repChar) 
{ 
    int pageNumber = 1; 
    PdfReader reader = new PdfReader(file); 
    iTextSharp.text.Rectangle size = new iTextSharp.text.Rectangle(
    Globals.fX, 
    Globals.fY, 
    Globals.fWidth, 
    Globals.fHeight); 
    Document document = new Document(size); 
    PdfWriter writer = PdfWriter.GetInstance(document, 
    new FileStream(file.Replace(oldchar, repChar), 
    FileMode.Create, FileAccess.Write)); 
    document.Open(); 
    PdfContentByte cb = writer.DirectContent; 
    document.NewPage(); 
    PdfImportedPage page = writer.GetImportedPage(reader, 
    pageNumber); 
    cb.AddTemplate(page, 0, 0); 
    document.Close(); 
} 

Một câu trả lời bằng @rafixwpt trong his question, nhưng nó không loại bỏ các yếu tố vô hình, nó làm sạch một khu vực của trang, có thể ảnh hưởng đến các bộ phận khác của trang:

static void textsharpie() 
{ 
    string file = "C:\\testpdf.pdf"; 
    string oldchar = "testpdf.pdf"; 
    string repChar = "test.pdf"; 
    PdfReader reader = new PdfReader(file); 
    PdfStamper stamper = new PdfStamper(reader, new FileStream(file.Replace(oldchar, repChar), FileMode.Create, FileAccess.Write)); 
    List<PdfCleanUpLocation> cleanUpLocations = new List<PdfCleanUpLocation>(); 
    cleanUpLocations.Add(new PdfCleanUpLocation(1, new iTextSharp.text.Rectangle(0f, 0f, 600f, 115f), iTextSharp.text.BaseColor.WHITE)); 
    PdfCleanUpProcessor cleaner = new PdfCleanUpProcessor(cleanUpLocations, stamper); 
    cleaner.CleanUp(); 
    stamper.Close(); 
    reader.Close(); 
} 

Sử dụng Amyuni

Như answered by @yms in another question:

IacDocument.GetObjectsInRectangle Phương pháp

Phương thức GetObjectsInRectangle nhận tất cả các đối tượng nằm trong số được chỉ định lại ctangle.

Sau đó, bạn có thể lặp lại tất cả các đối tượng trong trang và xóa những người mà bạn không quan tâm đến:

//open a pdf document 
document.Open(testfile, ""); 
IacPage page1 = document.GetPage(1); 
Amyuni.PDFCreator.IacAttribute attribute = page1.AttributeByName("Objects"); 

// listObj is an array list of graphic objects 
System.Collections.ArrayList listobj = (System.Collections.ArrayList) attribute.Value.Cast<IacObject>();; 

// listObjToKeep is an array list of graphic objects inside a rectangle 
var listObjToKeep = document.GetObjectsInRectangle(0f, 0f, 600f, 115f, IacGetRectObjectsConstants.acGetRectObjectsIntersecting).Cast<IacObject>(); 
foreach (IacObject pdfObj in listObj.Except(listObjToKeep)) 
{ 
    // if pdfObj is not in visible inside the rectangle then call pdfObj.Delete(); 
    pdfObj.Delete(false); 
} 

Như đã nói bởi @yms trong các ý kiến, giải pháp khác sử dụng phương pháp mới trong IacDocument.Redact phiên bản 5.0 cũng có thể được sử dụng để xóa tất cả các đối tượng trong hình chữ nhật được chỉ định và vẽ một hình chữ nhật màu ở vị trí của chúng.

Sử dụng Tracker-Phần mềm biên tập SDK

Tôi không thử nó nhưng có vẻ như có thể, xem post này.

+1

Trong trường hợp của Amyuni PDF Creator, một phương pháp mới [IacDocument.Redact] (https://www.amyuni.com/WebHelp/Amyuni_PDF_Creator_for_NET/Amyuni_PDFCreator_IacDocument/Methods/IacDocument.Redact_Method.htm) đã được thêm vào trong phiên bản 5.0 có thể hữu ích trong loại kịch bản này. – yms

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