C#: Insert Table after text in page

Hello. Can you help me. I want put my Aspose.Pdf.Table after all text in current page at existing pdf document. I can find only method Page.Paragraphs.Add(table). But in this, or in some other document, Page.Paragraphs.Count is 0. And when I put my table in page, table is placed at the top of the existing text.
Can I insert table after text in page?

@Bayer495

Thanks for contacting support.

We have already logged an issue as PDFNET-41545 in our issue tracking system, in order to add HtmlFragment after last paragraph inside a PDF document. As per my understandings, you also want to determine last paragraph of the PDF and add table right after it ends, so I have linked your post with the issue ID.

Furthermore, you may add a new page inside PDF by calling Document.Pages.Add() method and add table into newly added page. Concerning to the logged issue, as soon as the issue is resolved, we will definitely inform you within this forum thread. Please be patient and spare us little time.

We are sorry for the inconvenience.

I have similar problem. My solution is to add (empty) Graph object before adding the table.
I calculate width and height of Graph object I use the data from TextFragmentAbsorber fragments.
Here is my console app for testing (see AddInvoiceData method):

using System;
using System.Data;
using System.IO;
using System.Linq;
using Aspose.Pdf;
using Aspose.Pdf.Text;
using TextState = Aspose.Pdf.Text.TextState;
namespace ExampleConsole
{
    class Program
    {
        private const string AsposeTemplatePdf = @"c:\aspose\template.pdf";
        private const string AsposeDocumentPdf = @"c:\aspose\document.pdf";
        private static DataTable _productsDataTable;
        private static readonly Aspose.Pdf.License license = new Aspose.Pdf.License();
        static void Main()
        {
            // Set license
            license.SetLicense(@"C:\\Keys\\Aspose.Pdf.lic");
            _productsDataTable = GenerateDataTable();
            AddInvoiceData();
        }    
        private static DataTable GenerateDataTable()
        {
            var dt = new DataTable("InovoiceItems");
            dt.Columns.Add("ID", typeof(int));
            dt.Columns.Add("ItemName", typeof(string));
            dt.Columns.Add("Price", typeof(float));
            dt.Columns.Add("Qunatity", typeof(int));
            dt.Columns.Add("Summa", typeof(float));

            // Add 5 rows into the DataTable object programmatically
            var dr = dt.NewRow();
            for (var i = 0; i < 5; i++)
            {
                dr[0] = i + 1;
                dr[1] = $"Sun Glasses Type {i + 1}";
                dr[2] = 199.99;
                dr[3] = 1;
                dr[4] = 199.99;
                dt.Rows.Add(dr);
                dr = dt.NewRow();
            }
            return dt;
        }
    private static void AddInvoiceData()
        {
            //var tenants = _dbContext.Tenants.ToList();
            if (!File.Exists(AsposeTemplatePdf))
                GenerateLetterHead();
            if (File.Exists(AsposeDocumentPdf))
                File.Delete(AsposeDocumentPdf);

            // Create new a PDF document
            var document = new Document(AsposeTemplatePdf);

            //-----------------------------------            
            var pdfPage = document.Pages[1];
            // Create TextAbsorber object to find all instances            
            var textFragmentAbsorber = new TextFragmentAbsorber();

            // Accept the absorber for the page index 1
            pdfPage.Accept(textFragmentAbsorber);

            // Get the extracted text fragments
            var textFragmentCollection = textFragmentAbsorber.TextFragments;

            #region Info for debug
            foreach (TextFragment textFragment in textFragmentCollection)
            {
                Console.WriteLine($"{textFragment.Rectangle} - {textFragment.Text}");
            }

            #endregion Info for debug

            var x2 = textFragmentCollection.Cast<TextFragment>().Max(fragment => (float)fragment.Rectangle.URX);
            var x1 = textFragmentCollection.Cast<TextFragment>().Min(fragment => (float)fragment.Rectangle.LLX);

            var y1 = textFragmentCollection.Cast<TextFragment>().Min(fragment => (float)fragment.Rectangle.LLY);
            var y2 = textFragmentCollection.Cast<TextFragment>().Max(fragment => (float)fragment.Rectangle.URY);

            var width = x2 - x1;
            var height = y2 - y1;

            document.PageInfo.Margin.Left = x1;
            document.PageInfo.Margin.Top = pdfPage.PageInfo.Height - y2;

            // Create Graph object 
            // TODO: Remove border after testing
            var graph = new Aspose.Pdf.Drawing.Graph(width, height) { Border = new BorderInfo(BorderSide.All, 1) };
            // Add graph object to paragraphs collection of page instance            
            pdfPage.Paragraphs.Add(graph);

            graph.IsChangePosition = true;

            // Initializes a new instance of the Table
            var table = new Table
            {
                // Set column auto widths of the table
                ColumnWidths = "10 10 10 10 10",
                ColumnAdjustment = ColumnAdjustment.AutoFitToContent,
                // Set cell padding
                DefaultCellPadding = new MarginInfo(5, 5, 5, 5),
                // Set the table border color as Black
                Border = new BorderInfo(BorderSide.All, .5f, Color.Black),
                // Set the border for table cells as Black
                DefaultCellBorder = new BorderInfo(BorderSide.All, .2f, Color.Black),
                DefaultCellTextState = new TextState("TimesNewRoman", 10)
            };

            var paymentFormat = new TextState("TimesNewRoman", 10)
            {
                HorizontalAlignment = HorizontalAlignment.Right
            };
            table.SetColumnTextState(2, paymentFormat);
            table.SetColumnTextState(4, paymentFormat);
            table.ImportDataTable(_productsDataTable, true, 0, 1, 5, 5);

            //Repeat Header
            table.RepeatingRowsCount = 1;

            // Add table object to first page of input document
            pdfPage.Paragraphs.Add(table);

            using (var streamOut = new FileStream(AsposeDocumentPdf, FileMode.OpenOrCreate))
            {
                document.Save(streamOut);
            }
            System.Diagnostics.Process.Start(@"C:\aspose\document.pdf");
        }

        private static void GenerateLetterHead()
        {
            // Create new a PDF document
            var document = new Document()
            {
                PageInfo = new PageInfo { Margin = new MarginInfo(28, 28, 28, 28) }
            };

            var pdfPage = document.Pages.Add();
            // Initializes a new instance of the TextFragment for report's title or other text
            var textFragment = new TextFragment("Report's title or other text.");

            // Set text properties
            textFragment.TextState.FontSize = 12;
            textFragment.TextState.Font = Aspose.Pdf.Text.FontRepository.FindFont("TimesNewRoman");
            textFragment.TextState.FontStyle = Aspose.Pdf.Text.FontStyles.Bold;

            // Add text fragment object to first page of input document
            for (int i = 0; i < 3; i++)
            {
                pdfPage.Paragraphs.Add(textFragment);
            }

            using (var streamOut = new FileStream(AsposeTemplatePdf, FileMode.OpenOrCreate))
            {
                document.Save(streamOut);
            }
        }
    }
}
1 Like

Wow! It’s a wonderful solution! Thank you.

The issues you have found earlier (filed as PDFNET-41545) have been fixed in Aspose.PDF for .NET 22.2.