Table row breaking when Top and Bottom margin are set

Dear Sir/Madam,

Currently I am facing a issue with table row breaking when I set top and bottom margin in PageSetup. I am working on exporting html to PDF file.

Aspose.Words.Document doc = new Aspose.Words.Document();
DocumentBuilder builder = new DocumentBuilder(doc);
builder = PageSetupPDF(builder, GetCountryCode);
builder = CreatePDFHeader(builder, true, "", GetContractName);
builder = CreatePDFFooter(builder, ref html);
builder.InsertHtml(html);
NodeCollection table = doc.GetChildNodes(NodeType.Table, true);
foreach (Table tbl in table)
{
    try
    {
        foreach (Row row in tbl)
        {
            row.RowFormat.AllowBreakAcrossPages = false;
        }
    }
    catch { }
}
MemoryStream stream = new MemoryStream();
doc.Save(stream, SaveFormat.Pdf);
Aspose.Words.Section section = doc.Sections[0];
section.ClearContent();
Response.BinaryWrite(stream.ToArray());
//Creating PageSetup
//Commenting TopMargin,BottomMargin,HeaderDistance,FooterDistance works fine but if I uncomment them then the table breaks into next page even after setting AllowBreakAcrossPages = false
public static DocumentBuilder PageSetupPDF(DocumentBuilder builder, string countryCode)
{
    PageSetup ps = builder.PageSetup;
    ps.PaperSize = PaperSize.Letter;
    ps.Orientation = Aspose.Words.Orientation.Portrait;
    //ps.TopMargin = ConvertUtil.InchToPoint(.6);
    // ps.HeaderDistance = ConvertUtil.InchToPoint(.6);
    ps.LeftMargin = ps.RightMargin = ConvertUtil.InchToPoint(.7);
    // ps.FooterDistance = ConvertUtil.InchToPoint(.4);
    // ps.BottomMargin = ConvertUtil.InchToPoint(.4);
    return builder;
}

public static DocumentBuilder CreatePDFHeader(DocumentBuilder builder, bool differentFirstHeader, string firstHeaderText, string allHeaderText)
{
    Aspose.Words.Section currentSection = builder.CurrentSection;
    PageSetup pageSetup = currentSection.PageSetup;
    if (differentFirstHeader)
    {
        // Specify if we want headers/footers of the first page to be different from other pages.
        // You can also use PageSetup.OddAndEvenPagesHeaderFooter property to specify
        // different headers/footers for odd and even pages.
        pageSetup.DifferentFirstPageHeaderFooter = true;
        // — Create header for the first page. — 
        if (!string.IsNullOrEmpty(firstHeaderText))
        {
            builder.MoveToHeaderFooter(Aspose.Words.HeaderFooterType.HeaderFirst);
            builder.ParagraphFormat.Alignment = ParagraphAlignment.Center;
            builder.Write(firstHeaderText);
        }
    }
    // — Create header for pages other than first. — 
    builder.MoveToHeaderFooter(Aspose.Words.HeaderFooterType.HeaderPrimary);
    builder.StartTable();
    // Clear table borders.
    builder.CellFormat.ClearFormatting();
    builder.CellFormat.Borders.LineStyle = LineStyle.None;
    builder.CellFormat.Borders.Bottom.LineStyle = LineStyle.Single;
    builder.InsertCell();
    // Set the second cell to 2/3 of the page width.
    builder.CellFormat.PreferredWidth = PreferredWidth.FromPercent(100 \*2 / 3);
    builder.Font.Italic = true;
    builder.Write(allHeaderText);
    // Align this text to the right.
    builder.CurrentParagraph.ParagraphFormat.Alignment = ParagraphAlignment.Left;
    builder.InsertCell();
    // Set first cell to 1/3 of the page width.
    builder.CellFormat.PreferredWidth = PreferredWidth.FromPercent(100 / 3);
    builder.Font.Italic = false;
    // Insert page numbering text here.
    // It uses PAGE and NUMPAGES fields to auto calculate current page number and total number of pages.
    builder.Write("Page ");
    builder.InsertField("PAGE", "");
    builder.Write(" of ");
    builder.InsertField("NUMPAGES", "");
    // Align this text to the left.
    builder.CurrentParagraph.ParagraphFormat.Alignment = ParagraphAlignment.Right;
    builder.EndRow();
    builder.EndTable();
    builder.MoveToDocumentEnd();
    return builder;
}

public static DocumentBuilder CreatePDFFooter(DocumentBuilder builder, ref string html)
{
    //Get footer that has trademark
    //Remove it from HTML portion
    string pattern = @"<div[ a-zA-Z0-9-=;""’:></.&,]*(id=""?copyrightfooter""?|class=""?LDCopyright""?)"; *
        Match matchDivCopyright = Regex.Match(html, pattern, RegexOptions.IgnoreCase);
    string copyright = "";
    if (matchDivCopyright.Success)
    {
        int startIndex = matchDivCopyright.Index;
        int endIndex = MSWordOLandLIConversion.FindCorrespondingCloseTagPosition(html, startIndex, "div");
        string foundValue = html.Substring(startIndex, endIndex - startIndex + 6);
        html = html.Remove(startIndex, endIndex - startIndex + 6);
        pattern = @"\s[ a-zA-Z0-9-=;""’:></.&,]+\s\*";
        Match matchCopyRight = Regex.Match(foundValue, pattern, RegexOptions.IgnoreCase);
        if (matchCopyRight.Success)
        {
            copyright = matchCopyRight.Value.Replace("**", "", StringComparison.OrdinalIgnoreCase).Replace("**", "", StringComparison.OrdinalIgnoreCase)
            .Replace("**", "", StringComparison.OrdinalIgnoreCase).Replace("**", "", StringComparison.OrdinalIgnoreCase)
            .Replace("\r\n", "", StringComparison.OrdinalIgnoreCase).Replace("\n", "", StringComparison.OrdinalIgnoreCase);
        }
        else
        {
            startIndex = foundValue.IndexOf("©");
            endIndex = foundValue.IndexOf("™");
            if (startIndex != -1 && endIndex != -1)
            {
                copyright = foundValue.Substring(startIndex, (endIndex - startIndex) + 7);
            }
        }
    }
    Aspose.Words.Section currentSection = builder.CurrentSection;
    PageSetup pageSetup = currentSection.PageSetup;
    pageSetup.DifferentFirstPageHeaderFooter = true;
    //Go To First Footer and create
    builder.MoveToHeaderFooter(HeaderFooterType.FooterFirst);
    //Create a table
    builder.StartTable();
    builder.InsertCell();
    builder.Font.Size = 11;
    builder.CellFormat.PreferredWidth = PreferredWidth.FromPercent(100);
    builder.Write("Page ");
    builder.InsertField("PAGE", "");
    builder.Write(" of ");
    builder.InsertField("NUMPAGES", "");
    builder.CurrentParagraph.ParagraphFormat.Alignment = ParagraphAlignment.Right;
    builder.CellFormat.Borders.LineStyle = LineStyle.None;
    builder.EndRow();
    builder.EndTable();
    //Go to Next Footer and only set the Copy right if its last page
    builder.MoveToHeaderFooter(HeaderFooterType.FooterPrimary);
    builder.StartTable();
    // Clear table borders.
    builder.CellFormat.ClearFormatting();
    builder.CellFormat.Borders.LineStyle = LineStyle.None;
    builder.CellFormat.VerticalAlignment = CellVerticalAlignment.Bottom;
    //Left Cell
    builder.InsertCell();
    builder.Font.Size = 8;
    builder.CellFormat.PreferredWidth = PreferredWidth.FromPercent(100 / 3);
    FieldStart start = builder.InsertField("IF "", null).Start;

    builder.MoveTo(start.NextSibling.NextSibling);
    builder.InsertField("PAGE", null);
    builder.Write("*" = "");
    builder.InsertField("NUMPAGES", null); //If page == last page then set copyright
    builder.Write(" " + HttpUtility.HtmlDecode(copyright) + " ");

    builder.CurrentParagraph.ParagraphFormat.Alignment = ParagraphAlignment.Left;
    //If Footer is needed then Uncomment this one
    ////Right Cell
    //builder.InsertCell();
    //builder.Font.Size = 11;
    //builder.CellFormat.PreferredWidth = PreferredWidth.FromPercent(100 / 3);
    //FieldStart start1 = builder.InsertField("IF "", null).Start;
    //builder.Write("Page ");
    //builder.InsertField("PAGE", "");
    //builder.Write(" of ");
    //builder.InsertField("NUMPAGES", "");
    //builder.CurrentParagraph.ParagraphFormat.Alignment = ParagraphAlignment.Right;
    builder.EndRow();
    builder.EndTable();
    builder.MoveToDocumentEnd();
    return builder;
}

Please check the attached document for further info.

Thanking you,

Lakpa Sherpa

Hi Lakpa,

Thanks for your inquiry.

Please create a standalone console application (source code without compilation errors) that helps us to reproduce your problem on our end and attach it here for testing. We will investigate the issue on our side and provide you more information. Thanks for your cooperation.

Hi Tahir,

Since I am working on Web application, I have created a running Web application instead of Console.

Aspose version: 17.3.0.0

Aspose.Words for .NET

Please do check the attachment.

Thank you,

Lakpa Sherpa

Hi Lakpa,

Thanks for sharing the detail. Please note that Aspose.Words mimics the same behavior as MS Word does. We suggest you please read following article:

Keeping Tables and Rows from Breaking across Pages

RowFormat.AllowBreakAcrossPages disables row breaking across pages when its value is false. There are two table rows in your document. After setting the values of TopMargin, HeaderDistance, FooterDistance, BottomMargin, the table’s first row is not on two pages. It is on first page and second row is on second page. So, the RowFormat.AllowBreakAcrossPages property works as expected.

In your case, we suggest you please replace

foreach (Row row in tbl)
{
    row.RowFormat.AllowBreakAcrossPages = false;
}

with following code snippet to get the desired output.

NodeCollection table = doc.GetChildNodes(NodeType.Table, true);
foreach (Aspose.Words.Tables.Table tbl in table)
{
    foreach (Cell cell in tbl.GetChildNodes(NodeType.Cell, true))
    {
        // Call this method if table's cell is created on the fly
        // Newly created cell does not have paragraph inside
        cell.EnsureMinimum();
        foreach (Paragraph para in cell.Paragraphs)
            if (!(cell.ParentRow.IsLastRow && para.IsEndOfCell))
                para.ParagraphFormat.KeepWithNext = true;
    }
}

Hi Tahir,

Thank you for the information. It solved my problem.

Thank you,

Lakpa Sherpa