2012-01-13 2 views
1

Winnovative의 PdfToText 라이브러리를 평가 중이며 저에게 우려되는 것을 실행했습니다.NUnit을 실행하면 타사 Pdf 라이브러리가 상당히 느려집니다.

콘솔 응용 프로그램을 실행하고 있으면 모든 것이 잘 실행되고 작은 20k 이하 pdf에서 텍스트 콘텐츠를 즉시 추출 할 수 있습니다. 그러나 NUnit gui에서 동일한 코드를 호출하면 15-25 초가 걸립니다 (필자는 PdfToText라는 텍스트를 추출하고 F10을 눌러 코드를 추출하는 줄에 중단 점을 두어 확인했습니다. 다음 행).

내가 원인을 알지 못해서 어디서 책임을 질지 모르겠다는 이유로이 문제는 저에 관한 것입니다. NUnit 또는 PdfToText에 문제가 있습니까? PDF에서 텍스트를 추출하기 만하면되지만 특정 조건에서이 동작을 보게되면 20 초가 완전히 부당합니다. NUnit을 실행하는 중이라면 수용 할 만하다. 그렇지 않으면 다른 곳을 봐야 할 것이다. 당신은 ( http://dl.dropbox.com/u/273037/PdfToTextProblem.zip :

그것은 완전한 VS 솔루션 (2010)을 사용하여 문제를 보여주기 위해 쉽게, 그래서 여기에 링크가 설정 및 실행 (NUnit과 또는 PdfToText 또는 샘플 PDF 파일을 다운로드 할 필요가 없습니다)에보다 쉽게 ​​할 수 있어요 32 비트 시스템에서 실행중인 경우 x86 dll을 사용하려면 PdfToText에 대한 참조를 변경해야 할 수 있습니다.

F5를 누르면 NUnit Gui 러너가로드됩니다.

제안이 있으면 iTextSharp (2 줄의 코드가 너무 비쌉니다)를 시도하고 Aspose (내가 시도하지는 않았지만 SaaS 라이센스 $ 11k입니다.) 그러나 그들은 필요한 기능이 부족하거나 너무 비싸다.

+0

? iText의 4.1.6 버전은 마감 된 소스 솔루션을 허용합니다. 4.1.6은 텍스트 추출기를 직접 가지고 있지는 않지만'PdfReader'와'GetPageContent()'를 사용하여 텍스트 추출기를 쓰는 것은 그리 어렵지 않습니다. –

+0

PDF는 전혀 복잡하지 않습니다. 텍스트 나 형식의 텍스트는 없습니다. 그러나, 나는 v5.0 이전의 SourceForge에서 iTextSharp의 어떤 버전도 보지 못했다. 내가 구 버전을 어디서 구할 수 있을까? 또는 Java 버전 (.NET 응용 프로그램)을 사용해야합니다. –

+0

좋아, 내가 여기에 대한 소스를 찾은 것 같습니다 : http://itextsharp.svn.sourceforge.net/viewvc/itextsharp/tags/. 고마워, 나는 그것을 시험해 볼 것이다! –

답변

0

(댓글 답으로 전환)

당신의 PDF 파일이 얼마나 복잡한? iText의 4.1.6 버전은 마감 된 소스 솔루션을 허용합니다. 4.1.6은 텍스트 추출기를 직접 가지고 있지 않지만 PdfReader 및 GetPageContent()를 사용하여 텍스트 추출기를 작성하는 것은 그리 어렵지 않습니다.

0

아래는 iTextSharp v4.1.6을 사용하여 PDF에서 텍스트를 추출하는 데 사용한 코드입니다. 그것이 지나치게 장황하게 보일 경우, 필자는 그것을 어떻게 사용하고 유연성이 필요한지와 관련이 있습니다.

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using iTextSharp.text.pdf; 

namespace ClassLibrary1 
{ 
    public class PdfToken 
    { 
     private PdfToken(int type, string value) 
     { 
      Type = type; 
      Value = value; 
     } 

     public static PdfToken Create(PRTokeniser tokenizer) 
     { 
      return new PdfToken(tokenizer.TokenType, tokenizer.StringValue); 
     } 

     public int Type { get; private set; } 
     public string Value { get; private set; } 
     public bool IsOperand 
     { 
      get 
      { 
       return Type == PRTokeniser.TK_OTHER; 
      } 
     } 
    } 

    public class PdfOperation 
    { 
     public PdfOperation(PdfToken operationToken, IEnumerable<PdfToken> arguments) 
     { 
      Name = operationToken.Value; 
      Arguments = arguments; 
     } 

     public string Name { get; private set; } 
     public IEnumerable<PdfToken> Arguments { get; private set; } 
    } 

    public interface IPdfParsingStrategy 
    { 
     void Execute(PdfOperation op); 
    } 

    public class PlainTextParsingStrategy : IPdfParsingStrategy 
    { 
     StringBuilder text = new StringBuilder(); 

     public PlainTextParsingStrategy() 
     { 

     } 

     public String GetText() 
     { 
      return text.ToString(); 
     } 

     #region IPdfParsingStrategy Members 

     public void Execute(PdfOperation op) 
     { 
      // see Adobe PDF specs for additional operations 
      switch (op.Name) 
      { 
       case "TJ": 
        PrintText(op); 
        break; 
       case "Tm": 
        SetMatrix(op); 
        break; 
       case "Tf": 
        SetFont(op); 
        break; 
       case "S": 
        PrintSection(op); 
        break; 
       case "G": 
       case "g": 
       case "rg": 
        SetColor(op); 
        break; 
      } 
     } 

     #endregion 

     bool newSection = false; 

     private void PrintSection(PdfOperation op) 
     { 
      text.AppendLine("------------------------------------------------------------"); 
      newSection = true; 
     } 

     private void PrintNewline(PdfOperation op) 
     { 
      text.AppendLine(); 
     } 

     private void PrintText(PdfOperation op) 
     { 
      if (newSection) 
      { 
       newSection = false; 
       StringBuilder header = new StringBuilder(); 
       PrintText(op, header); 
      } 

      PrintText(op, text); 
     } 

     private static void PrintText(PdfOperation op, StringBuilder text) 
     { 
      foreach (PdfToken t in op.Arguments) 
      { 
       switch (t.Type) 
       { 
        case PRTokeniser.TK_STRING: 
         text.Append(t.Value); 
         break; 
        case PRTokeniser.TK_NUMBER: 
         text.Append(" "); 
         break; 
       } 
      } 
     } 

     String lastFont = String.Empty; 
     String lastFontSize = String.Empty; 

     private void SetFont(PdfOperation op) 
     { 
      var args = op.Arguments.ToList(); 
      string font = args[0].Value; 
      string size = args[1].Value; 

      //if (font != lastFont || size != lastFontSize) 
      // text.AppendLine(); 

      lastFont = font; 
      lastFontSize = size; 
     } 

     String lastX = String.Empty; 
     String lastY = String.Empty; 

     private void SetMatrix(PdfOperation op) 
     { 
      var args = op.Arguments.ToList(); 
      string x = args[4].Value; 
      string y = args[5].Value; 

      if (lastY != y) 
       text.AppendLine(); 
      else if (lastX != x) 
       text.Append(" "); 

      lastX = x; 
      lastY = y; 
     } 

     String lastColor = String.Empty; 

     private void SetColor(PdfOperation op) 
     { 
      lastColor = PrintCommand(op).Replace(" ", "_"); 
     } 

     private static string PrintCommand(PdfOperation op) 
     { 
      StringBuilder text = new StringBuilder(); 
      foreach (PdfToken t in op.Arguments) 
       text.AppendFormat("{0} ", t.Value); 
      text.Append(op.Name); 
      return text.ToString(); 
     } 

    } 
} 

그리고 여기가 내가 전화하는 방법은 다음과 같습니다

당신의 PDF 파일이 얼마나 복잡한
using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.IO; 
using iTextSharp.text.pdf; 

namespace ClassLibrary1 
{ 
    public class PdfExtractor 
    { 
     public static string GetText(byte[] pdfBuffer) 
     { 
      PlainTextParsingStrategy strategy = new PlainTextParsingStrategy(); 
      ParsePdf(pdfBuffer, strategy); 
      return strategy.GetText(); 
     } 

     private static void ParsePdf(byte[] pdf, IPdfParsingStrategy strategy) 
     { 
      PdfReader reader = new PdfReader(pdf); 

      for (int i = 1; i <= reader.NumberOfPages; i++) 
      { 
       byte[] page = reader.GetPageContent(i); 
       if (page != null) 
       { 
        PRTokeniser tokenizer = new PRTokeniser(page); 
        List<PdfToken> parameters = new List<PdfToken>(); 

        while (tokenizer.NextToken()) 
        { 
         var token = PdfToken.Create(tokenizer); 
         if (token.IsOperand) 
         { 
          strategy.Execute(new PdfOperation(token, parameters)); 
          parameters.Clear(); 
         } 
         else 
         { 
          parameters.Add(token); 
         } 
        } 
       } 
      } 

     } 
    } 
} 
관련 문제