我正在使用iTextSharp来阅读pdf文档并且它已成功读取。现在我想从pdf文档中获取标签,但我不知道如何使用iTextSharp获取标签。
代码如下:
class Program
{
static void Main(string[] args)
{
var result = pdfText(@"C:\Users\Purelogics\Desktop\tranfer\tagged.pdf");
}
public static string pdfText(string path)
{
PdfReader reader = new PdfReader(path);
//This line return true that means this document is tagged
bool isTagged = reader.IsTagged();
var metadeta = reader.Metadata;
IList<Dictionary<string, object>> bookmarks = SimpleBookmark.GetBookmark(reader);
string text = string.Empty;
var title = reader.Info["Title"];
for (int page = 1; page <= reader.NumberOfPages; page++)
{
var object1 = reader.GetPdfObject(page);
text += PdfTextExtractor.GetTextFromPage(reader, page);
}
reader.Close();
return text;
}
}
答案 0 :(得分:2)
这取决于你想要对这个标记做什么。
假设您要提取标记为\P
(段落)
首先,您需要获取文档的结构树根
File inputFile = new File("input.pdf");
PdfDocument pdfDocument = new PdfDocument(new PdfReader(inputFile));
IStructureNode root = pdfDocument.getStructTreeRoot();
现在您拥有了structuretree root,您可以抓取树。通过堆栈或递归。在这个例子中,我正在使用递归。
private Set<PdfNameMCIDGroup> find(PdfDocument pdfDocument, IStructureNode node){
Set<PdfNameMCIDGroup> out = new HashSet<>();
PdfName role = node.getRole();
if(markedRoles.contains(role))
out.add(mark(pdfDocument, node));
else
for(IStructureNode kid : node.getKids())
out.addAll(find(pdfDocument, kid));
return out;
}
这就是mark
方法的样子
private PdfNameMCIDGroup mark(PdfDocument pdfDocument, IStructureNode node){
PdfNameMCIDGroup out = new PdfNameMCIDGroup(0);
Set<PdfMcr> leaves = new HashSet<>();
Stack<IStructureNode> stk = new Stack<>();
stk.push(node);
while(!stk.isEmpty()){
IStructureNode tmp = stk.pop();
if(tmp instanceof PdfMcr)
leaves.add((PdfMcr) tmp);
else
for(IStructureNode kid : tmp.getKids())
stk.push(kid);
}
// mcids
for(PdfMcr mcr : leaves){
int mcid = mcr.getMcid();
int pageNr = pdfDocument.getPageNumber(mcr.getPageObject());
out.mcids.add(mcid);
out.pageNrs.add(pageNr);
}
return out;
}
这些方法背后的想法是find
将遍历树层次结构。 mark
只要与其中一个角色匹配就会处理该节点。
这段代码让我们找到了解决方案的一半。
我们现在拥有标记为\P
我们现在需要实际提取与这些ID匹配的渲染指令。
为此,您需要编写自己的IEventListener
。此类可以传递给CanvasProcessor
,然后每次解析器处理完指令时都会收到通知。
public void eventOccurred(IEventData iEventData, EventType eventType) {
if(eventType == EventType.RENDER_TEXT)
{
TextRenderInfo tri = (TextRenderInfo) iEventData;
int mcID = tri.getMcid();
// this is where you can do something with it
}
}