Table.GetHeight() returns incorrect values

Hello,


It seems that Table.GetHeight function doesn’t return the correct values.

I have tables that I measured in Acrobat but when I use Table.GetHeight, Aspose gives me a higher value. All tables have the same settings (width, margins, cell padding, etc) the only thing that changes it the content.

One row measures 99 points in Acrobat, but 102 in Aspose.
One row measures 55 points in Acrobat, 64 in Aspose.
One row measures 121 points in Acrobat, but 134 in Aspose.

What makes these discrepancies so different from each table? Is there a bug? I’m using an older version of Aspose unfortunately, has it been fixed in newer versions?

I can supply a sample code if needs be.

Thanks and regards

Hi Alexandre,


Thanks for your inquiry. Yes, we will appreciate it if you please share your sample code and input/output document here. We will look into it and provide you information accordingly.

We are sorry for the inconvenience caused.

Best Regards,

Thank you for your prompt response.

I have attached the PDF containing the result of the sampled code.

EDIT: I use Aspose.Pdf version 8.4.1.0. I know it’s outdated. I need to know if the issue is fixed in later releases so I can ask for my employer to get a new license.

Here is the sample code, you can see at the end where I run a GetHeight() on the section tables, it gives me 190 on run time but the PDF is clearly above that, about 283 points. The texts.GetHeight() is for another purpose and doesn’t give me a problem, only the Table.GetHeigth() at the end:

Aspose.Pdf.License license = new Aspose.Pdf.License();
license.SetLicense(“WMS.Reports.Aspose.Total.lic”);
AsposePdf = new Aspose.Pdf.Generator.Pdf();
AsposePdf.PageSetup = new PageSetup()
{
PageHeight = 595,
PageWidth = 841,
Margin = new MarginInfo()
{
Left = 30,
Top = 60,
Right = 30,
Bottom = 30
}
};
Aspose.Pdf.Generator.Section section = AsposePdf.Sections.Add();
section.PageInfo = (PageSetup)AsposePdf.PageSetup.Clone();
Table table = new Table();
//table.ColumnAdjustment = ColumnAdjustmentType.AutoFitToWindow;
table.IsKeptTogether = false;
table.Margin = new MarginInfo { Left = 0, Bottom = 0, Right = 0, Top = 0 };
table.DefaultCellPadding = new MarginInfo() { Left = 2, Bottom = 4, Right = 2, Top = 4 };
table.Border = new BorderInfo((int)BorderSide.All, 0.5f);
float minHeight = 0;
float cellHeight = 0;
float width = AsposePdf.PageSetup.PageWidth - AsposePdf.PageSetup.Margin.Left - AsposePdf.PageSetup.Margin.Right;
List widths = new List();
widths.Add(width / 732 * 124);
widths.Add(width / 732 * 124);
widths.Add(width / 732 * 80);
widths.Add(width / 732 * 190);
widths.Add(width / 732 * 90);
widths.Add(width / 732 * 124);
for (int i = 0; i < widths.Count; i++)
{
table.SetColumnWidth(i, widths[i]);
}
MarginInfo defaultTextMargin = new MarginInfo() { Left = 0, Right = 0, Top = 3, Bottom = 3 };
TextInfo defaultBigFont = new TextInfo() { FontSize = 8.5f, FontName = “Helvetica-Bold” };
TextInfo defaultSmallFont = new TextInfo() { FontSize = 8f, FontName = “Helvetica” };
//Première colonne Number Reference Priority
Text numberText = new Text(“DEF-0008”);
numberText.TextInfo = defaultBigFont;
numberText.Margin = new MarginInfo() { Left = 0, Right = 0, Top = 0, Bottom = 3 };
cellHeight = numberText.GetTextHeight(AsposePdf, widths[0]) + numberText.Margin.Top + numberText.Margin.Bottom;
Text refText = new Text(“Old DEF-013”);
refText.TextInfo = defaultSmallFont;
refText.Margin = defaultTextMargin;
cellHeight += refText.GetTextHeight(AsposePdf, widths[0]) + refText.Margin.Top + refText.Margin.Bottom;
Text prioText = new Text("[B] - Needed before hand over");
prioText.TextInfo = defaultSmallFont;
prioText.Margin = defaultTextMargin;
cellHeight += prioText.GetTextHeight(AsposePdf, widths[0]) + prioText.Margin.Top + prioText.Margin.Bottom;
minHeight = cellHeight > minHeight ? cellHeight : minHeight;
//Deuxième colonne = Package Discipline System
Text pkgText = new Text(“SGJV”);
pkgText.TextInfo = defaultBigFont;
pkgText.Margin = defaultTextMargin;
cellHeight = pkgText.GetTextHeight(AsposePdf, widths[1]) + pkgText.Margin.Top + pkgText.Margin.Bottom;
Text discText = new Text("[10730] POWER SUPPLY & DISTRIBUTION");
discText.TextInfo = defaultSmallFont;
discText.Margin = defaultTextMargin;
cellHeight += discText.GetTextHeight(AsposePdf, widths[1]) + discText.Margin.Top + discText.Margin.Bottom;
Text sysText = new Text(“S3”);
sysText.TextInfo = defaultSmallFont;
sysText.Margin = defaultTextMargin;
cellHeight += sysText.GetTextHeight(AsposePdf, widths[1]) + sysText.Margin.Top + sysText.Margin.Bottom;
minHeight = cellHeight > minHeight ? cellHeight : minHeight;
//Troisième colonne = Items
Text itemText = new Text("");
itemText.TextInfo = defaultSmallFont;
itemText.Margin = defaultTextMargin;
cellHeight = itemText.GetTextHeight(AsposePdf, widths[2]) + itemText.Margin.Top + itemText.Margin.Bottom;
minHeight = cellHeight > minHeight ? cellHeight : minHeight;
//Quatrième colonne = Details
Text descText = new Text(@“During a joint inspection with Carlos Ferreira (SGJV) on
May 22, 2014, the following grounding pad deficencies
identified by SGJV were reviewed:
1. P2-4: The I/B ground Plate was out of
position.
2. P2-4: The Center ground Plate was too low.
3. P2-4: The O/B ground Plate was out of
position and too low.
4. P2-5: The I/B ground Plate was out of
position.
5. P2-5: The O/B ground Plate was out of
position.
6. P2-6: The I/B ground Plate was out of
position.
7. P2-6: The Center ground Plate was too low.
8. P2-6: The O/B ground Plate was out of
position.
9. P2-7: The I/B ground Plate was out of
position.
10. P2-7: The O/B ground Plate was missing.
11. P2-8: Ground cable tails were missing.”);
descText.TextInfo = defaultSmallFont;
descText.Margin = defaultTextMargin;
//Cinquième colonne = Raised By/Date Action By/Required Date
Text rbText = new Text(“Simon Gould”);
rbText.TextInfo = defaultSmallFont;
rbText.Margin = defaultTextMargin;
cellHeight = rbText.GetTextHeight(AsposePdf, widths[4]) + rbText.Margin.Top + rbText.Margin.Bottom;
Text drText = new Text(“05/22/2014”);
drText.TextInfo = defaultSmallFont;
drText.Margin = new MarginInfo() { Left = 0, Right = 0, Top = 0, Bottom = 6 };
cellHeight += drText.GetTextHeight(AsposePdf, widths[4]) + drText.Margin.Top + drText.Margin.Bottom;
Text abText = new Text(“Garry Robertson”);
abText.TextInfo = defaultSmallFont;
abText.Margin = defaultTextMargin;
cellHeight += abText.GetTextHeight(AsposePdf, widths[4]) + abText.Margin.Top + abText.Margin.Bottom;
Text dreqText = new Text(“n/a”);
dreqText.TextInfo.FontName = “Helvetica”;
dreqText.TextInfo.FontSize = 8f;
dreqText.TextInfo.Color = new Color("#B8B8B8");
dreqText.Margin = defaultTextMargin;
cellHeight += dreqText.GetTextHeight(AsposePdf, widths[4]) + dreqText.Margin.Top + dreqText.Margin.Bottom;
minHeight = cellHeight > minHeight ? cellHeight : minHeight;
//Sixième colonne = Status
string statusString = “”;
int j = 0;
Text stepText = new Text();
Segment seg = new Segment(“Approval of Correction”);
seg.TextInfo.FontName = “Helvetica-Bold”;
seg.TextInfo.FontSize = 8f;
stepText.Segments.Add(seg);
seg = new Segment(" since: “);
seg.TextInfo = defaultSmallFont;
stepText.Segments.Add(seg);
seg = new Segment(“06/02/2014”);
seg.TextInfo.FontName = “Helvetica-Bold”;
seg.TextInfo.FontSize = 8f;
stepText.Segments.Add(seg);
seg = new Segment(” by: “);
seg.TextInfo = defaultSmallFont;
stepText.Segments.Add(seg);
seg = new Segment(“Simon Gould”);
seg.TextInfo.FontName = “Helvetica-Bold”;
seg.TextInfo.FontSize = 8f;
stepText.Segments.Add(seg);
stepText.Margin = defaultTextMargin;
cellHeight = stepText.GetTextHeight(AsposePdf, widths[5]) + stepText.Margin.Top + stepText.Margin.Bottom;
Text step2Text = new Text(”(2/3 steps completed)");
step2Text.TextInfo.FontName = “Helvetica”;
step2Text.TextInfo.FontSize = 7f;
step2Text.Margin = defaultTextMargin;
cellHeight += step2Text.GetTextHeight(AsposePdf, widths[5]) + step2Text.Margin.Top + step2Text.Margin.Bottom;
Text step3Text = new Text(“nno”);
step3Text.TextInfo.FontName = “ZapfDingbats”;
step3Text.TextInfo.FontSize = 7f;
step3Text.Margin = defaultTextMargin;
cellHeight += step3Text.GetTextHeight(AsposePdf, widths[5]) + step3Text.Margin.Top + step3Text.Margin.Bottom;
minHeight = cellHeight > minHeight ? cellHeight : minHeight;
Row row = table.Rows.Add();
row.VerticalAlignment = VerticalAlignmentType.Top;
//Première colonne Number Reference Priority
Cell cell = row.Cells.Add();
cell.Alignment = AlignmentType.Left;
cell.Paragraphs.Add(numberText);
cell.Paragraphs.Add(refText);
cell.Paragraphs.Add(prioText);
//Deuxième colonne = Package Discipline System
cell = row.Cells.Add();
cell.Alignment = AlignmentType.Left;
cell.Paragraphs.Add(pkgText);
cell.Paragraphs.Add(discText);
cell.Paragraphs.Add(sysText);
//Troisième colonne = Items
cell = row.Cells.Add();
cell.Alignment = AlignmentType.Left;
cell.Paragraphs.Add(itemText);
//Quatrième colonne = Details
cell = row.Cells.Add();
cell.Alignment = AlignmentType.Left;
cell.Paragraphs.Add(descText);
//Cinquième colonne = Raised By/Date Action By/Required Date
cell = row.Cells.Add();
cell.Alignment = AlignmentType.Left;
cell.Paragraphs.Add(rbText);
cell.Paragraphs.Add(drText);
cell.Paragraphs.Add(abText);
cell.Paragraphs.Add(dreqText);
//Sixième colonne = Status
cell = row.Cells.Add();
cell.Alignment = AlignmentType.Left;
cell.Paragraphs.Add(stepText);
cell.Paragraphs.Add(step2Text);
cell.Paragraphs.Add(step3Text);
section.Paragraphs.Add(table);
foreach (Table myTable in section.Paragraphs)
{
float tableHeight = myTable.GetHeight(AsposePdf);
float tableHeightWithMargins = myTable.GetHeight(AsposePdf) + myTable.Margin.Top + myTable.Margin.Bottom;
}
//FINALISATION DU RAPPORT
String outputFile = String.Join("", TempFileLocation, Guid.NewGuid(), “.pdf”);
FileStream myStream = new FileStream(outputFile, FileMode.Create);
AsposePdf.Save(myStream);
myStream.Close();

Thank you for looking into this.

Hi Alexandre,


Thanks for your sharing additional information. We have noticed the table height difference in Aspose.Pdf value and Adobe, so logged a ticket PDFNEWNET-38273 in our issue tracking system for further investigation and resolution. We will notify you as soon as we resolve it.

We are sorry for the inconvenience caused.

Best Regards,

Any updates on this? I need to know if there’s a better way to get the height of the currently drawn tables in a section so I can tell how much space left on my page there is and break my page accordingly since the automatic page breaking isn’t sufficient. Unless there is an alternative solution to what I am trying to achieve?


What I’m trying to achieve is this: In the example PDF I submitted in my previous reply, you can see there are 5 columns of information. Column #1, 2, 4 and 5 will never take more than 3-4 lines and I NEVER want them to split on a page break. However, column #3 can contain some very long text that I might have to split on 2 or even 3 pages. I tried every option to forbid a paragraph from splitting but they don’t seem to work in a table.

So I’ve resigned myself to calculate the size of my cells 1, 2, 4 and 5 and calculate the remaining height of my page by keeping count of all rows height I inserted before and checking if the remaining space of my page is shorter than the maximum height of cell 1, 2,4 and 5. If it is shorter, I force my row to go in a new page with row.IsInNewPage.

It’s actually a very simple thing to do except I can’t rely on the heights returned from the GetHeight method. Any help would be greatly appreciated.

Hi Alexandre,


Thanks for your inquiry. I am afraid your issue is still not resolved, as we have recently noticed the issue and it is still pending for investigation due to other issues already under investigation and resolution. We will notify you as soon as we made some significant progress towards issue resolution.

Moreover, in reference to your requirement. We will appreciate it if you please share two different documents, a problematic document and other with sample intended results. It would help us to understand your requirements exactly. So we will provide you information accordingly.

We are sorry for the inconvenience caused.

Best Regards,

Thank you for your response.


You can see attached three files, one with the issues with numbered comments, the other with the desired results, and a third one with the “IsKeptTogether” directive.

#1: This isn’t an issue, but it’s to highlight the section of my row that I would very much like to NOT split, ever. The large text under “details” CAN be split and, if you look at page 7-8-9, can actually split into several pages.

#2: This is the most urgent issue. In these samples, I am not using any codes to try and figure out the row heights and force it to go into a new page or not. I am simply letting Aspose do all the rendering and the page breaking, but for some unknown reasons, it puts a line straight across my text. My suspicions are targeted towards #2A, which is a Text that I add a margin to in the following manner:

drText = new Text(CurrentPunch.dateRaised.Value.ToShortDateString());
drText.TextInfo = defaultSmallFont;
drText.Margin = new MarginInfo() { Left = 0, Right = 0, Top = 0, Bottom = 6 };

#3: For unknown reasons sometimes the bottom line of my rows doesn’t draw.

#4: This is perfect example of what, ultimately, a row should look like when it’s got a very large detail. It will span multiple pages but the “core” text doesn’t split. This use case is the main reason why I can’t use “Table.IsKeptTogether”. See the third page for the generated output with “IsKeptTogether”.

#3A and #3B: #3B is at page 14. Both cases are similar: A row with a very large Detail section that breaks across multiple pages. However, for 3A, there aren’t any lines drawn at the end of the page, while 3B does.

#5: This is not urgent, but it IS something I was trying to achieve while manually calculating the remaining space and my rows heights. I don’t want Aspose to break my rows for only a single line. I want it to shrink the text until it fits into the current page if it’s only going to split one or two lines. This isn’t major but it would be nice to have a “break-threshold” (in points)option to a paragraph letting Aspose know I’d rather have my text shrunk than split a single line or two on a new page.

(By the way, I haven’t found an “Auto-fit” kind of option for cells. I had to make my own that basically took a float “cellWidth”, float “maximumHeight” and an Aspose Text object, and performed a Text.GetTextHeight() to see if it passed the maximum height, and if it did, loop through the Text.Segments and reduce each Segment.FontSize by 0.2, and recalculate until it fits. It works mostly well, but with the newly found issues with Text.GetTextHeight() I might encounter problems later).

Obviously I didn’t highlight all the repeating issues (#2 and #3) but you can see in the examples that the undesired behavior is consistent. I also tried with the latest versions of Aspose.PDF DLLs and the generated output was identical.

The “IsKeptTogether” example mostly resembles to what I would like my output to look like. The main issue with this is that large rows will skip page even if there’s only a single short row on the previous page giving huge blank sections in some pages which makes A) doesn’t look professional and B) ultimately wastes lots of paper as these reports are made to be printed.

Technical details:
  • Each rows are in fact “Tables” of a single row, since the “IsKeptTogether” directive doesn’t exist for rows but only tables.
  • Each column is composed of a single cell that, for some, contains multiple Text paragraphs.
Proposed solution: When I first tried to find options to handle these issues, my intuition was to look into IsKeptTogether and apply it directly to the Cells I didn’t want to break. Defining cells in a table that I want to be kept together and forbid Aspose from splitting, while allowing other cells to split, seems to most logical manner of handling this. Another option would be to define a “minimum break size” that would let Aspose know that it must not break a row beneath this minimum size.

I know my company just renewed its license with you. I will inquire to see if we can have some support credits to give for you guys to work on these issues.

Thank you and I hope everything is clear.

Hi Alexandre,


Thanks for your sharing the details. Please note we have fixed the reported issues in our new DOM approach. It is recommended to use new DOM approach for creating tables. I have converted your above shared sample to new approach. There is no need to calculate the cell heights manually, it would be handled by Aspose. Please give this a try with latest version of Aspose.Pdf for .NET, hopefully it will resolve the issue.

Moreover, If you have some old license, then you may request a 30 days temporary license to test the scenario with latest version.

Best Regards,