In another blog entry, we demonstrated how to create an extension method to add an auto-size functionality to Text Control Table ╰ TX Text Control .NET Server for ASP.NET
╰ TXTextControl Namespace
╰ Table Class
An instance of the Table class represents a table in a Text Control document. objects by looping through all cells of the given table, checking the length of all lines and resizing each column based on the longest detected lines.
This article shows how to auto-size a table by resizing all columns proportionally to fit into the current page width:
The Maths
To calculate the required gap (negative or positive), the total available width is required (maxWidth). This is the page size minus the left and right margin of the current section. currentWidth is calculated by totalizing all column widths in each row. The missing gap is then the maximum width minus the current width of the table row (destinationWidth).
Windows Forms, WPF, ASP.NET
This missing gap must be distributed proportionally to each cell width in the current row. The following C# code shows how to solve this using the Windows Forms, WPF or ASP.NET Text Control:
public static class TableExtender { | |
public static void AdaptSize(this Table table, TextControl TextControl) { | |
if (table == null) | |
return; | |
TextControl.PageUnit = MeasuringUnit.Twips; | |
// calculate the max available width | |
var maxWidth = TextControl.Sections.GetItem().Format.PageSize.Width - | |
TextControl.Sections.GetItem().Format.PageMargins.Left - | |
TextControl.Sections.GetItem().Format.PageMargins.Right; | |
// loop through all cells | |
for (int row = 1; row <= table.Rows.Count; row++) { | |
// reset the calculated width | |
var currentWidth = 0; | |
// row by row | |
for (int col = 1; col <= table.Columns.Count; col++) { | |
// calculate the complete width of the row | |
currentWidth += table.Cells[row, col].Width; | |
} | |
// calculate the missing gap | |
var destinationWidth = currentWidth - maxWidth; | |
// loop through all columns in current row | |
for (int col = 1; col <= table.Columns.Count; col++) { | |
// calculate the ratio percentage for each cell | |
float percentage = (float)table.Cells[row, col].Width / | |
(float)currentWidth; | |
// resize the actual cell by it's calculated ratio | |
table.Cells[row, col].Width = (int)(table.Cells[row, col].Width - | |
(destinationWidth * percentage)); | |
} | |
} | |
} | |
} |
This extension method can be called on any table in Text Control:
textControl1.Tables.GetItem().AdaptSize(textControl1); |
JavaScript
The following JavaScript function shows how to realize this using the JavaScript API of the TX Text Control online document editor:
async function adaptTable() | |
{ | |
var maxWidth = await getMaxWidth(); | |
var tableInfo = await getTableInfo(); | |
for (let row = 1; row <= tableInfo.rows ; row++) { | |
var rowWidth = await getRowWidth(row, | |
tableInfo.cols, | |
tableInfo.table); | |
var destinationWidth = rowWidth - maxWidth; | |
var tableCheck = await setRowWidth(row, | |
tableInfo.cols, | |
tableInfo.table, | |
destinationWidth, | |
rowWidth); | |
}; | |
function getMaxWidth() { | |
var maxWidth = 0; | |
var pageWidth = 0; | |
var marginLeft = 0; | |
var marginRight = 0; | |
return new Promise(resolve => { | |
TXTextControl.setPageUnit(TXTextControl.MeasuringUnit.Twips, function() { | |
TXTextControl.sections.getItem( function (section) { | |
section.format.pageSize.getWidth(function (width) { | |
pageWidth = width; | |
section.format.pageMargins.getLeft(function (left) { | |
marginLeft = left; | |
section.format.pageMargins.getRight(function (right) { | |
marginRight = right; | |
resolve(pageWidth - marginLeft - marginRight); | |
});});});});});}); | |
} | |
function getTableInfo() { | |
var cols = 0; | |
var rows = 0; | |
return new Promise(resolve => { | |
TXTextControl.tables.getItem( function (table) { | |
if (table === null) | |
return; | |
table.rows.getCount(function(rowCount) { | |
table.columns.getCount(function(colCount) { | |
var tableInfo = { | |
rows: rowCount, | |
cols: colCount, | |
table: table | |
}; | |
resolve(tableInfo); | |
});});});}); | |
} | |
function getRowWidth(row, colCount, table) { | |
return new Promise(resolve => { | |
var currentWidth = 0; | |
for (let col = 1; col <= colCount; col++) { | |
table.cells.getItem(function (cell) { | |
cell.getWidth(function (cellWidth) { | |
currentWidth = currentWidth + cellWidth; | |
if (col === colCount) | |
resolve(currentWidth); | |
}); | |
}, null, row, col);};}); | |
} | |
function setRowWidth(row, colCount, table, destinationWidth, currentWidth) { | |
return new Promise(resolve => { | |
for (let col = 1; col <= colCount; col++) { | |
// calculate the ratio percentage for each cell | |
table.cells.getItem(function (cell) { | |
cell.getWidth(function (cellWidth) { | |
var percentage = cellWidth / currentWidth; | |
cell.setWidth(parseInt(cellWidth - (destinationWidth * percentage)), function() { | |
if (col === colCount) | |
resolve(true); | |
}); | |
}); | |
}, null, row, col);};});} | |
} |
This function can be simply called and will auto-size the table at the current input position:
adaptTable(); |