我在我的C#winform应用程序中使用iTextSharp。我想要获得PDF文件中的特定段落。这在iTextSharp中可能吗?如何在C#中使用iTextSharp获取PDF文件中的特定段落?
回答
是的,没有。
首先没有。 PDF格式没有文本结构的概念,如段落,句子甚至文字,它只是包含文本。事实是两段文本彼此接近,所以我们认为它们是结构化的,这是人类的事情。当在PDF中看到类似于三行的段落时,实际上生成PDF的程序实际上完成了将文本分成三个不相关的文本行然后在特定的x,y坐标处绘制每行的工作。更糟糕的是,根据设计者的需求,每一行文字都可能由较小的文字组成,这些文字可能是文字,甚至只是字符。所以它可能是draw "the cat in the hat" at 10,10
或者它可能是draw "t" at 10,10, then draw "h" at 14,10, then draw "e" at 18,10
等等。实际上,Adobe InDesign等设计精良的程序的PDF格式非常常见。
现在是的。其实它也许是。如果你愿意投入一点工作,你可能会让iTextSharp做你正在寻找的东西。有一个名为PdfTextExtractor
的类,它有一个名为GetTextFromPage
的方法,它将从页面获取所有原始文本。该方法的最后一个参数是一个实现接口的对象。如果您创建自己的实现此接口的类,则可以处理每个文本运行并执行自己的逻辑。
在这个界面中有一个叫做RenderText
的方法,每调用一次文本都会被调用。您将获得一个iTextSharp.text.pdf.parser.TextRenderInfo
对象,您可以从中获取运行中的原始文本以及其他内容,例如当前坐标,当前字体等。由于可视文本行可以由多个运行,您可以使用此方法将运行的基线(起始x坐标)与上一次运行进行比较,以确定它是否属于同一视线。
下面是一个接口的实现的例子:我们会做
public class TextAsParagraphsExtractionStrategy : iTextSharp.text.pdf.parser.ITextExtractionStrategy {
//Text buffer
private StringBuilder result = new StringBuilder();
//Store last used properties
private Vector lastBaseLine;
//Buffer of lines of text and their Y coordinates. NOTE, these should be exposed as properties instead of fields but are left as is for simplicity's sake
public List<string> strings = new List<String>();
public List<float> baselines = new List<float>();
//This is called whenever a run of text is encountered
public void RenderText(iTextSharp.text.pdf.parser.TextRenderInfo renderInfo) {
//This code assumes that if the baseline changes then we're on a newline
Vector curBaseline = renderInfo.GetBaseline().GetStartPoint();
//See if the baseline has changed
if ((this.lastBaseLine != null) && (curBaseline[Vector.I2] != lastBaseLine[Vector.I2])) {
//See if we have text and not just whitespace
if ((!String.IsNullOrWhiteSpace(this.result.ToString()))) {
//Mark the previous line as done by adding it to our buffers
this.baselines.Add(this.lastBaseLine[Vector.I2]);
this.strings.Add(this.result.ToString());
}
//Reset our "line" buffer
this.result.Clear();
}
//Append the current text to our line buffer
this.result.Append(renderInfo.GetText());
//Reset the last used line
this.lastBaseLine = curBaseline;
}
public string GetResultantText() {
//One last time, see if there's anything left in the buffer
if ((!String.IsNullOrWhiteSpace(this.result.ToString()))) {
this.baselines.Add(this.lastBaseLine[Vector.I2]);
this.strings.Add(this.result.ToString());
}
//We're not going to use this method to return a string, instead after callers should inspect this class's strings and baselines fields.
return null;
}
//Not needed, part of interface contract
public void BeginTextBlock() { }
public void EndTextBlock() { }
public void RenderImage(ImageRenderInfo renderInfo) { }
}
要叫它:
PdfReader reader = new PdfReader(workingFile);
TextAsParagraphsExtractionStrategy S = new TextAsParagraphsExtractionStrategy();
iTextSharp.text.pdf.parser.PdfTextExtractor.GetTextFromPage(reader, 1, S);
for (int i = 0; i < S.strings.Count; i++) {
Console.WriteLine("Line {0,-5}: {1}", S.baselines[i], S.strings[i]);
}
我们实际上从GetTextFromPage
,而是扔掉值检查工作人员的baselines
和strings
数组字段。接下来的步骤是比较基线并尝试确定如何将线条组合成段落。
我应该注意到,并非所有段落的间距都与文本的各行不同。例如,如果通过上面的代码运行下面创建的PDF,则会看到每行文本相距18个点,而不管该行是否构成新段落。如果您打开在Acrobat中创建的PDF,并覆盖除了每行的第一个字母之外的所有内容,您会发现您的眼睛甚至无法区分换行符和分段符。
using (FileStream fs = new FileStream(workingFile, FileMode.Create, FileAccess.Write, FileShare.None)) {
using (Document doc = new Document(PageSize.LETTER)) {
using (PdfWriter writer = PdfWriter.GetInstance(doc, fs)) {
doc.Open();
doc.Add(new Paragraph("Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas porttitor congue massa. Fusce posuere, magna sed pulvinar ultricies, purus lectus malesuada libero, sit amet commodo magna eros quis urna."));
doc.Add(new Paragraph("This"));
doc.Add(new Paragraph("Is"));
doc.Add(new Paragraph("A"));
doc.Add(new Paragraph("Test"));
doc.Close();
}
}
}
- 1. 如何使用iText库获取pdf文件的段落内容?
- 2. 如何使用iTextSharp在特定位置放置段落
- 3. 如何使用C#获取Word文档中的段落编号?
- 4. 如何使用vim从文本中提取特定段落?
- 5. 如何在使用iTextSharp的pdf文件中获取节目标页码?
- 6. 如何使用iTextSharp设置PDF段落或字体行高?
- 7. 如何证明Itextsharp中的段落?
- 8. 如何从一个文本文件中提取特定的段落中的R
- 9. 如何使用iTextSharp从PDF文档中的字段确定字段类型?
- 10. 获取Word文档的特定部分中的段落
- 11. 从pdf中提取段落
- 12. 如何使用microsoft.office.interop.word从word文件中获取段落和形状c#
- 13. 如何使用java在文本文件中搜索特定段落
- 14. 如何在C#中使用itextsharp或pdfsharp复制PDF文件的正文#
- 15. 如何使用iTextSharp编辑PDF文件
- 16. 使用iTextSharp在C#中旋转PDF
- 17. 从文本文件中读取特定段落matlab
- 18. 如何在古吉拉特语中使用PDF iTextSharp的
- 19. 如何使用iTextSharp在PDF中显示✔?
- 20. 如何使用带空格的itextsharp从pdf中提取文本?
- 21. 如何在C#中使用iTextSharp合并之前知道损坏的PDF文件
- 22. 如何在C#中创建SVG文件并在iTextSharp pdf中导入文件?
- 23. 使用C#中的itextsharp创建PDF文件
- 24. 如何用poi打开特定段落中的word文档?
- 25. 如何使用iTextSharp从PDF中提取高亮文本?
- 26. iTextSharp的如何在PDF文件
- 27. 在apache POI中获取段落样式,语言特定
- 28. 如何获取文件的特定部分并在C编程中使用它?
- 29. C#:特定段落后获取表的索引
- 30. 如何使用PHP删除段落中的特定单词?
@excellent explanation..i尝试这种代码来构建一个paragraph..but知道坐标位置并没有帮助me..because文本可以在任何地方在pdf..but很好的解释一致..谢谢 – 2013-07-19 09:35:27