2015-11-27 5 views
0

Я стараюсь конвертировать PDF (.pdf) Text (.txt) Использование iTextSharp библиотеки, но в текстовый файл Дополнительное пространство добавить между словами,iTextSharp PDF To Text Колонтитулы Read Issue


  • Содержание В PDF

"Расположение Путь: D: \ PDF Files \ Проекты \ 101-14-A \ 2015_10_12 \ Методы испытаний \ 121015.pdf"

  • Содержание в текстовый файл после преобразования PDF в текстовый файл

"L ocation Путь: D: \ PDF Files \ Projects \ 101-14-A \ 2015_10_12 \ Методы испытаний \ 121015.pdf"

  • Некоторое время я буду получать ниже содержания в текстовом файле

"Расположение Путь: D: \ Файлы PDF \ Проекты \ 101-14-A \ 2015_10_12 \ Методы испытаний \ 121015.pdf"

Я использую ниже код для Преобразование PDF в текстовый файл

Imports iTextSharp 

Private Sub Form_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load 

Dim sOut As String = String.Empty 

Dim oReader As New iTextSharp.text.pdf.PdfReader(Filepath) 

Dim strategy1 As New iTextSharp.text.pdf.parser.SimpleTextExtractionStrategy 

Dim strategy2 As New iTextSharp.text.pdf.parser.LocationTextExtractionStrategy 


sOut &= iTextSharp.text.pdf.parser.PdfTextExtractor.GetTextFromPage(oReader, 1, strategy1) 

sOut &= iTextSharp.text.pdf.parser.PdfTextExtractor.GetTextFromPage(oReader, 1, strategy2) 

End Sub 

В обоих Результат стратегии неожиданна Так, пожалуйста Кинди Replay Любой Другое

+0

Просьба поделиться с нами PDF. Дополнительные пробелы могут быть связаны либо с разрядным отступом, либо с фактически существующими (но надпечатанными) пробелами. – mkl

+0

Привет, сэр, я также сообщаю все pdf в вашей почте. Идентификатор Пожалуйста, проверьте –

+0

. Я посмотрю на это позже (скорее всего, в понедельник). – mkl

ответ

0

На первый взгляд

I проверил файлы, предоставленные OP, используя текущую версию iTextSharp 5.5.7. Прежде всего, они не показывают точной проблемы, которую ОП описывает, потому что ни один из документов даже не содержит строку Путь местоположения. Они показывают сравнимое поведение, хотя, колонтитулы, как это:

Method Path: D:\Analyst Data\Projects\879...

Здесь экстрагирования с SimpleTextExtractionStrategy действительно возвращает

M ethod Path: D:\Analyst Data\Projects\879... 
Results Path: D:\Analyst Data\Projects\879... 

Я уже объяснил некоторые фоны для этого в комментарии:

В «Пути методов» две буквы «M» и «e» не соответствуют друг другу, они фактически почти перекрываются! iText в таком случае хочет указать, что буквы неправильно следуют друг за другом, а поскольку строка не содержит небольшой задний шаг, iText выражает это с помощью символа пробела.

Но здесь ситуация отличается от ситуации OP описанной, поскольку экстракция с использованием LocationTextExtractionStrategy возвращается:

Method Path: D:\Analyst Data\Projects\879... 
Results Path: D:\Analyst Data\Projects\879... 

Таким образом, я хотел бы предложить, что ОП проверяет версию iTextSharp он использует и переключается на LocationTextExtractionStrategy текущей версии библиотеки.

Если даже после обновления до текущей версии проблема остается, пожалуйста, поделитесь PDF-файлом, с которым проблема может наблюдаться и с LocationTextExtractionStrategy.

На второй взгляд

Как О.П. настаивал, что существуют пробелы, где никто не должен быть, даже в LocationTextExtractionStrategy выходе, я действительно нашел некоторые после снова и снова искать (намек относительно местонахождение пространств будет иметь было приятно ...)

В разделе заголовка я нашел «Налист», «Оператор» и «W orkstation».

Причина для них, к сожалению, не имеет ничего общего с iText, указывающим на то, что текстовые фрагменты не соответствуют друг другу. Вместо этого причина в том, что - пробел. Например. в случае «Налиста» поток контента выглядит следующим образом:

q 
1.0 1.0 1.0 rg 
29.28 822.24 39.12 4.8 re 
f 
BT 
/F2 4.515 Tf 
0.0 0.0 0.0 rg 
0.9998 0.0 0.0 1.0 29.28 823.2 Tm 
[()] TJ 
ET 
Q 
q 
BT 
/F2 4.515 Tf 
0.0 0.0 0.0 rg 
0.9998 0.0 0.0 1.0 29.28 823.2 Tm 
[(A)30(n)21(a)18(l)65(y)21(s)-36(t)12()-15(V)137(e)71(r)14(s)-36(i)65(o)-31(n)21(:)65()-15(1)21(.)-15(6)21(.)-15(2)] TJ 
ET 
Q 

I.e. после того, как рисунок белый прямоугольник (повторно, е), пробел обращается ([()] TJ) в точно то же самое положение (0,9998 0,0 0,0 1,0 29,28 823,2 Тт) как " A 'аналитика ([(A) ...] TJ).

После сортировки фрагментов текста пространство появляется сразу после «A» (порядок символов в том же положении после сортировки произвольный), поэтому вы получаете «A nalyst».

Можно было бы подумать об изменении стратегии извлечения текста, чтобы сохранить исходный порядок символов, напечатанных в одном месте, но в конце концов могут сломать другие документы. Тем не менее ...

Более верная стратегия извлечения

Мы попытаемся настроить LocationTextExtractionStrategy сохранить порядок блоков текста которые закреплены на одной и той же позиции.

LocationTextExtractionStrategy явно произвольно в связи с этим:

virtual public int CompareTo(TextChunk rhs) { 
    if (this == rhs) return 0; // not really needed, but just in case 

    int rslt; 
    rslt = CompareInts(orientationMagnitude, rhs.orientationMagnitude); 
    if (rslt != 0) return rslt; 

    rslt = CompareInts(distPerpendicular, rhs.distPerpendicular); 
    if (rslt != 0) return rslt; 

    // note: it's never safe to check floating point numbers for equality, and if two chunks 
    // are truly right on top of each other, which one comes first or second just doesn't matter 
    // so we arbitrarily choose this way. 
    rslt = distParallelStart < rhs.distParallelStart ? -1 : 1; 

    return rslt; 
} 

(LocationTextExtractionStrategy.TextChunk)

Это произвольный выбор не только ненужным, но и нарушает договор, связанный с интерфейсом IComparable который этот метод инвентарь:

Для объектов A, B и C следуют должно быть правдой:

A.CompareTo(A) должен вернуть ноль.

Если A.CompareTo(B) возвращает ноль, то B.CompareTo(A) должен вернуть ноль.

Если A.CompareTo(B) возвращает ноль и B.CompareTo(C) возвращает ноль, то A.CompareTo(C) должен вернуть ноль.

Если A.CompareTo(B) возвращает значение, отличное от нуля, то B.CompareTo(A) должно возвращать значение противоположного знака.

Если A.CompareTo(B) возвращает значение x не равное нулю, и B.CompareTo(C) возвращает значение y одного и того же знака, что и x, то A.CompareTo(C) должна возвращать значение одного и того же знака, что и xy.

(MSDN on IComparable.CompareTo)

Особенно жирным шрифтом условие не выполнено.

Следующая стратегия удаления текста здесь не является произвольной, но сохраняет порядок, в котором текстовые фрагменты поступают в качестве конечного элемента сравнения.

class FaithfulLocationTextExtractionStrategy : LocationTextExtractionStrategy 
{ 
    public class FaithfulTextChunk : TextChunk 
    { 
     public FaithfulTextChunk(String stringValue, Vector startLocation, Vector endLocation, float charSpaceWidth, int index) 
      : base(stringValue, startLocation, endLocation, charSpaceWidth) 
     { 
      this.index = index; 
      orientationMagnitudeField = typeof(TextChunk).GetField("orientationMagnitude", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance); 
      distPerpendicularField = typeof(TextChunk).GetField("distPerpendicular", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance); 
      distParallelStartField = typeof(TextChunk).GetField("distParallelStart", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance); 
     } 

     override public int CompareTo(TextChunk rhs) 
     { 
      if (this == rhs) return 0; // not really needed, but just in case 

      if (rhs is FaithfulTextChunk) 
      { 
       int rslt; 
       rslt = CompareInts((int)orientationMagnitudeField.GetValue(this), (int)orientationMagnitudeField.GetValue(rhs)); 
       if (rslt != 0) return rslt; 

       rslt = CompareInts((int)distPerpendicularField.GetValue(this), (int)distPerpendicularField.GetValue(rhs)); 
       if (rslt != 0) return rslt; 

       rslt = CompareFloats((float)distParallelStartField.GetValue(this), (float)distParallelStartField.GetValue(rhs)); 
       if (rslt != 0) return rslt; 

       return CompareInts(index, ((FaithfulTextChunk)rhs).index); 
      } 
      else 
       return base.CompareTo(rhs); 
     } 

     private static int CompareInts(int int1, int int2) 
     { 
      return int1 == int2 ? 0 : int1 < int2 ? -1 : 1; 
     } 

     private static int CompareFloats(float float1, float float2) 
     { 
      return float1 == float2 ? 0 : float1 < float2 ? -1 : 1; 
     } 

     int index; 
     System.Reflection.FieldInfo orientationMagnitudeField, distPerpendicularField, distParallelStartField; 
    } 

    public override void RenderText(TextRenderInfo renderInfo) 
    { 
     LineSegment segment = renderInfo.GetBaseline(); 
     if (renderInfo.GetRise() != 0){ // remove the rise from the baseline - we do this because the text from a super/subscript render operations should probably be considered as part of the baseline of the text the super/sub is relative to 
      Matrix riseOffsetTransform = new Matrix(0, -renderInfo.GetRise()); 
      segment = segment.TransformBy(riseOffsetTransform); 
     } 
     TextChunk location = new FaithfulTextChunk(renderInfo.GetText(), segment.GetStartPoint(), segment.GetEndPoint(), renderInfo.GetSingleSpaceWidth(), nextIndex++); 
     getLocationalResult().Add(location);   
    } 

    public FaithfulLocationTextExtractionStrategy() 
    { 
     locationalResultField = typeof(LocationTextExtractionStrategy).GetField("locationalResult", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance); 
    } 

    List<TextChunk> getLocationalResult() 
    { 
     return (List<TextChunk>) locationalResultField.GetValue(this); 
    } 

    System.Reflection.FieldInfo locationalResultField; 
    int nextIndex = 0; 
} 

Используя эту стратегию, я извлечь «Аналитик» вместо «А nalyst», «Оператор» вместо «O perator» и «Рабочая станция» вместо «W orkstation».

Поскольку многие используемые переменные являются частными, класс использует отражение. Это может быть запрещено в некоторых контекстах. Поэтому в таких контекстах просто выполните эти изменения в копию кода LocationTextExtractionStrategy.

+0

Привет, сэр, спасибо, за ответ. Я также проверяю и тестирую тот же PDF с новой версией 5.5.7. iTextSharp, но была обнаружена одна и та же проблема. Поэтому снова я добавляю файлы PDF и текстовые файлы с обеих сторон. Чтобы вы могли проверить точный senario –

+0

Было бы проще, если бы вы просто указали примерное слово, которое нужно искать! Я снова и снова искал файл и только теперь нашел что-то: «Налист», «O-perator» и «W orkstation» во втором файле. Я буду изучать это. BTW, файлы, которые вы отправили, не помогли, содержимое текстового файла не соответствует тому, что предлагают их имена файлов. – mkl

+0

Я объяснил эти три слова пробелами в них. Есть ли еще в выходе 'LocationTextExtractionStrategy'? – mkl