




Вы можете посмотреть на это: http://www.codeproject.com/KB/showcase/pdfrasterizer.aspx Это не совсем бесплатно, но выглядит очень красиво.
Алекс
Может ли это помочь преобразовать PDF в необработанный текст? Кажется, этот инструмент преобразует его в изображение. Тогда мне нужна библиотека OCR :-)
PDFКлоун может помочь, но я бы не рекомендовал его для большого или интенсивного использования.
Лицензия LGPL, поэтому ее можно использовать для создания коммерческого проприетарного программного обеспечения.
Также есть LibHaru
http://libharu.org/wiki/Main_Page
Ссылка не работает. libharu.org
Также: «В настоящий момент libHaru не поддерживает чтение и редактирование существующих файлов PDF, и маловероятно, что эта поддержка когда-либо появится». Это действительно актуально?
iText - лучшая библиотека, которую я знаю. Первоначально написанный на Java, существует также порт .NET.
См. http://www.ujihara.jp/iTextdotNET/en/
Это не официальный порт, и ссылка в любом случае не работает. Официальный порт iText для .NET, iTextSharp, можно найти на GitHub: github.com/itext/itextsharp
http://www.c-sharpcorner.com/UploadFile/psingh/PDFFileGenerator12062005235236PM/PDFFileGenerator.aspx имеет открытый исходный код и может стать для вас хорошей отправной точкой.
iTextSharp - лучший вариант. Использовал его для создания паука для lucene.Net, чтобы он мог сканировать PDF.
using System;
using System.IO;
using iTextSharp.text.pdf;
using System.Text.RegularExpressions;
namespace Spider.Utils
{
/// <summary>
/// Parses a PDF file and extracts the text from it.
/// </summary>
public class PDFParser
{
/// BT = Beginning of a text object operator
/// ET = End of a text object operator
/// Td move to the start of next line
/// 5 Ts = superscript
/// -5 Ts = subscript
#region Fields
#region _numberOfCharsToKeep
/// <summary>
/// The number of characters to keep, when extracting text.
/// </summary>
private static int _numberOfCharsToKeep = 15;
#endregion
#endregion
#region ExtractText
/// <summary>
/// Extracts a text from a PDF file.
/// </summary>
/// <param name = "inFileName">the full path to the pdf file.</param>
/// <param name = "outFileName">the output file name.</param>
/// <returns>the extracted text</returns>
public bool ExtractText(string inFileName, string outFileName)
{
StreamWriter outFile = null;
try
{
// Create a reader for the given PDF file
PdfReader reader = new PdfReader(inFileName);
//outFile = File.CreateText(outFileName);
outFile = new StreamWriter(outFileName, false, System.Text.Encoding.UTF8);
Console.Write("Processing: ");
int totalLen = 68;
float charUnit = ((float)totalLen) / (float)reader.NumberOfPages;
int totalWritten = 0;
float curUnit = 0;
for (int page = 1; page <= reader.NumberOfPages; page++)
{
outFile.Write(ExtractTextFromPDFBytes(reader.GetPageContent(page)) + " ");
// Write the progress.
if (charUnit >= 1.0f)
{
for (int i = 0; i < (int)charUnit; i++)
{
Console.Write("#");
totalWritten++;
}
}
else
{
curUnit += charUnit;
if (curUnit >= 1.0f)
{
for (int i = 0; i < (int)curUnit; i++)
{
Console.Write("#");
totalWritten++;
}
curUnit = 0;
}
}
}
if (totalWritten < totalLen)
{
for (int i = 0; i < (totalLen - totalWritten); i++)
{
Console.Write("#");
}
}
return true;
}
catch
{
return false;
}
finally
{
if (outFile != null) outFile.Close();
}
}
#endregion
#region ExtractTextFromPDFBytes
/// <summary>
/// This method processes an uncompressed Adobe (text) object
/// and extracts text.
/// </summary>
/// <param name = "input">uncompressed</param>
/// <returns></returns>
public string ExtractTextFromPDFBytes(byte[] input)
{
if (input == null || input.Length == 0) return "";
try
{
string resultString = "";
// Flag showing if we are we currently inside a text object
bool inTextObject = false;
// Flag showing if the next character is literal
// e.g. '\' to get a '\' character or '\(' to get '('
bool nextLiteral = false;
// () Bracket nesting level. Text appears inside ()
int bracketDepth = 0;
// Keep previous chars to get extract numbers etc.:
char[] previousCharacters = new char[_numberOfCharsToKeep];
for (int j = 0; j < _numberOfCharsToKeep; j++) previousCharacters[j] = ' ';
for (int i = 0; i < input.Length; i++)
{
char c = (char)input[i];
if (input[i] == 213)
c = "'".ToCharArray()[0];
if (inTextObject)
{
// Position the text
if (bracketDepth == 0)
{
if (CheckToken(new string[] { "TD", "Td" }, previousCharacters))
{
resultString += "\n\r";
}
else
{
if (CheckToken(new string[] { "'", "T*", "\"" }, previousCharacters))
{
resultString += "\n";
}
else
{
if (CheckToken(new string[] { "Tj" }, previousCharacters))
{
resultString += " ";
}
}
}
}
// End of a text object, also go to a new line.
if (bracketDepth == 0 &&
CheckToken(new string[] { "ET" }, previousCharacters))
{
inTextObject = false;
resultString += " ";
}
else
{
// Start outputting text
if ((c == '(') && (bracketDepth == 0) && (!nextLiteral))
{
bracketDepth = 1;
}
else
{
// Stop outputting text
if ((c == ')') && (bracketDepth == 1) && (!nextLiteral))
{
bracketDepth = 0;
}
else
{
// Just a normal text character:
if (bracketDepth == 1)
{
// Only print out next character no matter what.
// Do not interpret.
if (c == '\' && !nextLiteral)
{
resultString += c.ToString();
nextLiteral = true;
}
else
{
if (((c >= ' ') && (c <= '~')) ||
((c >= 128) && (c < 255)))
{
resultString += c.ToString();
}
nextLiteral = false;
}
}
}
}
}
}
// Store the recent characters for
// when we have to go back for a checking
for (int j = 0; j < _numberOfCharsToKeep - 1; j++)
{
previousCharacters[j] = previousCharacters[j + 1];
}
previousCharacters[_numberOfCharsToKeep - 1] = c;
// Start of a text object
if (!inTextObject && CheckToken(new string[] { "BT" }, previousCharacters))
{
inTextObject = true;
}
}
return CleanupContent(resultString);
}
catch
{
return "";
}
}
private string CleanupContent(string text)
{
string[] patterns = { @"\\(", @"\\)", @"\226", @"\222", @"\223", @"\224", @"\340", @"\342", @"\344", @"\300", @"\302", @"\304", @"\351", @"\350", @"\352", @"\353", @"\311", @"\310", @"\312", @"\313", @"\362", @"\364", @"\366", @"\322", @"\324", @"\326", @"\354", @"\356", @"\357", @"\314", @"\316", @"\317", @"\347", @"\307", @"\371", @"\373", @"\374", @"\331", @"\333", @"\334", @"\256", @"\231", @"\253", @"\273", @"\251", @"\221"};
string[] replace = { "(", ")", "-", "'", "\"", "\"", "à", "â", "ä", "À", "Â", "Ä", "é", "è", "ê", "ë", "É", "È", "Ê", "Ë", "ò", "ô", "ö", "Ò", "Ô", "Ö", "ì", "î", "ï", "Ì", "Î", "Ï", "ç", "Ç", "ù", "û", "ü", "Ù", "Û", "Ü", "®", "™", "«", "»", "©", "'" };
for (int i = 0; i < patterns.Length; i++)
{
string regExPattern = patterns[i];
Regex regex = new Regex(regExPattern, RegexOptions.IgnoreCase);
text = regex.Replace(text, replace[i]);
}
return text;
}
#endregion
#region CheckToken
/// <summary>
/// Check if a certain 2 character token just came along (e.g. BT)
/// </summary>
/// <param name = "tokens">the searched token</param>
/// <param name = "recent">the recent character array</param>
/// <returns></returns>
private bool CheckToken(string[] tokens, char[] recent)
{
foreach (string token in tokens)
{
if ((recent[_numberOfCharsToKeep - 3] == token[0]) &&
(recent[_numberOfCharsToKeep - 2] == token[1]) &&
((recent[_numberOfCharsToKeep - 1] == ' ') ||
(recent[_numberOfCharsToKeep - 1] == 0x0d) ||
(recent[_numberOfCharsToKeep - 1] == 0x0a)) &&
((recent[_numberOfCharsToKeep - 4] == ' ') ||
(recent[_numberOfCharsToKeep - 4] == 0x0d) ||
(recent[_numberOfCharsToKeep - 4] == 0x0a))
)
{
return true;
}
}
return false;
}
#endregion
}
}
привет ceetheman, я пытался использовать код, который вы предоставили выше ... но возникла одна проблема. Некоторые мои файлы pdf читаются правильно, но в некоторых файлах pdf я получил ошибку «Индекс вне диапазона» в функции «CheckToken». не могли бы вы помочь мне решить эту проблему?
Ссылка на источник вашего примера - хорошая и вежливая идея. В этом случае тот же исходный код можно найти здесь codeproject.com/KB/cs/PDFToText.aspx
У меня проблемы с этим кодом, он возвращает gobledegook, состоящий из букв r и n. В конце концов, я использовал PDFBox.
Так странно ... Я подключил свой pdf, и в моем текстовом файле 1627 пустых строк ...
Ответ Брока Нуссера выглядит как самое современное решение, и его следует рассматривать как правильный ответ на этот вопрос.
Привет! Мне очень нравится это решение, и оно отлично работает с англоязычными PDF-документами. Однако, используя французские PDF-документы, я получаю много "\ 036" и "\ 037" в текстовом файле. Я заметил, что вы используете CleanupContent для очистки документа. Но, используя ту же логику, «\ 037» может быть «F» или «», так что я немного потерялся. Не могли бы вы подробнее объяснить использование CleanupContent? Спасибо.
aspose pdf работает неплохо. опять же, вы должны заплатить за это
public string ReadPdfFile(object Filename, DataTable ReadLibray)
{
PdfReader reader2 = new PdfReader((string)Filename);
string strText = string.Empty;
for (int page = 1; page <= reader2.NumberOfPages; page++)
{
ITextExtractionStrategy its = new iTextSharp.text.pdf.parser.SimpleTextExtractionStrategy();
PdfReader reader = new PdfReader((string)Filename);
String s = PdfTextExtractor.GetTextFromPage(reader, page, its);
s = Encoding.UTF8.GetString(ASCIIEncoding.Convert(Encoding.Default, Encoding.UTF8, Encoding.Default.GetBytes(s)));
strText = strText + s;
reader.Close();
}
return strText;
}
Единственный метод, который у меня сработал! Спасибо чувак!
PdfReader? Пожалуйста, добавьте информацию.
@DT см. iTextSharp
Поскольку последний ответ на этот вопрос был дан в 2008 году, iTextSharp значительно улучшил свой API. Если вы загрузите последнюю версию их api из http://sourceforge.net/projects/itextsharp/, вы можете использовать следующий фрагмент кода для извлечения всего текста из PDF в строку.
using iTextSharp.text.pdf;
using iTextSharp.text.pdf.parser;
namespace PdfParser
{
public static class PdfTextExtractor
{
public static string pdfText(string path)
{
PdfReader reader = new PdfReader(path);
string text = string.Empty;
for(int page = 1; page <= reader.NumberOfPages; page++)
{
text += PdfTextExtractor.GetTextFromPage(reader,page);
}
reader.Close();
return text;
}
}
}
Вероятно, вам не следует называть свой класс PdfTextExtractor, так как он будет конфликтовать с классом iTextSharp.text.pdf.parser.
iTextSharp переехал на GitHub: github.com/itext/itextsharp
возможно, ответившие здесь могли помочь здесь?
Это было просто .... Спасибо
Сейчас платят за коммерческие проекты.
@Veverke благодарим вас за добавление вашего окончательного решения в другой поток, о котором вы говорите здесь
Лицензия AGPL, поэтому ее можно использовать для создания коммерческого программного обеспечения, только если она также имеет лицензию AGPL. Если вы хотите разрабатывать коммерческое проприетарное программное обеспечение, вы должны платить.
@iTextSharp устарел и заменен на iText 7 github.com/itext/itext7-dotnet.
Если кому-то нужен полный образец рабочего консольного приложения, похожий на приведенный выше код, посмотрите qawithexperts.com/article/c-sharp/…
Взгляните на Библиотека Docotic.Pdf. Это не требует, чтобы вы открывали исходный код вашего приложения (например, iTextSharp с вирусной лицензией AGPL 3).
Docotic.Pdf можно использовать для чтения файлов PDF и извлечения текста с форматированием или без него. Пожалуйста, посмотрите статью, в которой показан как извлечь текст из PDF-файлов.
Отказ от ответственности: я работаю в Bit Miracle, разработчике библиотеки.
Только 30 дней бесплатно. Не лучший вариант ...
Ответ Брока Нуссера выглядит как самое современное решение, и его следует рассматривать как правильный ответ на этот вопрос.