【问题标题】:Getting Coordinates of string using ITextExtractionStrategy and LocationTextExtractionStrategy in Itextsharp在 Itextsharp 中使用 ITextExtractionStrategy 和 LocationTextExtractionStrategy 获取字符串的坐标
【发布时间】:2014-07-17 13:47:42
【问题描述】:

我有一个 PDF 文件,我正在使用 ITextExtractionStrategy 将其读入字符串。现在,我从字符串中获取一个像 My name is XYZ 这样的子字符串,并且需要从 PDF 文件中获取子字符串的直角坐标,但无法做到这一点。在谷歌上我知道LocationTextExtractionStrategy,但不知道如何使用它来获取坐标。

这是代码..

ITextExtractionStrategy strategy = new SimpleTextExtractionStrategy();
string currentText = PdfTextExtractor.GetTextFromPage(pdfReader, page, strategy);
currentText = Encoding.UTF8.GetString(ASCIIEncoding.Convert(Encoding.Default, Encoding.UTF8, Encoding.Default.GetBytes(currentText)));
text.Append(currentText);

string getcoordinate="My name is XYZ";

如何使用 ITEXTSHARP 获取此子字符串的直角坐标..

请帮忙。

【问题讨论】:

  • 您可能想关注this answerthis answer 的话。顺便说一句,currentText = Encoding.UTF8.GetString(ASCIIEncoding.Convert(Encoding.Default, Encoding.UTF8, Encoding.Default.GetBytes(currentText))); 的目的是什么?
  • @mkl 我已经浏览了两个答案帖子,但我很遗憾地说我无法实施。我无法开始,如何将子字符串与方法一起使用。 .如果你请指导我,这将是我的救星..
  • 查看这篇文章以将第 3 行更改为正确的内容:stackoverflow.com/a/10191879/231316
  • @ChrisHaas 我已经按照建议更改了。现在请告诉我如何解决帖子中描述的问题。
  • @ChrisHaas 你对这个问题有什么建议吗..这会有所帮助...

标签: c# itextsharp


【解决方案1】:

这是一个非常非常简单的实现版本。

在实施之前,非常了解 PDF 的“单词”、“段落”、“句子”等零概念非常重要。此外, PDF 不一定从左到右和从上到下排列,这与非 LTR 语言无关。短语“Hello World”可以这样写到 PDF 中:

Draw H at (10, 10)
Draw ell at (20, 10)
Draw rld at (90, 10)
Draw o Wo at (50, 20)

也可以写成

Draw Hello World at (10,10)

您需要实现的ITextExtractionStrategy 接口有一个名为RenderText 的方法,它会为PDF 中的每个文本块调用一次。注意我说的是“chunk”而不是“word”。在上面的第一个示例中,对于这两个词,该方法将被调用四次。在第二个例子中,这两个词会被调用一次。这是理解的非常重要的部分。 PDF 没有文字,因此 iTextSharp 也没有文字。 “单词”部分100%由你来解决。

同样,正如我上面所说,PDF 没有段落。要注意这一点的原因是因为 PDF 不能将文本换行到新行。每当您看到类似于段落的内容时,您实际上会看到一个全新的文本绘图命令,该命令具有与前一行不同的y 坐标。见this for further discussion

下面的代码是一个非常简单的实现。为此,我将LocationTextExtractionStrategy 子类化,它已经实现了ITextExtractionStrategy。在每次调用RenderText() 时,我都会找到当前块的矩形(使用Mark's code here)并将其存储起来以备后用。我正在使用这个简单的帮助类来存储这些块和矩形:

//Helper class that stores our rectangle and text
public class RectAndText {
    public iTextSharp.text.Rectangle Rect;
    public String Text;
    public RectAndText(iTextSharp.text.Rectangle rect, String text) {
        this.Rect = rect;
        this.Text = text;
    }
}

这是子类:

public class MyLocationTextExtractionStrategy : LocationTextExtractionStrategy {
    //Hold each coordinate
    public List<RectAndText> myPoints = new List<RectAndText>();

    //Automatically called for each chunk of text in the PDF
    public override void RenderText(TextRenderInfo renderInfo) {
        base.RenderText(renderInfo);

        //Get the bounding box for the chunk of text
        var bottomLeft = renderInfo.GetDescentLine().GetStartPoint();
        var topRight = renderInfo.GetAscentLine().GetEndPoint();

        //Create a rectangle from it
        var rect = new iTextSharp.text.Rectangle(
                                                bottomLeft[Vector.I1],
                                                bottomLeft[Vector.I2],
                                                topRight[Vector.I1],
                                                topRight[Vector.I2]
                                                );

        //Add this to our main collection
        this.myPoints.Add(new RectAndText(rect, renderInfo.GetText()));
    }
}

最后是上面的实现:

//Our test file
var testFile = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "test.pdf");

//Create our test file, nothing special
using (var fs = new FileStream(testFile, FileMode.Create, FileAccess.Write, FileShare.None)) {
    using (var doc = new Document()) {
        using (var writer = PdfWriter.GetInstance(doc, fs)) {
            doc.Open();

            doc.Add(new Paragraph("This is my sample file"));

            doc.Close();
        }
    }
}

//Create an instance of our strategy
var t = new MyLocationTextExtractionStrategy();

//Parse page 1 of the document above
using (var r = new PdfReader(testFile)) {
    var ex = PdfTextExtractor.GetTextFromPage(r, 1, t);
}

//Loop through each chunk found
foreach (var p in t.myPoints) {
    Console.WriteLine(string.Format("Found text {0} at {1}x{2}", p.Text, p.Rect.Left, p.Rect.Bottom));
}

我不能强调以上内容没有考虑“单词”,这取决于你。传递给RenderTextTextRenderInfo 对象有一个名为GetCharacterRenderInfos() 的方法,您可以使用它来获取更多信息。如果您不关心字体中的下降,您可能还想使用GetBaseline() instead ofGetDescentLine()`。

编辑

(我吃了一顿丰盛的午餐,所以我感觉更有帮助。)

这是MyLocationTextExtractionStrategy 的更新版本,它执行下面我的 cmets 所说的操作,即需要一个字符串来搜索并在每个块中搜索该字符串。由于列出的所有原因,这在某些/许多/大多数/所有情况下都不起作用。如果子字符串在一个块中多次存在,它也只会返回第一个实例。连字和变音符号也可能与此混淆。

public class MyLocationTextExtractionStrategy : LocationTextExtractionStrategy {
    //Hold each coordinate
    public List<RectAndText> myPoints = new List<RectAndText>();

    //The string that we're searching for
    public String TextToSearchFor { get; set; }

    //How to compare strings
    public System.Globalization.CompareOptions CompareOptions { get; set; }

    public MyLocationTextExtractionStrategy(String textToSearchFor, System.Globalization.CompareOptions compareOptions = System.Globalization.CompareOptions.None) {
        this.TextToSearchFor = textToSearchFor;
        this.CompareOptions = compareOptions;
    }

    //Automatically called for each chunk of text in the PDF
    public override void RenderText(TextRenderInfo renderInfo) {
        base.RenderText(renderInfo);

        //See if the current chunk contains the text
        var startPosition = System.Globalization.CultureInfo.CurrentCulture.CompareInfo.IndexOf(renderInfo.GetText(), this.TextToSearchFor, this.CompareOptions);

        //If not found bail
        if (startPosition < 0) {
            return;
        }

        //Grab the individual characters
        var chars = renderInfo.GetCharacterRenderInfos().Skip(startPosition).Take(this.TextToSearchFor.Length).ToList();

        //Grab the first and last character
        var firstChar = chars.First();
        var lastChar = chars.Last();


        //Get the bounding box for the chunk of text
        var bottomLeft = firstChar.GetDescentLine().GetStartPoint();
        var topRight = lastChar.GetAscentLine().GetEndPoint();

        //Create a rectangle from it
        var rect = new iTextSharp.text.Rectangle(
                                                bottomLeft[Vector.I1],
                                                bottomLeft[Vector.I2],
                                                topRight[Vector.I1],
                                                topRight[Vector.I2]
                                                );

        //Add this to our main collection
        this.myPoints.Add(new RectAndText(rect, this.TextToSearchFor));
    }

您可以像以前一样使用它,但现在构造函数有一个必需的参数:

var t = new MyLocationTextExtractionStrategy("sample");

【讨论】:

  • iTextSharp.text.Rectangle rect = new iTextSharp.text.Rectangle(60.6755f, 749.172f, 94.0195f, 735.3f);这是我需要使用子字符串坐标的代码行。我实现了你的代码并得到了结果为 36x785.516....我怎样才能这样实现?跨度>
  • 发布的代码显示了如何使用这些工具,但多次告诉您 PDF 中不存在“单词”或“子字符串”,因此 iText 也不支持它们。无法保证您正在搜索的文本是按照您正在搜索的顺序编写的。但是,如果您想假设它确实如此,请向 MyLocationTextExtractionStrategy 添加一个构造函数来获取您的搜索文本,然后使用 renderInfo.GetText() 搜索该文本,然后使用 GetCharacterRenderInfos() 获取您的边界框。
  • 通过上面提供的示例,当调用 renderInfo.GetText() 时,一次只返回一个字母,所以我永远找不到我要搜索的文本。有任何想法吗?谢谢。
  • @MariusPopa,我建议重新阅读此答案的前几段以及 EDIT 标记之前的最后一段,它可以准确地告诉您您找到了什么。您需要缓冲所有 renderInfo 对象,然后跨该数据集执行一些逻辑。
【解决方案2】:

这是一个老问题,但我把我的回答留在这里,因为我在网上找不到正确的答案。

正如 Chris Haas 所揭示的,处理单词并不容易,因为 iText 处理块。 Chris 发布的代码在我的大部分测试中都失败了,因为一个单词通常被分成不同的块(他在帖子中对此提出警告)。

为了解决这个问题,这是我使用的策略:

  1. 按字符拆分块(实际上是每个字符的 textrenderinfo 对象)
  2. 按行对字符进行分组。这并不简单,因为您必须处理块对齐。
  3. 搜索每行需要查找的单词

我把代码留在这里。我用几个文档对其进行了测试,它工作得很好,但在某些情况下它可能会失败,因为这个块 -> 单词转换有点棘手。

希望对某人有所帮助。

  class LocationTextExtractionStrategyEx : LocationTextExtractionStrategy
{
    private List<LocationTextExtractionStrategyEx.ExtendedTextChunk> m_DocChunks = new List<ExtendedTextChunk>();
    private List<LocationTextExtractionStrategyEx.LineInfo> m_LinesTextInfo = new List<LineInfo>();
    public List<SearchResult> m_SearchResultsList = new List<SearchResult>();
    private String m_SearchText;
    public const float PDF_PX_TO_MM = 0.3528f;
    public float m_PageSizeY;


    public LocationTextExtractionStrategyEx(String sSearchText, float fPageSizeY)
        : base()
    {
        this.m_SearchText = sSearchText;
        this.m_PageSizeY = fPageSizeY;
    }

    private void searchText()
    {
        foreach (LineInfo aLineInfo in m_LinesTextInfo)
        {
            int iIndex = aLineInfo.m_Text.IndexOf(m_SearchText);
            if (iIndex != -1)
            {
                TextRenderInfo aFirstLetter = aLineInfo.m_LineCharsList.ElementAt(iIndex);
                SearchResult aSearchResult = new SearchResult(aFirstLetter, m_PageSizeY);
                this.m_SearchResultsList.Add(aSearchResult);
            }
        }
    }

    private void groupChunksbyLine()
    {                     
        LocationTextExtractionStrategyEx.ExtendedTextChunk textChunk1 = null;
        LocationTextExtractionStrategyEx.LineInfo textInfo = null;
        foreach (LocationTextExtractionStrategyEx.ExtendedTextChunk textChunk2 in this.m_DocChunks)
        {
            if (textChunk1 == null)
            {                    
                textInfo = new LocationTextExtractionStrategyEx.LineInfo(textChunk2);
                this.m_LinesTextInfo.Add(textInfo);
            }
            else if (textChunk2.sameLine(textChunk1))
            {                      
                textInfo.appendText(textChunk2);
            }
            else
            {                                        
                textInfo = new LocationTextExtractionStrategyEx.LineInfo(textChunk2);
                this.m_LinesTextInfo.Add(textInfo);
            }
            textChunk1 = textChunk2;
        }
    }

    public override string GetResultantText()
    {
        groupChunksbyLine();
        searchText();
        //In this case the return value is not useful
        return "";
    }

    public override void RenderText(TextRenderInfo renderInfo)
    {
        LineSegment baseline = renderInfo.GetBaseline();
        //Create ExtendedChunk
        ExtendedTextChunk aExtendedChunk = new ExtendedTextChunk(renderInfo.GetText(), baseline.GetStartPoint(), baseline.GetEndPoint(), renderInfo.GetSingleSpaceWidth(), renderInfo.GetCharacterRenderInfos().ToList());
        this.m_DocChunks.Add(aExtendedChunk);
    }

    public class ExtendedTextChunk
    {
        public string m_text;
        private Vector m_startLocation;
        private Vector m_endLocation;
        private Vector m_orientationVector;
        private int m_orientationMagnitude;
        private int m_distPerpendicular;           
        private float m_charSpaceWidth;           
        public List<TextRenderInfo> m_ChunkChars;


        public ExtendedTextChunk(string txt, Vector startLoc, Vector endLoc, float charSpaceWidth,List<TextRenderInfo> chunkChars)
        {
            this.m_text = txt;
            this.m_startLocation = startLoc;
            this.m_endLocation = endLoc;
            this.m_charSpaceWidth = charSpaceWidth;                
            this.m_orientationVector = this.m_endLocation.Subtract(this.m_startLocation).Normalize();
            this.m_orientationMagnitude = (int)(Math.Atan2((double)this.m_orientationVector[1], (double)this.m_orientationVector[0]) * 1000.0);
            this.m_distPerpendicular = (int)this.m_startLocation.Subtract(new Vector(0.0f, 0.0f, 1f)).Cross(this.m_orientationVector)[2];                
            this.m_ChunkChars = chunkChars;

        }


        public bool sameLine(LocationTextExtractionStrategyEx.ExtendedTextChunk textChunkToCompare)
        {
            return this.m_orientationMagnitude == textChunkToCompare.m_orientationMagnitude && this.m_distPerpendicular == textChunkToCompare.m_distPerpendicular;
        }


    }

    public class SearchResult
    {
        public int iPosX;
        public int iPosY;

        public SearchResult(TextRenderInfo aCharcter, float fPageSizeY)
        {
            //Get position of upperLeft coordinate
            Vector vTopLeft = aCharcter.GetAscentLine().GetStartPoint();
            //PosX
            float fPosX = vTopLeft[Vector.I1]; 
            //PosY
            float fPosY = vTopLeft[Vector.I2];
            //Transform to mm and get y from top of page
            iPosX = Convert.ToInt32(fPosX * PDF_PX_TO_MM);
            iPosY = Convert.ToInt32((fPageSizeY - fPosY) * PDF_PX_TO_MM);
        }
    }

    public class LineInfo
    {            
        public string m_Text;
        public List<TextRenderInfo> m_LineCharsList;

        public LineInfo(LocationTextExtractionStrategyEx.ExtendedTextChunk initialTextChunk)
        {                
            this.m_Text = initialTextChunk.m_text;
            this.m_LineCharsList = initialTextChunk.m_ChunkChars;
        }

        public void appendText(LocationTextExtractionStrategyEx.ExtendedTextChunk additionalTextChunk)
        {
            m_LineCharsList.AddRange(additionalTextChunk.m_ChunkChars);
            this.m_Text += additionalTextChunk.m_text;
        }
    }
}

【讨论】:

  • 上面的代码每行只定位一次搜索到的文本。如果需要检查每行的多个出现,则在 searchText 函数中迭代搜索。
  • 好帖子!谢谢
【解决方案3】:

我知道这是一个非常老的问题,但下面是我最终要做的。只是在这里发布它,希望它对其他人有用。

以下代码将告诉您包含搜索文本的行的起始坐标。修改它以给出单词的位置应该不难。 笔记。我在 itextsharp 5.5.11.0 上对此进行了测试,在某些旧版本上无法使用

如上所述,pdf 没有单词/行或段落的概念。但是我发现LocationTextExtractionStrategy在分割线和词方面做得很好。所以我的解决方案就是以此为基础的。

免责声明:

此解决方案基于https://github.com/itext/itextsharp/blob/develop/src/core/iTextSharp/text/pdf/parser/LocationTextExtractionStrategy.cs,并且该文件有一条注释说它是开发预览。所以这在未来可能行不通。

不管怎样,代码在这里。

using System.Collections.Generic;
using iTextSharp.text.pdf.parser;

namespace Logic
{
    public class LocationTextExtractionStrategyWithPosition : LocationTextExtractionStrategy
    {
        private readonly List<TextChunk> locationalResult = new List<TextChunk>();

        private readonly ITextChunkLocationStrategy tclStrat;

        public LocationTextExtractionStrategyWithPosition() : this(new TextChunkLocationStrategyDefaultImp()) {
        }

        /**
         * Creates a new text extraction renderer, with a custom strategy for
         * creating new TextChunkLocation objects based on the input of the
         * TextRenderInfo.
         * @param strat the custom strategy
         */
        public LocationTextExtractionStrategyWithPosition(ITextChunkLocationStrategy strat)
        {
            tclStrat = strat;
        }


        private bool StartsWithSpace(string str)
        {
            if (str.Length == 0) return false;
            return str[0] == ' ';
        }


        private bool EndsWithSpace(string str)
        {
            if (str.Length == 0) return false;
            return str[str.Length - 1] == ' ';
        }

        /**
         * Filters the provided list with the provided filter
         * @param textChunks a list of all TextChunks that this strategy found during processing
         * @param filter the filter to apply.  If null, filtering will be skipped.
         * @return the filtered list
         * @since 5.3.3
         */

        private List<TextChunk> filterTextChunks(List<TextChunk> textChunks, ITextChunkFilter filter)
        {
            if (filter == null)
            {
                return textChunks;
            }

            var filtered = new List<TextChunk>();

            foreach (var textChunk in textChunks)
            {
                if (filter.Accept(textChunk))
                {
                    filtered.Add(textChunk);
                }
            }

            return filtered;
        }

        public override void RenderText(TextRenderInfo renderInfo)
        {
            LineSegment segment = renderInfo.GetBaseline();
            if (renderInfo.GetRise() != 0)
            { // remove the rise from the baseline - we do this because the text from a super/subscript render operations should probably be considered as part of the baseline of the text the super/sub is relative to 
                Matrix riseOffsetTransform = new Matrix(0, -renderInfo.GetRise());
                segment = segment.TransformBy(riseOffsetTransform);
            }
            TextChunk tc = new TextChunk(renderInfo.GetText(), tclStrat.CreateLocation(renderInfo, segment));
            locationalResult.Add(tc);
        }


        public IList<TextLocation> GetLocations()
        {

            var filteredTextChunks = filterTextChunks(locationalResult, null);
            filteredTextChunks.Sort();

            TextChunk lastChunk = null;

             var textLocations = new List<TextLocation>();

            foreach (var chunk in filteredTextChunks)
            {

                if (lastChunk == null)
                {
                    //initial
                    textLocations.Add(new TextLocation
                    {
                        Text = chunk.Text,
                        X = iTextSharp.text.Utilities.PointsToMillimeters(chunk.Location.StartLocation[0]),
                        Y = iTextSharp.text.Utilities.PointsToMillimeters(chunk.Location.StartLocation[1])
                    });

                }
                else
                {
                    if (chunk.SameLine(lastChunk))
                    {
                        var text = "";
                        // we only insert a blank space if the trailing character of the previous string wasn't a space, and the leading character of the current string isn't a space
                        if (IsChunkAtWordBoundary(chunk, lastChunk) && !StartsWithSpace(chunk.Text) && !EndsWithSpace(lastChunk.Text))
                            text += ' ';

                        text += chunk.Text;

                        textLocations[textLocations.Count - 1].Text += text;

                    }
                    else
                    {

                        textLocations.Add(new TextLocation
                        {
                            Text = chunk.Text,
                            X = iTextSharp.text.Utilities.PointsToMillimeters(chunk.Location.StartLocation[0]),
                            Y = iTextSharp.text.Utilities.PointsToMillimeters(chunk.Location.StartLocation[1])
                        });
                    }
                }
                lastChunk = chunk;
            }

            //now find the location(s) with the given texts
            return textLocations;

        }

    }

    public class TextLocation
    {
        public float X { get; set; }
        public float Y { get; set; }

        public string Text { get; set; }
    }
}

如何调用方法:

        using (var reader = new PdfReader(inputPdf))
            {

                var parser = new PdfReaderContentParser(reader);

                var strategy = parser.ProcessContent(pageNumber, new LocationTextExtractionStrategyWithPosition());

                var res = strategy.GetLocations();

                reader.Close();
             }
                var searchResult = res.Where(p => p.Text.Contains(searchText)).OrderBy(p => p.Y).Reverse().ToList();




inputPdf is a byte[] that has the pdf data

pageNumber is the page where you want to search in

【讨论】:

    【解决方案4】:

    这是在 VB.NET 中使用 LocationTextExtractionStrategy 的方法。

    类定义:

    Class TextExtractor
        Inherits LocationTextExtractionStrategy
        Implements iTextSharp.text.pdf.parser.ITextExtractionStrategy
        Public oPoints As IList(Of RectAndText) = New List(Of RectAndText)
        Public Overrides Sub RenderText(renderInfo As TextRenderInfo) 'Implements IRenderListener.RenderText
            MyBase.RenderText(renderInfo)
    
            Dim bottomLeft As Vector = renderInfo.GetDescentLine().GetStartPoint()
            Dim topRight As Vector = renderInfo.GetAscentLine().GetEndPoint() 'GetBaseline
    
            Dim rect As Rectangle = New Rectangle(bottomLeft(Vector.I1), bottomLeft(Vector.I2), topRight(Vector.I1), topRight(Vector.I2))
            oPoints.Add(New RectAndText(rect, renderInfo.GetText()))
        End Sub
    
        Private Function GetLines() As Dictionary(Of Single, ArrayList)
            Dim oLines As New Dictionary(Of Single, ArrayList)
            For Each p As RectAndText In oPoints
                Dim iBottom = p.Rect.Bottom
    
                If oLines.ContainsKey(iBottom) = False Then
                    oLines(iBottom) = New ArrayList()
                End If
    
                oLines(iBottom).Add(p)
            Next
    
            Return oLines
        End Function
    
        Public Function Find(ByVal sFind As String) As iTextSharp.text.Rectangle
            Dim oLines As Dictionary(Of Single, ArrayList) = GetLines()
    
            For Each oEntry As KeyValuePair(Of Single, ArrayList) In oLines
                'Dim iBottom As Integer = oEntry.Key
                Dim oRectAndTexts As ArrayList = oEntry.Value
                Dim sLine As String = ""
                For Each p As RectAndText In oRectAndTexts
                    sLine += p.Text
                    If sLine.IndexOf(sFind) <> -1 Then
                        Return p.Rect
                    End If
                Next
            Next
    
            Return Nothing
        End Function
    
    End Class
    
    Public Class RectAndText
        Public Rect As iTextSharp.text.Rectangle
        Public Text As String
        Public Sub New(ByVal rect As iTextSharp.text.Rectangle, ByVal text As String)
            Me.Rect = rect
            Me.Text = text
        End Sub
    End Class
    

    用法(在找到的文本右侧插入签名框)

    Sub EncryptPdf(ByVal sInFilePath As String, ByVal sOutFilePath As String)
    
            Dim oPdfReader As iTextSharp.text.pdf.PdfReader = New iTextSharp.text.pdf.PdfReader(sInFilePath)
            Dim oPdfDoc As New iTextSharp.text.Document()
            Dim oPdfWriter As PdfWriter = PdfWriter.GetInstance(oPdfDoc, New FileStream(sOutFilePath, FileMode.Create))
            'oPdfWriter.SetEncryption(PdfWriter.STRENGTH40BITS, sPassword, sPassword, PdfWriter.AllowCopy)
            oPdfDoc.Open()
    
            oPdfDoc.SetPageSize(iTextSharp.text.PageSize.LEDGER.Rotate())
    
            Dim oDirectContent As iTextSharp.text.pdf.PdfContentByte = oPdfWriter.DirectContent
            Dim iNumberOfPages As Integer = oPdfReader.NumberOfPages
            Dim iPage As Integer = 0
    
            Dim iBottomMargin As Integer = txtBottomMargin.Text '10
            Dim iLeftMargin As Integer = txtLeftMargin.Text '500
            Dim iWidth As Integer = txtWidth.Text '120
            Dim iHeight As Integer = txtHeight.Text '780
    
            Dim oStrategy As New parser.SimpleTextExtractionStrategy()
    
    
            Do While (iPage < iNumberOfPages)
                iPage += 1
                oPdfDoc.SetPageSize(oPdfReader.GetPageSizeWithRotation(iPage))
                oPdfDoc.NewPage()
    
                Dim oPdfImportedPage As iTextSharp.text.pdf.PdfImportedPage =
                oPdfWriter.GetImportedPage(oPdfReader, iPage)
                Dim iRotation As Integer = oPdfReader.GetPageRotation(iPage)
                If (iRotation = 90) Or (iRotation = 270) Then
                    oDirectContent.AddTemplate(oPdfImportedPage, 0, -1.0F, 1.0F,
                     0, 0, oPdfReader.GetPageSizeWithRotation(iPage).Height)
                Else
                    oDirectContent.AddTemplate(oPdfImportedPage, 1.0F, 0, 0, 1.0F, 0, 0)
                End If
    
                'Dim sPageText As String = parser.PdfTextExtractor.GetTextFromPage(oPdfReader, iPage, oStrategy)
                'sPageText = System.Text.Encoding.UTF8.GetString(System.Text.ASCIIEncoding.Convert(System.Text.Encoding.Default, System.Text.Encoding.UTF8, System.Text.Encoding.Default.GetBytes(sPageText)))
                'If txtFind.Text = "" OrElse sPageText.IndexOf(txtFind.Text) <> -1 Then
    
                Dim oTextExtractor As New TextExtractor()
                PdfTextExtractor.GetTextFromPage(oPdfReader, iPage, oTextExtractor) 'Initialize oTextExtractor
    
                Dim oRect As iTextSharp.text.Rectangle = oTextExtractor.Find(txtFind.Text)
                If oRect IsNot Nothing Then
                    Dim iX As Integer = oRect.Left + oRect.Width + iLeftMargin 'Move right
                    Dim iY As Integer = oRect.Bottom - iBottomMargin 'Move down
    
                    Dim field As PdfFormField = PdfFormField.CreateSignature(oPdfWriter)
                    field.SetWidget(New Rectangle(iX, iY, iX + iWidth, iY + iHeight), PdfAnnotation.HIGHLIGHT_OUTLINE)
                    field.FieldName = "myEmptySignatureField" & iPage
                    oPdfWriter.AddAnnotation(field)
                End If
    
            Loop
    
            oPdfDoc.Close()
    
        End Sub
    

    【讨论】:

      猜你喜欢
      • 2011-11-22
      • 1970-01-01
      • 1970-01-01
      • 2021-03-30
      • 2012-10-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多