在.Net中阅读PDF文档

14 浏览
0 Comments

在.Net中阅读PDF文档

有没有一个开源库可以帮助我在.NET/C#中阅读/解析PDF文档?

0
0 Comments

阅读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阅读需求,对于大型或高负载的应用程序,可能需要考虑其他更强大和高效的解决方案。

0
0 Comments

在.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文件转换为可读的文本。如果在提取文本时出现问题,可以检查代码中的字符索引并进行适当的边界检查和处理,以解决问题。

0
0 Comments

从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(在一个方便的许可证下),尽管它可能有些过时。

0