使用VB.NET或C#中的itextsharp dll读取PDF内容

时间:2010-03-31 05:56:06

标签: c# vb.net pdf itextsharp

如何使用带有Pdfreader类的itextsharp读取PDF内容。我的PDF可能包含纯文本或文本图像。

7 个答案:

答案 0 :(得分:175)

using iTextSharp.text.pdf;
using iTextSharp.text.pdf.parser;
using System.IO;

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(ASCIIEncoding.Convert(Encoding.Default, Encoding.UTF8, Encoding.Default.GetBytes(currentText)));
            text.Append(currentText);
        }
        pdfReader.Close();
    }
    return text.ToString();
}

答案 1 :(得分:19)

您无法像使用iTextSharp一样阅读和解析PDF的内容。

来自iTextSharp的SourceForge tutorial

  

您无法“解析”现有的PDF文件   使用iText,你只能“阅读”它   每页一页。

     

这是什么意思?

     

pdf格式只是一个画布   文本和图形没有放置   任何结构信息。因此   a中没有任何'iText-objects'   PDF文件。在每个页面中都会有   可能是一些'字符串',但是   你不能重建一个短语或一个   段落使用这些字符串。那里   可能是画了很多行,   但是你无法检索一个Table对象   基于这些线。简而言之:   解析PDF文件的内容是   用iText是不可能的。张贴你的   关于新闻组的问题   news://comp.text.pdf也许你   会得到一些人的答案   已经构建了可以解析PDF的工具   并提取其中的一些内容,但是   不要指望能够执行的工具   防弹转换为结构化   文本。

答案 2 :(得分:15)

LGPL / FOSS iTextSharp 4.x

var pdfReader = new PdfReader(path); //other filestream etc
byte[] pageContent = _pdfReader .GetPageContent(pageNum); //not zero based
byte[] utf8 = Encoding.Convert(Encoding.Default, Encoding.UTF8, pageContent);
string textFromPage = Encoding.UTF8.GetString(utf8);

其他答案都没有对我有用,它们似乎都针对iTextSharp的AGPL v5。我在FOSS版本中找不到SimpleTextExtractionStrategyLocationTextExtractionStrategy的任何引用。

与此相关的其他可能非常有用的东西:

const string PdfTableFormat = @"\(.*\)Tj";
Regex PdfTableRegex = new Regex(PdfTableFormat, RegexOptions.Compiled);

List<string> ExtractPdfContent(string rawPdfContent)
{
    var matches = PdfTableRegex.Matches(rawPdfContent);

    var list = matches.Cast<Match>()
        .Select(m => m.Value
            .Substring(1) //remove leading (
            .Remove(m.Value.Length - 4) //remove trailing )Tj
            .Replace(@"\)", ")") //unencode parens
            .Replace(@"\(", "(")
            .Trim()
        )
        .ToList();
    return list;
}

这将从PDF中提取仅文本数据,如果显示的文本为Foo(bar),则它将在PDF中编码为(Foo\(bar\))Tj,此方法将按预期返回Foo(bar)。此方法将从原始pdf内容中删除大量其他信息,例如位置坐标。

答案 3 :(得分:6)

这是一个基于ShravankumarKumar解决方案的VB.NET解决方案。

这只会给你文字。图像是一个不同的故事。

Public Shared Function GetTextFromPDF(PdfFileName As String) As String
    Dim oReader As New iTextSharp.text.pdf.PdfReader(PdfFileName)

    Dim sOut = ""

    For i = 1 To oReader.NumberOfPages
        Dim its As New iTextSharp.text.pdf.parser.SimpleTextExtractionStrategy

        sOut &= iTextSharp.text.pdf.parser.PdfTextExtractor.GetTextFromPage(oReader, i, its)
    Next

    Return sOut
End Function

答案 4 :(得分:5)

在我的情况下,我只想要来自PDF文档特定区域的文本,所以我在区域周围使用了一个矩形并从中提取了文本。在下面的示例中,坐标是针对整个页面的。我没有PDF创作工具,所以当需要将矩形缩小到特定位置时,我会在坐标处进行一些猜测,直到找到该区域为止。

Rectangle _pdfRect = new Rectangle(0f, 0f, 612f, 792f); // Entire page - PDF coordinate system 0,0 is bottom left corner.  72 points / inch
RenderFilter _renderfilter = new RegionTextRenderFilter(_pdfRect);
ITextExtractionStrategy _strategy = new FilteredTextRenderListener(new LocationTextExtractionStrategy(), _filter);
string _text = PdfTextExtractor.GetTextFromPage(_pdfReader, 1, _strategy);

如上述注释所述,生成的文本不会保留PDF文档中的任何格式,但我很高兴它确实保留了回车。在我的例子中,文本中有足够的常量,我能够提取我需要的值。

答案 5 :(得分:0)

Public Sub PDFTxtToPdf(ByVal sTxtfile As String, ByVal sPDFSourcefile As String)
        Dim sr As StreamReader = New StreamReader(sTxtfile)
    Dim doc As New Document()
    PdfWriter.GetInstance(doc, New FileStream(sPDFSourcefile, FileMode.Create))
    doc.Open()
    doc.Add(New Paragraph(sr.ReadToEnd()))
    doc.Close()
End Sub

答案 6 :(得分:0)

这是ShravankumarKumar的改进答案。我为页面创建了特殊的类,以便您可以基于文本行和该行中的单词访问pdf中的单词。

using iTextSharp.text.pdf;
using iTextSharp.text.pdf.parser;

//create a list of pdf pages
var pages = new List<PdfPage>();

//load the pdf into the reader. NOTE: path can also be replaced with a byte array
using (PdfReader reader = new PdfReader(path))
{
    //loop all the pages and extract the text
    for (int i = 1; i <= reader.NumberOfPages; i++)
    {
        pages.Add(new PdfPage()
        {
           content = PdfTextExtractor.GetTextFromPage(reader, i)
        });
    }
}

//use linq to create the rows and words by splitting on newline and space
pages.ForEach(x => x.rows = x.content.Split('\n').Select(y => 
    new PdfRow() { 
       content = y,
       words = y.Split(' ').ToList()
    }
).ToList());

自定义类

class PdfPage
{
    public string content { get; set; }
    public List<PdfRow> rows { get; set; }
}


class PdfRow
{
    public string content { get; set; }
    public List<string> words { get; set; }
}

现在您可以逐行获取单词和单词索引。

string myWord = pages[0].rows[12].words[4];

或者使用Linq查找包含特定单词的行。

//find the rows in a specific page containing a word
var myRows = pages[0].rows.Where(x => x.words.Any(y => y == "myWord1")).ToList();

//find the rows in all pages containing a word
var myRows = pages.SelectMany(r => r.rows).Where(x => x.words.Any(y => y == "myWord2")).ToList();