Get position of a Table cell in dynamically generated pdf document

hello,

I have a dynamically generated PDF document, it can have various number of pages. The document body consists of tables of variable sizes.

Somewhere in one of those tables, I want to place a visible digital signature in one of the cells. I tried inserting a text fragment into a cell and get its position, but it’s always (0,0).

Can I have some pointer?

@hao.deng

To get the position of a table cell in a dynamically generated PDF document, you can follow these steps:

  1. Create and Add the Table: First, ensure that you are correctly creating and adding the table to your PDF document. You can use the Aspose.Pdf.Table class to create a table and add it to a specific page in your document.

  2. Accessing Cell Position: After adding the table, you can access the position of a specific cell. The position of a cell can be determined by using the GetRect() method of the cell, which returns the rectangle that bounds the cell. This rectangle contains the coordinates of the cell.

  3. Inserting the Signature: Once you have the position of the cell, you can place your digital signature at that location. You can use the coordinates obtained from the cell’s rectangle to position your signature accurately.

Here is a sample code snippet demonstrating how to create a table and retrieve the position of a specific cell:

using System.IO;
using Aspose.Pdf;

namespace Aspose.Pdf.Examples
{
    public class AddTableWithSignature
    {
        public static void Run()
        {
            // Load source PDF document
            Document doc = new Document("path_to_your_pdf.pdf");
            Table table = new Table();

            // Add rows and cells to the table
            for (int row_count = 1; row_count < 3; row_count++)
            {
                Row row = table.Rows.Add();
                for (int cell_count = 1; cell_count < 4; cell_count++)
                {
                    Cell cell = row.Cells.Add("Cell (" + row_count + ", " + cell_count + ")");
                }
            }

            // Add table to the first page
            doc.Pages[1].Paragraphs.Add(table);

            // Get the position of a specific cell (e.g., first cell in the first row)
            Rectangle cellRect = table.Rows[1].Cells[1].GetRect();
            float x = cellRect.LLX; // X position
            float y = cellRect.LLY; // Y position

            // Now you can use (x, y) to place your digital signature
            // Example: Place a signature at the cell position
            // Signature logic goes here...

            // Save the updated document
            doc.Save("document_with_table_and_signature.pdf");
        }
    }
}

In this example, the GetRect() method is used to retrieve the position of the first cell in the first row of the table. You can adjust the indices to get the position of any specific cell you need.

Make sure to replace "path_to_your_pdf.pdf" with the actual path to your PDF document. This approach should help you accurately place your digital signature within the desired cell of the table.

Dear AI poster,

GetRect() is not an available method call to Cell object. I am using AsposePDF v 24.7 C#. Is this a recent API addition?

@hao.deng

Would you kindly share your sample document as well as sample code snippet with us? We will test the scenario in our environment and address it accordingly.

Dear asad.ali, here’s my sample code, it’s pretty straight forward

using Aspose.Pdf;
using Aspose.Pdf.Text;

namespace AsposePDFEval
{
    public class GenerateTable
    {
        public byte[] GeneratePDF()
        {
            byte[] rv = null;
            using(var doc = new Document())
            {
                var page = doc.Pages.Add();
                doc.PageInfo.Width = 600;
                doc.PageInfo.Height = 800;
                doc.PageInfo.Margin = new MarginInfo(20, 30, 20, 30);
                var signatureTextFragment = InsertTable(page, doc);
                var footer = new TextFragment($"\r\n\r\n\r\n\r\nReport generated at {DateTime.Now.ToLocalTime().ToString("yyyy-MM-dd HH:mm:ss \"GMT\"zzz")}");
                Console.Write("TextFragment Position: " + signatureTextFragment.Position); //always (0,0)
                footer.TextState.FontStyle = FontStyles.Italic;
                doc.Pages.Last().Paragraphs.Add(footer);
                rv = doc.SaveAsByteArray();
                
            }
            return rv;
        }

        private TextFragment InsertTable(Page page, Document doc)
        {
            var table = InsertFieldValueTable(page, "Information", false);
            NewRow(table, "Name", "my name");
            NewRow(table, "Approval", "my approval");
            NewRow(table, "Decision", "Pending");
            var rv = NewRow(table, "Digital Signature", "Siganture placeholder");
            return rv;
        }

        public Table InsertFieldValueTable(Page page, string headerText, bool withBorder = false)
        {
            TextFragment header = new TextFragment(headerText);
            page.Paragraphs.Add(header);

            var table = new Table
            {
                BackgroundColor = Color.White,
                ColumnWidths = "150 450",
            };
            if (withBorder)
            {
                table.Border = new BorderInfo(BorderSide.All, Color.Gray);
                table.DefaultCellBorder = new BorderInfo(BorderSide.All, Color.LightGray);
                table.DefaultCellPadding = new MarginInfo(2, 1, 2, 1);
            }
            page.Paragraphs.Add(table);
            return table;
        }

    
        protected void NewRow(Table table, string fieldLabel, BaseParagraph value)
        {
            var row = table.Rows.Add();
            row.DefaultCellPadding = new MarginInfo(5, 5, 5, 5);
            
            var c1= row.Cells.Add(fieldLabel);
            c1.Border = new BorderInfo(BorderSide.Bottom, Color.White);
            c1.VerticalAlignment = VerticalAlignment.Top;

            var c2= row.Cells.Add();
            c2.BackgroundColor = Color.White;
            c2.Border = new BorderInfo(BorderSide.Bottom, Color.LightGray);
            c2.Paragraphs.Add(value);
            
        }

        /// <summary>
        /// insert a row with field name column and a value column
        /// </summary>
        /// <param name="table"></param>
        /// <param name="fieldLabel"></param>
        /// <param name="value"></param>
        protected TextFragment NewRow(Table table, string fieldLabel, string value)
        {
            var text = new TextFragment(value ?? string.Empty);
            NewRow(table, fieldLabel, text);
            return text;
        }
    }

    public static class ExtensionClasses
    {
        public static byte[] SaveAsByteArray(this Aspose.Pdf.Document doc)
        {
            using (var rv = new MemoryStream())
            {
                doc.Save(rv);
                return rv.ToArray();
            }
        }
    }

    
}

Of course the entry point will call the GeneratePDF() function and save it to a file:


var outputFile = new GenerateTable().GeneratePDF();
System.IO.File.WriteAllBytes("out.pdf", outputFile);
System.Diagnostics.Process.Start("out.pdf");

out.pdf (2.5 KB)

@hao.deng

As per our understanding, you want to determine position of the above text in dynamically generated PDF document with table inside it so that you can replace it later.

The textfragment position is always (0,0) because it is still in memory and PDF is not yet saved. Once PDF is saved, you can search for the same text using TextFragmentAbsorber Class and perform your desired operation as you will be able to get page number as well as position of the textfragment this way.

Please let us know if our understandings are correct and this approach can help you in achieving your requirements.

I’ll give that a try. thank you for the pointer.