2012-04-17 2 views
4

Я использую этот код для чтения pdf-контента с помощью iTextSharp. он отлично работает, когда контент является английским, но он не работает, когда контент является персидским или арабским.
Результат выглядит примерно так:
Here - образец неанглийского PDF для теста.Чтение pdf-содержимого с помощью iTextSharp в C#

Узу> Ù † ا UU»Ø¨Ù~Ø · Ø« یؿیÙ> Ù~ زؾا UU> ÙØÙ»Ù,Ù> Ù ... Ø ÛŒÙ» Ou • س  © Karl Seguin foppersian.codeplex.com www.codebetter.com 1 1 UU»Ø¨Ù~Ø · Ø« Узу> Ù † ا یؿیÙ> Ù~

همانرب لوصا یسیون مرن دیلوت رتهب رازÙا 

Что такое решение ?

public string ReadPdfFile(string fileName) 
     { 
      StringBuilder text = new StringBuilder(); 

      if (File.Exists(fileName)) 
      { 
       PdfReader pdfReader = new PdfReader(fileName); 

       for (int page = 1; page <= pdfReader.NumberOfPages; page++) 
       { 
        ITextExtractionStrategy strategy = new SimpleTextExtractionStrategy(); 
        string currentText = PdfTextExtractor.GetTextFromPage(pdfReader, page, strategy); 

        currentText = Encoding.UTF8.GetString(Encoding.Convert(Encoding.Default, Encoding.UTF8, Encoding.UTF8.GetBytes(currentText))); 
        text.Append(currentText); 
        pdfReader.Close(); 
       } 
      } 
      return text.ToString(); 
     } 
+0

Я думаю, что для арабских символов он печатает соответствующие символы юникода. Поэтому перед печатью вам нужно преобразовать их в нормальный символ/символ. – vikiiii

+0

@vikiiii Спасибо, ты хоть представляешь, как мне это сделать? – Shahin

+1

[См. Этот ответ] (http://stackoverflow.com/questions/9447648/parse-a-persian-pdf-file-to-txt-and-its-images/9454073#9454073) для примера. Но даже в этом случае ** была проблема (IIRC с 5.1.2), потому что персидский/арабский языки имеют право налево. Предложите вам попробовать последнюю версию или SVN и посмотреть, исправлена ​​ли проблема. – kuujinbo

ответ

11

В .Net, когда у вас есть строка, у вас есть строка, и это Unicode, всегда. Фактическая реализация в памяти - UTF-16, но это не имеет значения. Никогда, никогда, никогда не разлагайте строку в байты и не пытайтесь переинтерпретировать ее как другую кодировку и удалять ее как строку, потому что это не имеет смысла и почти всегда будет терпеть неудачу.

Ваша проблема эта линия:

currentText = Encoding.UTF8.GetString(Encoding.Convert(Encoding.Default, Encoding.UTF8, Encoding.UTF8.GetBytes(currentText))); 

Я собираюсь вытащить его на части в несколько линий, чтобы показать:

byte[] bytes = Encoding.UTF8.GetBytes("ی"); //bytes now holds 0xDB8C 
byte[] converted = Encoding.Convert(Encoding.Default, Encoding.UTF8, bytes);//converted now holds 0xC39BC592 
string final = Encoding.UTF8.GetString(converted);//final now holds ی 

Код будет перепутать что-либо выше 127 ASCII барьер. Отбросьте строку повторного кодирования, и вы должны быть хорошими.

Боковое примечание, вполне возможно, что все, что создает строку, делает это неправильно, это не так уж редко. Но вам необходимо исправить эту проблему до становится string, на уровне byte.

EDIT

Код должен быть точно такой же, как у вас, за исключением того, что одна линия должна быть удалена. Кроме того, независимо от того, что вы используете для отображения текста, убедитесь, что он поддерживает Unicode. Кроме того, как сказал @kuujinbo, убедитесь, что вы используете последнюю версию iTextSharp. Я тестировал это с помощью 5.2.0.0.

public string ReadPdfFile(string fileName) { 
     StringBuilder text = new StringBuilder(); 

     if (File.Exists(fileName)) { 
      PdfReader pdfReader = new PdfReader(fileName); 

      for (int page = 1; page <= pdfReader.NumberOfPages; page++) { 
       ITextExtractionStrategy strategy = new SimpleTextExtractionStrategy(); 
       string currentText = PdfTextExtractor.GetTextFromPage(pdfReader, page, strategy); 

       text.Append(currentText); 
      } 
      pdfReader.Close(); 
     } 
     return text.ToString(); 
    } 

EDIT 2

Приведенный выше код устраняет проблему кодирования, но не устанавливает порядок самих строк. К сожалению, эта проблема, похоже, находится на самом уровне PDF.

Следовательно, показывая текст в таких справа-слева системах письма требуешь либо позиционирования каждого глифа в отдельности (что является утомительным и дорогостоящий) или представляющего текст с шоу строк (см 9,2, «Организация и использование Fonts "), коды символов которого приведены в обратном порядке.

PDF 2008 Spec - 14.8.2.3.3 - Реверс-заказ Показать Струны

При повторной упорядочения строк, таких как указано выше, содержание (если я понимаю, спецификации правильно) предполагалось использовать «отмечен содержание ", BMC. Тем не менее, несколько примеров PDF-файлов, которые я просмотрел и сгенерировали, на самом деле не делают этого. Я абсолютно ошибаюсь в этой части, потому что это очень не моя специальность, поэтому вам придется больше так думать.

+0

Спасибо, сэр, Я пытаюсь исправить свои функция в соответствии с вашим ответом, но я не был успешным, вы бы полностью скопировали функцию в свой ответ? – Shahin

+0

Ваше решение работает с обычным текстом, но оно не работает, когда данные поступают из pdf для pdf с контентом «سلام» он возвращает «م لا س» – Shahin

+0

shaahin, мой код исправит вашу первую проблему, которая была просто проблемой кодирования. Ваша вторая проблема - LTR vs RTL, и, как сказал kuujunbo, это, вероятно, необходимо будет зафиксировать на уровне iText/iTextSharp. –

Смежные вопросы