在.Net中阅读PDF文档
阅读PDF文档在.Net中是一个常见的需求。在寻找解决方法时,可以考虑使用PDFClown。然而,需要注意的是,虽然PDFClown可以帮助实现这一需求,但不推荐在大型或高负载的应用程序中使用它。PDFClown是根据LGPL许可证发布的,因此可以用于创建商业和私有软件。
解决方法:
1. 下载PDFClown库。可以在PDFClown的官方网站上找到下载链接。
2. 安装PDFClown库。将下载的PDFClown库文件添加到项目中。
3. 导入所需的命名空间。在代码中导入PDFClown库的命名空间。
4. 初始化PDF文档。使用PDFClown库的类和方法来初始化PDF文档。
5. 读取PDF文档内容。使用PDFClown库的类和方法来读取PDF文档的内容。可以使用循环来遍历文档中的每一页,并提取所需的信息。
6. 处理PDF文档数据。根据需求对读取到的PDF文档数据进行处理和分析。
7. 关闭PDF文档。在完成对PDF文档的操作后,使用PDFClown库的方法来关闭文档。
通过以上步骤,可以使用PDFClown库在.Net中读取PDF文档。然而,需要注意的是,PDFClown适用于一般的PDF阅读需求,对于大型或高负载的应用程序,可能需要考虑其他更强大和高效的解决方案。
在.NET中读取PDF文档的问题出现的原因是需要从PDF文件中提取文本内容。为了解决这个问题,可以使用iTextSharp库。下面是一个使用iTextSharp库的示例代码:
using System; using System.IO; using iTextSharp.text.pdf; using System.Text.RegularExpressions; namespace Spider.Utils { public class PDFParser { private static int _numberOfCharsToKeep = 15; public bool ExtractText(string inFileName, string outFileName) { StreamWriter outFile = null; try { PdfReader reader = new PdfReader(inFileName); 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)) + " "); 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(); } } public string ExtractTextFromPDFBytes(byte[] input) { if (input == null || input.Length == 0) return ""; try { string resultString = ""; bool inTextObject = false; bool nextLiteral = false; int bracketDepth = 0; 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 (inTextObject) { 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 += " "; } } } } if (bracketDepth == 0 && CheckToken(new string[] { "ET" }, previousCharacters)) { inTextObject = false; resultString += " "; } else { if ((c == '(') && (bracketDepth == 0) && (!nextLiteral)) { bracketDepth = 1; } else { if ((c == ')') && (bracketDepth == 1) && (!nextLiteral)) { bracketDepth = 0; } else { if (bracketDepth == 1) { if (c == '\\' && !nextLiteral) { resultString += c.ToString(); nextLiteral = true; } else { if (((c >= ' ') && (c <= '~')) || ((c >= 128) && (c < 255))) { resultString += c.ToString(); } nextLiteral = false; } } } } } } for (int j = 0; j < _numberOfCharsToKeep - 1; j++) { previousCharacters[j] = previousCharacters[j + 1]; } previousCharacters[_numberOfCharsToKeep - 1] = c; 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; } 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; } } }
这段代码使用iTextSharp库提供的功能,从PDF文件中提取文本内容,并将提取的文本保存到输出文件中。代码中的`ExtractText`方法接受输入文件名和输出文件名作为参数,返回一个布尔值,表示提取文本是否成功。`ExtractTextFromPDFBytes`方法使用iTextSharp库提供的功能从PDF字节数组中提取文本内容。`CleanupContent`方法清理提取的文本内容,将特殊字符替换为可读字符。`CheckToken`方法检查字符数组中是否包含特定的字符令牌。
根据用户的反馈,该代码在一些PDF文件中可能会出现问题,报告了“Index Out of Range”的错误。这可能是由于提取文本时出现了错误的字符索引。为了解决这个问题,可以检查代码中的字符索引是否超出范围,并进行适当的边界检查和处理。
使用iTextSharp库可以在.NET中读取PDF文档并提取文本内容。通过调用适当的方法,可以将PDF文件转换为可读的文本。如果在提取文本时出现问题,可以检查代码中的字符索引并进行适当的边界检查和处理,以解决问题。
从2008年回答这个问题以来,iTextSharp已经大大改进了他们的API。如果你从http://sourceforge.net/projects/itextsharp/下载他们的最新版本的API,你可以使用下面的代码片段将pdf中的所有文本提取到一个字符串中。
使用iTextSharp.text.pdf和iTextSharp.text.pdf.parser命名空间
定义一个名为PdfTextExtractor的静态类
在PdfTextExtractor类中定义一个名为pdfText的公共静态方法,该方法接受一个字符串类型的路径作为参数
在pdfText方法中,创建一个PdfReader对象,传入路径参数
创建一个空字符串text
使用一个循环遍历pdf的每一页,从每一页中提取文本,并将其添加到text字符串中
关闭PdfReader对象
返回text字符串
你可能不应该将你的类命名为PdfTextExtractor,因为它将与iTextSharp.text.pdf.parser中的类冲突。
iTextSharp已经转移到GitHub:http://github.com/itext/itextsharp
现在它是付费的商业项目。
它是AGPL许可的,所以只有在也是AGPL许可的情况下才能用于创建商业软件。如果你想开发商业的、专有的软件,你必须付费。
已经被弃用,被iText 7取代,网址是https://github.com/itext/itext7-dotnet。
**注意**如果你为一个商业公司写作,这是不可行的(与其他替代产品相比,成本太高了)。AGPL3实际上并不是开源的,除非你的项目和所有的消费者也是如此。这是一种让公司在开始时显得开源,然后直接从软件中获得巨额利润的工具。当然,人们应该得到报酬,如果他们想要的话!但这是一种诱骗和欺骗。所以要小心。
我不确定这个问题是否可以使用iText 4来解决,但AGPL许可证是在第5版引入的。之前的版本是在LGPL和MPL下可用的。所以有一个免费版本的iText(在一个方便的许可证下),尽管它可能有些过时。