【发布时间】:2019-08-30 12:24:00
【问题描述】:
我正在尝试使用 Itext7 的 RegexBasedLocationExtractionStrategy 循环遍历所述 PDF 中的所有页面来定位 PDF 中的字符串模式。例如,我正在搜索的字符串是“Conrad Noll IV,#6272795”。我想要做的是,每次我找到这个字符串的 x 和 7 坐标时,我都会使用这些坐标,从 x 坐标中减去几个点,这样我就可以在它旁边标记一个“X”(png 图像) .
这是我尝试过的代码/模块。
Imports iTextSharp.text
Imports System.IO
Imports System.IO.Path
Imports System.Text.RegularExpressions
Imports iTextSharp.text.pdf.parser
Imports System.Linq
Imports iText
Imports iText.Kernel.Pdf.Canvas.Parser.Listener
Imports iText.Kernel.Pdf.Canvas.Parser
Imports iText.Kernel.Pdf
Module Module1
Dim signedFolder = "C:\Users\xborja\Desktop\Original PDF's\Signed PDFs\"
Sub Main()
If Not Directory.Exists(signedFolder) Then
Directory.CreateDirectory(signedFolder)
End If
Dim src = "C:\Users\xborja\Desktop\Original PDF's Before Merge\TP067389.CRUZ.pdf"
Dim pattern = "Conrad Noll IV, #6272795"
Dim inputfile As Stream = New FileStream(src, FileMode.Open, FileAccess.Read, FileShare.Read)
Dim inputImage As Stream = New FileStream("C:\Users\user\source\repos\addImagePdf\addImagePdf\CN signature.png", FileMode.Open, FileAccess.Read, FileShare.Read)
Dim xmarkImage As Stream = New FileStream("C:\Users\user\Desktop\xmark.png", FileMode.Open, FileAccess.Read, FileShare.Read)
Dim finalPDF As String = signedFolder & GetFileNameWithoutExtension(src) & " signed.pdf"
Dim outputPdf As Stream = New FileStream(finalPDF, FileMode.Create, FileAccess.Write, FileShare.None)
Dim pdfReader = New iText.Kernel.Pdf.PdfReader(src)
Dim pdfReader2 = New pdf.PdfReader(inputfile)
Dim pdfDoc As iText.Kernel.Pdf.PdfDocument = New iText.Kernel.Pdf.PdfDocument(pdfReader)
Dim pageCount = pdfDoc.GetNumberOfPages
Dim pagecount2 = pdfReader2.NumberOfPages
Dim extractionStrategy As RegexBasedLocationExtractionStrategy = New RegexBasedLocationExtractionStrategy(pattern)
Dim locationList As IList(Of IPdfTextLocation) = New List(Of IPdfTextLocation)
Dim parser As PdfCanvasProcessor = New PdfCanvasProcessor(extractionStrategy)
Dim stamper = New pdf.PdfStamper(pdfReader2, outputPdf)
Dim pdfContentByte = Nothing
Dim image As Image = Image.GetInstance(inputImage)
Dim xmark As Image = Image.GetInstance(xmarkImage)
Dim xy = Nothing
Dim counter = 0
Console.WriteLine(pagecount2)
For page1 = 1 To pagecount2
parser.ProcessPageContent(pdfDoc.GetPage(page1)) ' THIS has to be outside the for each
For Each location As IPdfTextLocation In extractionStrategy.GetResultantLocations
parser.ProcessPageContent(pdfDoc.GetPage(page1))
pdfContentByte = stamper.GetOverContent(page1)
If location IsNot Nothing Then
counter += 1
Dim xP = Math.Round(location.GetRectangle.GetX)
Dim yP = Math.Round(location.GetRectangle.GetY)
xmark.SetAbsolutePosition(xP - 18, yP)
pdfContentByte.addimage(xmark)
stamper.Close()
Console.WriteLine(pattern & " " & xP & " " & yP & " located on page " & page1 & " and counter is " & counter)
End If
Next location
Next page1
End Sub
End Module
如您所见,我正在同时使用 2 个不同的阅读器,因为每个阅读器都有不同的参数,因此我尝试将两者结合使用来做一些棘手的事情。
当我运行它并向自己打印结果时,它显示了我正在搜索的字符串的正确 X 和 Y 位置数量以及正确的页数,但 itextsharp.pdfstamper 仅标记一个位置,这是第一个它找到的位置。
xmark.SetAbsolutePosition(xP - 18, yP) 是我设置的,这样当它找到 x y 坐标时,x 减去 8 从而将我的 X 图像直接移动到它的右侧,所以它看起来像名称已签出。
代码会读取所有页面,打印出搜索字符串的所有位置,但只标记其中一个,这是有原因的吗?
【问题讨论】: