2015-02-02 5 views
1

"PROCEDURE DELETED"와 같은 특정 텍스트가있는 모든 페이지에 워터 마크를 추가해야합니다.iText 선택한 페이지에 워터 마크 추가

protected Phrase watermark = new Phrase("DELETED", new Font(FontFamily.HELVETICA, 60, Font.NORMAL, BaseColor.PINK)); 
ArrayList<Integer> arrPages = new ArrayList<Integer>(); 
boolean pdfChecked = false; 

@Override 
public void onEndPage(PdfWriter writer, Document document) { 

    if(pdfChecked == false) { 
     detectPages(writer, document); 
     pdfChecked = true; 
    } 
    int pageNum = writer.getPageNumber(); 

    if(arrPages.contains(pageNum)) { 
     PdfContentByte canvas = writer.getDirectContentUnder(); 
     ColumnText.showTextAligned(canvas, Element.ALIGN_CENTER, watermark, 298, 421, 45); 
    } 
} 

내가 말, 추가 할 경우이 잘 작동, 내 사용자의 arrPages의 ArrayList를에 숫자 3 :와 Adding watermark directly to the stream

지금까지 가지고있는 PdfWatermark 클래스에서 브루노 Lowagie의 제안을 바탕으로

detectPages 메서드 - 페이지 3에 원하는 워터 마크를 표시합니다.

여기에서 내가 액세스 할 수있는 텍스트 문자열을 문서에서 검색하는 방법은 PdfWriter 작성자 또는 com.itextpdf.text.Document 문서는 onEndPage 메서드로 보내집니다. 솔루션 등이 함께 궤도에

private void detectPages(PdfWriter writer, Document document) { 
    try { 

     //arrPages.add(3); 

     ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); 
     PdfWriter.getInstance(document, byteArrayOutputStream); 
     //following code no work 
     PdfReader reader = new PdfReader(writer.getDirectContent().getPdfDocument()); 
     PdfContentByte canvas = writer.getDirectContent(); 
     PdfImportedPage page; 

     for (int i = 0; i < reader.getNumberOfPages();) {  
      page = writer.getImportedPage(reader, ++i); 
      canvas.addTemplate(page, 1f, 0, 0.4f, 0.4f, 72, 50 * i); 
      canvas.beginText(); 
      canvas.showTextAligned(Element.ALIGN_CENTER, 

        //search String 
        String.valueOf((char)(181 + i)), 496, 150 + 50 * i, 0); 

        //if(detected) arrPages.add(i); 

      canvas.endText(); 
     } 

암 I 또는 내가 철회해야합니까 : 여기

는 실패, 내가 시도 무엇인가?

누구든지 문서를 스캔하고 "PROCEDURE DELETED"페이지를 골라야하는 누락 된 링크를 제공 할 수 있습니까?

편집 : iText 5.0.4를 사용하고 있습니다. 현재 5.5.X로 업그레이드 할 수는 없지만 그 아래의 최신 버전으로 업그레이드 할 수 있습니다.

EDIT2 : 추가 정보 :

 String processed = processText(template); 
     List<Element> objects = HTMLWorker.parseToListLog(new StringReader(processed), 
       styles, interfaceProps, errors); 
     for (Element elem : objects) { 
      doc.add(elem); 

     } 

I 제어 addText 방법 호출이 문서 (doc)에 텍스트를 추가하는 방법이다. template은 단순히 데이터베이스 LOB의 html입니다. processText은 curlies에 포함 된 맞춤 마커에 대해 ${replaceMe}과 같이 html을 확인합니다.

문서 생성 중에 "PROCEDURE DELETED"문자열을 식별하는 곳인 것처럼 보이지만 Chunk.setGenericTags()에 대한 경로가 표시되지 않습니다.

EDIT3 : 표 어려움

 List<Element> objects = HTMLWorker.parseToListLog(new StringReader(processed), 
       styles, interfaceProps, errors); 
     for (Element elem : objects) { 
      //Code below no work 
      if (elem instanceof PdfPTable) { 
       PdfPTable table = (PdfPTable) elem; 
       ArrayList<Chunk> chks = table.getChunks(); 
       for(Chunk chk : chks){ 
        if(chk.toString().contains("TEST DELETED")) { 
         chk.setGenericTag("delete_tag"); 
        } 
       }      
      } 

      doc.add(elem); 
     } 

메모 작성자 MLK 브루노는이 문서에 추가 된 시간에 "절차 DELETED"키워드를 감지 제안했다. 그러나 키워드가 반드시 테이블 내부에 있기 때문에 더 간단한 요소가 아닌 PdfPTable을 통해 키워드를 검색해야합니다.

위의 코드로는 수행 할 수 없습니다. 모든 제안 정확히 어떻게 테이블 셀 안의 텍스트를 찾고 그것에 문자열 비교합니까?

EDIT4는 :

  1. (PdfPTable) table.getChunks()가하는 어떤 이유로 핸들러 onGenericTag
  2. 을 실행하는 데 필요한 Chunk.setGenericTag()를 사용하여 다음 몇 가지 실험을 바탕으로, 나는 몇 가지 주장을하고 나에게 그들을 통해 길을 보여 주시기 바랍니다 싶습니다 청크를 반환하지 않습니다. 최소한 내 시스템이 응답합니다. 이것은 반 직관적이며 아마도이 동작을 일으키는 설정, 버전 또는 코드 버그가있을 수 있습니다.
  3. 따라서 테이블 내의 선택 텍스트 문자열을 사용하여 워터 마크를 트리거 할 수 없습니다.
+1

잘못된 트랙에 있습니다. 두 번째 스 니펫의 코드는 여러 단계에서 잘못되었습니다. 누구든지 여러분의 질문에 답하기 전에, 처음부터 문서를 만드는 경우 (페이지 이벤트를 사용하기 때문에 그렇게 보입니다) 또는 기존 PDF로 작업하는 경우 (사실 당신이 사용하는'PdfReader'는 사용자가있을 수 있음을 나타냅니다. –

+0

문서가 동적으로 생성되고 있습니다. 문서가 완성 될 때까지 워터 마크와 함께 저장되지 않습니다. 페이지 번호 가져 오기, 페이지 내용 가져 오기 및 워터 마크를 제어하는 ​​문자 시퀀스 찾기 – KTys

+1

왜 페이지에 문자 시퀀스를 추가 한 다음 페이지의 내용에서 해당 문자 시퀀스를 검색하려고합니까? 문자 시퀀스를 일반 태그로 표시 한 다음 페이지 이벤트를 사용하여 워터 마크를 추가해야하는지 여부를 결정하십시오. –

답변

1

@mkl과 @Bruno의 도움으로 마침내 실행 가능한 솔루션을 얻었습니다. 좀 더 우아한 접근을 할 수있는 사람은 누구나 환영합니다.

원본 질문에 제공된 모든 발췌 문장에서 두 개의 클래스가 사용되었습니다. 아래는 작업 솔루션을 구현하는 부분 코드입니다.

public class PdfExporter 
    //a custom class to build content 

    //create some content to add to pdf 
    String text = "<div>Lots of important content here</div>"; 

    //assume the section is known to be deleted 
    if(section_deleted) { 
     //add a special marker to the text, in white-on-white 
     text = "<span style=\"color:white;\">.!^DEL^?.</span>" + text + "</span>"; 
    } 

    //based on some indicator, we know we want to force a new page for a new section 
    boolean ensureNewPage = true; 

    //use an instance of PdfDocHandler to add the content 
    pdfDocHandler.addText(text, ensureNewPage); 




public class PdfDocHandler extends PdfPageEventHelper 
    private boolean isDEL; 

    public boolean addText(String text, boolean ensureNewPage) 

     if (ensureNewPage) {  
      //turn isDEL off: a forced pagebreak indicates a new section 
      isDEL = false; 
     } 

     //attempt to find the special DELETE marker in first chunk 
     //NOTE: this can be done several ways 
     ArrayList<Chunk> chks = elem.getChunks(); 
     if(chks.size()>0) { 
      if(chks.get(0).getContent().contains(".!^DEL^?.")) { 
       //special delete marker found in text 
       isDEL = true; 
      } 
     } 

     //doc is an iText Document 
     doc.add(elem); 


    public void onEndPage(PdfWriter writer, Document document) { 

     if(isDEL) { 
      //set the watermark 
      Phrase watermark = new Phrase("DELETED", new Font(Font.FontFamily.HELVETICA, 60, Font.NORMAL, BaseColor.PINK)); 
      PdfContentByte canvas = writer.getDirectContentUnder(); 
      ColumnText.showTextAligned(canvas, Element.ALIGN_CENTER, watermark, 298, 421, 45); 
     } 
    }