You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

iText7定位PDF字符串后,iTextSharp PdfStamper仅盖章一处问题排查

问题根源及修复方案

我仔细看了你的代码,发现几个关键问题,其中最直接导致仅第一个定位位置盖章的原因是过早关闭了PdfStamper,另外还有一些其他问题会影响整体逻辑的正确性:


1. 致命错误:过早调用stamper.Close()

在你处理第一个匹配到的位置时,就执行了stamper.Close(),这会立即关闭PDF stamper并释放资源,后续所有页面的盖章操作都无法生效。你需要把这个调用移到所有页面处理完成之后,也就是外层For page1循环的外面。


2. 重复解析页面内容+策略未重置

  • 你在For Each location循环里又重复调用了parser.ProcessPageContent(pdfDoc.GetPage(page1)),这会重复解析同一页面,导致匹配结果重复累积。
  • RegexBasedLocationExtractionStrategy是有状态的,如果你不每页重新实例化或重置,它会保留之前页面的匹配结果,导致后续循环处理到的是所有页面的累积结果,逻辑混乱。

解决方法:每页处理前重新创建extractionStrategy和parser,确保每次只处理当前页面的内容。


3. 重复创建PdfReader实例

代码里同时创建了pdfReader和pdfReader2,这不仅浪费资源,还容易导致上下文混乱,你只需要一个PdfReader实例来处理输入PDF即可。


4. Image复用的潜在问题

xmark这个Image实例如果被多次添加,可能因为内部状态的问题无法正确显示在后续位置。建议每次使用前重新获取实例,或者克隆一个新的Image对象来避免这个问题。


修正后的代码示例

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 xmarkImagePath = "C:\Users\user\Desktop\xmark.png"
        Dim finalPDF As String = signedFolder & GetFileNameWithoutExtension(src) & " signed.pdf"

        ' 只创建一个PdfReader实例,用Using自动管理资源
        Using pdfReader = New Pdf.PdfReader(src)
            Using outputPdf As Stream = New FileStream(finalPDF, FileMode.Create, FileAccess.Write, FileShare.None)
                Using stamper = New Pdf.PdfStamper(pdfReader, outputPdf)
                    Dim pageCount = pdfReader.NumberOfPages
                    Dim counter = 0

                    Console.WriteLine(pageCount)

                    For pageNum = 1 To pageCount
                        ' 每页重新创建提取策略和解析器,避免状态累积
                        Dim extractionStrategy As New RegexBasedLocationExtractionStrategy(pattern)
                        Dim parser As New PdfCanvasProcessor(extractionStrategy)
                        parser.ProcessPageContent(New iText.Kernel.Pdf.PdfDocument(pdfReader).GetPage(pageNum))

                        Dim locationList = extractionStrategy.GetResultantLocations
                        If locationList IsNot Nothing AndAlso locationList.Count > 0 Then
                            Dim pdfContentByte = stamper.GetOverContent(pageNum)
                            For Each location As IPdfTextLocation In locationList
                                counter += 1
                                Dim xP = Math.Round(location.GetRectangle.GetX)
                                Dim yP = Math.Round(location.GetRectangle.GetY)

                                ' 每次重新获取Image实例,避免复用问题
                                Using xmarkStream As New FileStream(xmarkImagePath, FileMode.Open, FileAccess.Read, FileShare.Read)
                                    Dim xmark As Image = Image.GetInstance(xmarkStream)
                                    xmark.SetAbsolutePosition(xP - 18, yP)
                                    pdfContentByte.AddImage(xmark)
                                End Using

                                Console.WriteLine($"{pattern} {xP} {yP} located on page {pageNum} and counter is {counter}")
                            Next location
                        End If
                    Next pageNum

                    ' 所有页面处理完成后再关闭stamper
                    stamper.Close()
                End Using
            End Using
        End Using
    End Sub
End Module

额外说明

我还添加了Using语句来自动管理流和PDF对象的资源,避免内存泄漏。这样修改后,应该能在所有匹配到的位置正确添加X标记,控制台也会输出所有定位到的坐标和页码。

内容的提问来源于stack exchange,提问作者user10349555

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 07:19:59