Just if someone is curious: What we actually ended up having to do, was using
a single table,
more cells per row and then merging them and
fixed cell widths (not PreferredWidths).
All other avenues either didn’t display all cells with equivalent widths or had some rows stick out on the right most edge for no apparent reason (in some cases).
Something similar to this:
// data
List<List<string>> rows = null; // set data
// For equal spacing, we need to insert LCM(cell_count_of_all_rows) cells into each row and merge them appropriately:
var cellsPerRow = LeastCommonMultiple(rows.Select(cells => cells.Count).Distinct());
var totalWidth = builder.PageSetup.PageWidth - builder.PageSetup.LeftMargin - builder.PageSetup.RightMargin;
var table = builder.StartTable();
foreach (var cells in rows) // "cells" are the cells to display for the current row
{
var cellWidthPts = totalWidth / cellsPerRow;
var cellsPerCell = cellsPerRow / cells.Count; // How many cells need to be merged to one cell for the current row. (Because "cells.Count" is part of the LCM computation, this division does not have a remainder!)
foreach (var cellValue in cells)
{
var cell = builder.InsertCell();
cell.CellFormat.HorizontalMerge = CellMerge.None;
cell.CellFormat.Width = cellWidthPts;
builder.Write(cellValue);
// Merge cells, s.t. the cells will use an equal width in the table
if (cellsPerCell > 1)
{
cell.CellFormat.HorizontalMerge = CellMerge.First;
// idx 0 equals "cell"
for (var i = 1; i < cellsPerCell; i++)
{
var dummyCell = builder.InsertCell();
dummyCell.CellFormat.Width = cellWidthPts;
dummyCell.CellFormat.HorizontalMerge = CellMerge.Previous;
}
}
}
builder.EndRow();
}
builder.EndTable();
table.AutoFit(AutoFitBehavior.FixedColumnWidths);
// == Helper functions ==
private static int GreatestCommonDivisor(int n1, int n2)
{
if (n2 == 0)
return n1;
else
return GreatestCommonDivisor(n2, n1 % n2);
}
private static int LeastCommonMultiple(IEnumerable<int> numbers)
{
return numbers.Aggregate((a, b) => a * b / GreatestCommonDivisor(a, b));
}
Interesting that the behavior change lined up exactly with the 25.01 update. Did you ever try locking the table’s AutoFit settings explicitly to Fixed Column Widths before calling UpdatePageLayout()? I’ve seen that prevent Aspose from recalculating widths in ways you don’t expect. And also, thanks for posting the final solution
Yeah, we did. But because we’ve only been setting the PreferredWidth with our previous solution, and that apparently doesn’t set the Width property instantaneously ( → it only does set Width during rendering, i.e. UpdatePageLayout() → which since the update breaks in our use case…) and thus when calling table.AutoFit(AutoFitBehavior.FixedColumnWidths);, none of the cell Widths are set and subsequently all cells assume the min. required width to fit their respective contents. We explicitly want the table to use 100% of the page width though to achieve a consistent look and feel regardless of cell contents.
should use the same width per column and total width; which, due to the text length in the second row, they clearly don’t in this example…)
A final idea, we were having is to format the entire thing using even more tables. Basically making a table with one column and the required number of rows and then in each row/cell insert an entirely new table which contains the actual PreferredWidth in % and then using AutoFitBehaviour.AutoFitToWindow throughout. This obviously might misalign other stuff, e.g. like
but we haven’t been required to mess with that, because we’ve managed to achieve the posted workaround first. And of course formatting this to look pretty would have been an other nightmare…