2017-11-08 27 views
1

PDF 문서에서 텍스트를 삭제해야합니다. 나는 목적을 위해 Aspose를 사용하고 있습니다 현재 TextFragmentAbsorber을 사용하고 있습니다.Aspose.PDF 라이브러리를 사용하여 PDF 문서에서 텍스트를 제거 하시겠습니까?

참고 : 제 3 자 라이브러리는 사용할 수 없습니다. 삭제할 내용이 한 페이지에있는 경우

private string DeleteMachineReadableCode(string inputFilePath) 
    { 
     var outputFilePath = Path.Combine(Path.GetTempPath(), string.Format(@"{0}.pdf", Guid.NewGuid())); 

     try 
     { 
      // Open document 
      Document pdfDocument = new Document(inputFilePath); 

      // Create TextAbsorber object to find all the phrases matching the regular expression 
      TextFragmentAbsorber textFragmentAbsorber = new TextFragmentAbsorber("#START#((.|\r\n)*?)#END#"); 

      // Set text search option to specify regular expression usage 
      TextSearchOptions textSearchOptions = new TextSearchOptions(true); 


      textFragmentAbsorber.TextSearchOptions = textSearchOptions; 

      // Accept the absorber for all pages 
      pdfDocument.Pages.Accept(textFragmentAbsorber); 

      // Get the extracted text fragments 
      TextFragmentCollection textFragmentCollection = textFragmentAbsorber.TextFragments; 

      // Loop through the fragments 
      foreach (TextFragment textFragment in textFragmentCollection) 
      { 
       // Update text and other properties 
       textFragment.Text = string.Empty; 

       // Set to an instance of an object. 
       textFragment.TextState.Font = FontRepository.FindFont("Verdana"); 
       textFragment.TextState.FontSize = 1; 
       textFragment.TextState.ForegroundColor = Aspose.Pdf.Color.FromRgb(System.Drawing.Color.White); 
       textFragment.TextState.BackgroundColor = Aspose.Pdf.Color.FromRgb(System.Drawing.Color.White); 
      } 

      pdfDocument.Save(outputFilePath); 

     } 
     finally 
     { 
      if (File.Exists(inputFilePath)) 
       File.Delete(inputFilePath); 
     } 

     return outputFilePath; 
    } 

내가 내용을 바꿀 수 있어요 : 아래

내가 사용하고있는 코드입니다. 내 문제는 텍스트가 여러 페이지에 걸쳐있는 경우 TextFragmentAbsorber가 언급 한 정규식 패턴 (" #START#((.|\r\n)*?)#END#")이있는 텍스트를 인식하지 못한다는 것입니다.

Aspose의 정규식 또는 일부 설정으로 내 문제를 해결할 수 있는지 제안 해주세요.

+1

나는이 시나리오를 테스트하기 위해 특정 문서가 필요하기 때문에 귀하의 의견을 관찰했으며 소스 파일을 우리와 공유하도록 요청한 바 있습니다. Google 드라이브, Dropbox 등 무료 파일 호스팅 서비스를 사용하여 파일을 공유 할 수 있습니다. –

+0

@FarhanRaza 업로드 : https://drive.google.com/open?id=1PALgqgXIltrAKcZuZ2ron_I2pD-8Wgqg –

+0

요청한 파일을 공유해 주셔서 감사합니다. 나는 당신과 공유 한 데이터로 작업했지만 TextFragmentAbsorber가 한 페이지에 걸쳐 있어도 텍스트를 인식하지 못합니다.이 PDF에서 추출 할 문자열을 알려 주시면 그에 따라 정규식을 검사 할 수 있습니다 . 참고 : 저는 Aspose with Developer Evangelist에서 일합니다. –

답변

2

@Jose Francis, 텍스트가 여러 페이지에 걸쳐있을 때 TextFragmentAbsorber를 사용하여이 문제를 관찰 할 수있었습니다. 따라서 ID 번호 의 조사 티켓 PDFNET-43671이 문제 관리 시스템에 기록되었습니다. 문제가 조사되는대로 즉시 결과를 알려 드리겠습니다.

불편을 끼쳐 드려 죄송합니다.

+0

티켓 상태를 어떻게 볼 수 있습니까? –

+2

문서를 페이지 단위로 처리하기 때문에 문제를 조사했으며 TextFragmentAbsorber의 아키텍처 제한 사항을 알려 드리고자합니다. 이전에 기록 된 우선 순위 문제를 고려하면 가까운 장래에 궁극적 인 해결책을 약속 할 수 없습니다. 또한 버그 추적 시스템은 내부 문제 관리 시스템이며 사용자가 액세스 할 수 없을 수도 있습니다. –

1

이전에 공유 한대로 아키텍처 제한으로 인해보고 된 문제의 초기 해결을 약속 할 수 없습니다. 그러나 귀하의 요구 사항에 맞게 코드 스 니펫을 수정했습니다.

아이디어는 문서 페이지 중 하나에서 '# START #'부터 시작하는 텍스트를 찾는 것입니다. 다음 페이지 중 하나에서 '# END #'로 끝나는 텍스트를 찾으십시오. 또한 두 페이지 사이에있는 모든 텍스트 조각을 처리합니다 (존재하는 경우).

private string DeleteMachineReadableCodeUpdated(string inputFilePath) 
    { 
    string outputFilePath = Path.Combine(Path.GetTempPath(), string.Format(@"{0}.pdf", Guid.NewGuid())); 

try 
{ 
    // Open document 
    Document pdfDocument = new Document(inputFilePath); 

    // Create TextAbsorber object to find all the phrases matching the regular expression 
    TextFragmentAbsorber absorber = new TextFragmentAbsorber("#START#((.|\r\n)*?)#END#"); 

    // Set text search option to specify regular expression usage 
    TextSearchOptions textSearchOptions = new TextSearchOptions(true); 

    absorber.TextSearchOptions = textSearchOptions; 

    // Accept the absorber for all pages 
    pdfDocument.Pages.Accept(absorber); 

    // Get the extracted text fragments 
    TextFragmentCollection textFragmentCollection = absorber.TextFragments; 

    // If pattern found on one of the pages 
    if (textFragmentCollection.Count > 0) 
    { 
     RemoveTextFromFragmentCollection(textFragmentCollection); 
    } 
    else 
    { 
     // In case nothing was found tries to find by parts 
     string startingPattern = "#START#((.|\r\n)*?)\\z"; 
     string endingPattern = "\\A((.|\r\n)*?)#END#"; 
     bool isStartingPatternFound = false; 
     bool isEndingPatternFound = false; 
     ArrayList fragmentsToRemove = new ArrayList(); 

     foreach (Page page in pdfDocument.Pages) 
     { 
      // If ending pattern was already found - do nothing 
      if (isEndingPatternFound) 
       continue; 

      // If starting pattern was already found - activate textFragmentAbsorber with ending pattern 
      absorber.Phrase = !isStartingPatternFound ? startingPattern : endingPattern; 

      page.Accept(absorber); 
      if (absorber.TextFragments.Count > 0) 
      { 
       // In case something is found - add it to list 
       fragmentsToRemove.AddRange(absorber.TextFragments); 

       if (isStartingPatternFound) 
       { 
        // Both starting and ending patterns found - the document processing 
        isEndingPatternFound = true;       
        RemoveTextFromFragmentCollection(fragmentsToRemove); 
       } 
       else 
       { 
        // Only starting pattern found yet - continue 
        isStartingPatternFound = true;       
       } 
      } 
      else 
      { 
       // In case neither starting nor ending pattern are found on current page 
       // If starting pattern was found previously - get all fragments from the page 
       if (isStartingPatternFound) 
       { 
        absorber.Phrase = String.Empty; 
        page.Accept(absorber); 
        fragmentsToRemove.AddRange(absorber.TextFragments); 
       } 
       // Otherwise do nothing (continue) 
      } 
     } 
    } 

    pdfDocument.Save(outputFilePath); 
} 
finally 
{ 
    if (File.Exists(inputFilePath)) 
     File.Delete(inputFilePath); 
} 

return outputFilePath; 
} 

private void RemoveTextFromFragmentCollection(ICollection fragmentCollection) 
{ 
// Loop through the fragments 
foreach (TextFragment textFragment in fragmentCollection) 
{ 
    textFragment.Text = string.Empty; 
} 
} 

참고 :

  • 이 코드는 하나의 텍스트 블록은 '#의 START 번호'에서 시작하여 문서에 '# 끝 #'로 끝나는 것으로 가정. 그러나 위의 코드는 easly 몇 가지 블록을 처리하도록 수정할 수 있습니다.
  • 중간 페이지에 텍스트를 처리하는 대신 페이지 번호를 저장할 수 있으며 저장 문서 앞에 pdfDocument.Pages.Delete (pageNumber)를 사용하여 삭제할 수 있습니다. 그것은 바람직하지 않은 경우 '빈 페이지'를 피할 수 있습니다.