从PDF文本中获取书目数据并导出到窗口表单

本文关键字:表单 窗口 数据 文本 PDF 获取 | 更新日期: 2023-09-27 18:16:51

我使用iText5 for . net从PDF中提取文本,使用下面的代码。

private void button1_Click(object sender, EventArgs e)
{
  PdfReader reader2 = new PdfReader("Scharfetter1969.pdf");
  int pagen = reader2.NumberOfPages;
  reader2.Close();
  ITextExtractionStrategy its = new iTextSharp.text.pdf.parser.SimpleTextExtractionStrategy();
  for (int i = 1; i < 2; i++)
  {
    textBox1.Text = "";
    PdfReader reader = new PdfReader("Scharfetter1969.pdf");
    String s = PdfTextExtractor.GetTextFromPage(reader, i, its);
    s = Encoding.UTF8.GetString(ASCIIEncoding.Convert(Encoding.Default, Encoding.UTF8, Encoding.Default.GetBytes(s)));
    textBox1.Text = s;
    reader.Close();
  }
}

但是我想从研究论文pdf中得到书目数据。

这是从这个pdf(尾注格式)中提取的数据示例,这里有一个链接!

%0 Journal Article
%T Repeated temperature modulation epitaxy for p-type doping and light-emitting diode based on ZnO
%A Tsukazaki, A.
%A Ohtomo, A.
%A Onuma, T.
%A Ohtani, M.
%A Makino, T.
%A Sumiya, M.
%A Ohtani, K.
%A Chichibu, S.F.
%A Fuke, S.
%A Segawa, Y.
%J Nature Materials
%V 4
%N 1
%P 42-46
%@ 1476-1122
%D 2004
%I Nature Publishing Group

但请记住,这是书目信息,它在此pdf的元数据中不可用。我想访问文章类型(%O),标题(%T),作者(%A),日期(%D)和(%I),并以窗口形式将其显示给不同的指定文本框。

我正在使用c#,如果有人对此有任何代码,或指导我如何做到这一点。

从PDF文本中获取书目数据并导出到窗口表单

PDF是单向格式。你输入数据以便在所有设备(监视器、打印机等)上呈现一致,但格式从未打算将数据拉出来。任何这样做的尝试都将是纯粹的猜测。iText的PdfTextExtractor可以工作,但您必须根据自己的任意规则集将内容拼凑在一起,这些规则可能会因PDF而异。所提供的PDF是由InDesign创建的,它在使文本看起来很好方面做得很好,实际上使解析数据变得更加困难。

也就是说,如果您的pdf在视觉上都是一致的,那么您可以尝试在保留格式的同时取出数据,并使用格式规则来猜测哪些是什么。那篇文章会告诉你一些你能猜到的HTML格式。(如果这确实有效,我建议返回比HTML更具体的东西,但我把它留给你。)

运行它对您提供的PDF显示标题是使用字体HelveticaNeue-LightExt在大约17点,所以你可以写一个规则来寻找所有行的使用该字体在那个大小,并将它们组合在一起。作者在HelveticaNeue-Condensed中完成大约10分,所以这是另一个规则。

下面的代码是上面链接的代码的修改版本。这是一个完整的c# 2010 WinForms应用程序,目标是iTextSharp 5.1.1.0。它为提供的PDF提取标题和作者,但您需要为其他PDF和元数据调整它。具体的实现细节请参见代码中的注释。

using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using iTextSharp.text.pdf.parser;
using iTextSharp.text.pdf;
namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
        private void Form1_Load(object sender, EventArgs e)
        {
            PdfReader reader = new PdfReader(System.IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "nmat4-42.pdf"));
            TextWithFontExtractionStategy S = new TextWithFontExtractionStategy();
            string F = iTextSharp.text.pdf.parser.PdfTextExtractor.GetTextFromPage(reader, 1, S);
            //Buffers to hold various parts from the PDF
            List<string> titles = new List<string>();
            List<string> authors = new List<string>();
            //Array of lines of text
            string[] lines = F.Split(new string[] { Environment.NewLine }, StringSplitOptions.None);
            //Temporary string
            string t;
            //Loop through each line in the array
            foreach (string line in lines)
            {
                //See if the line looks like a "title"
                if (line.Contains("HelveticaNeue-LightExt") && line.Contains("font-size:17.28003"))
                {
                    //Remove the HTML tags
                    titles.Add(System.Text.RegularExpressions.Regex.Replace(line, "</?span.*?>", "").Trim());
                }
                    //See if the line looks like an "author"
                else if (line.Contains("HelveticaNeue-Condensed") && line.Contains("font-size:9.995972"))
                {
                    //Remove the HTML tags and trim extra characters
                    t = System.Text.RegularExpressions.Regex.Replace(line, "</?span.*?>", "").Trim(new char[] { ' ', ',', '*' });
                    //Make sure we have a valid name, probably need some more exceptions here, too
                    if (!string.IsNullOrWhiteSpace(t) && t != "AND")
                    {
                        authors.Add(t);
                    }
                }
            }
            //Write out the title to the console
            Console.WriteLine("Title  : {0}", string.Join(" ", titles.ToArray()));
            //Write out each author
            foreach (string author in authors)
            {
                Console.WriteLine("Author : {0}", author);
            }
            Console.WriteLine(F);
            this.Close();
        }
        public class TextWithFontExtractionStategy : iTextSharp.text.pdf.parser.ITextExtractionStrategy
        {
            //HTML buffer
            private StringBuilder result = new StringBuilder();
            //Store last used properties
            private Vector lastBaseLine;
            private string lastFont;
            private float lastFontSize;
            //http://api.itextpdf.com/itext/com/itextpdf/text/pdf/parser/TextRenderInfo.html
            private enum TextRenderMode
            {
                FillText = 0,
                StrokeText = 1,
                FillThenStrokeText = 2,
                Invisible = 3,
                FillTextAndAddToPathForClipping = 4,
                StrokeTextAndAddToPathForClipping = 5,
                FillThenStrokeTextAndAddToPathForClipping = 6,
                AddTextToPaddForClipping = 7
            }

            public void RenderText(iTextSharp.text.pdf.parser.TextRenderInfo renderInfo)
            {
                string curFont = renderInfo.GetFont().PostscriptFontName;
                //Check if faux bold is used
                if ((renderInfo.GetTextRenderMode() == (int)TextRenderMode.FillThenStrokeText))
                {
                    curFont += "-Bold";
                }
                //This code assumes that if the baseline changes then we're on a newline
                Vector curBaseline = renderInfo.GetBaseline().GetStartPoint();
                Vector topRight = renderInfo.GetAscentLine().GetEndPoint();
                iTextSharp.text.Rectangle rect = new iTextSharp.text.Rectangle(curBaseline[Vector.I1], curBaseline[Vector.I2], topRight[Vector.I1], topRight[Vector.I2]);
                Single curFontSize = rect.Height;
                //See if something has changed, either the baseline, the font or the font size
                if ((this.lastBaseLine == null) || (curBaseline[Vector.I2] != lastBaseLine[Vector.I2]) || (curFontSize != lastFontSize) || (curFont != lastFont))
                {
                    //if we've put down at least one span tag close it
                    if ((this.lastBaseLine != null))
                    {
                        this.result.AppendLine("</span>");
                    }
                    //If the baseline has changed then insert a line break
                    if ((this.lastBaseLine != null) && curBaseline[Vector.I2] != lastBaseLine[Vector.I2])
                    {
                        this.result.AppendLine("<br />");
                    }
                    //Create an HTML tag with appropriate styles
                    this.result.AppendFormat("<span style='"font-family:{0};font-size:{1}'">", curFont, curFontSize);
                }
                //Append the current text
                this.result.Append(renderInfo.GetText());
                //Set currently used properties
                this.lastBaseLine = curBaseline;
                this.lastFontSize = curFontSize;
                this.lastFont = curFont;
            }
            public string GetResultantText()
            {
                //If we wrote anything then we'll always have a missing closing tag so close it here
                if (result.Length > 0)
                {
                    result.Append("</span>");
                }
                return result.ToString();
            }
            //Not needed
            public void BeginTextBlock() { }
            public void EndTextBlock() { }
            public void RenderImage(ImageRenderInfo renderInfo) { }
        }
    }
}