Algorithm 集合表宽度的可变列宽计算算法
我需要找出一个算法,该算法将计算列宽度的优化大小,如下所示:Algorithm 集合表宽度的可变列宽计算算法,algorithm,math,Algorithm,Math,我需要找出一个算法,该算法将计算列宽度的优化大小,如下所示: 表格的宽度固定在页面的大小上 列中的数据是可变的,因此列的宽度是可变的 必须对宽度进行优化,以了解何时包装列以及何时不包装列 鉴于以下数据: 'From' => '03/06/2014', 'To' => '03/06/2014', 'First Name' => 'John Doe', 'Status' => 'approved', 'Type' => 'PTO', 'Amount' => '
- 表格的宽度固定在页面的大小上
- 列中的数据是可变的,因此列的宽度是可变的
- 必须对宽度进行优化,以了解何时包装列以及何时不包装列
'From' => '03/06/2014',
'To' => '03/06/2014',
'First Name' => 'John Doe',
'Status' => 'approved',
'Type' => 'PTO',
'Amount' => '8 Hours',
'Notes' => 'Oops! Who knew I would need one more day. This should be all I need over the next week to support my trip.'
如何计算最佳列宽,以便“注释”列不会将其他列宽压缩到小于可接受的宽度
更新:我目前知道页面的宽度和字体的宽度,因此我可以计算每列的最大宽度要求。它应该填满页面上的可用空间。但是,除非必要,否则我希望列不换行。像这样:
一个简单的解决方案是为您的列指定属性;例如,您的
注释
列可以是灵活的
。然后,您可以计算所有行上每列的最大宽度,为所有非柔性列设置该宽度,然后将剩余空间均匀地(或可能按其最大宽度加权)分配给柔性列
但您也可以尝试通过一些简单的条件找出属性:
- 如果列的任何条目中有空格,则可以对其进行单词包装。在您的示例中,无法包装日期以及状态和类型条目。在正常情况下,名称不应被包装,但如果名称很长或提供了多个名称,则可以进行包装。notes列应该被包装
- 如果列的最大宽度超过(例如)所有大小均匀分布时单元格的宽度,则列应该是灵活的
function layout(table[], width, gutter, col[])
var maxw[col.length] # max. text width over all rows
var maxl[col.length] # max. width of longest word
var flex[col.length] # is column flexible?
var wrap[col.length] # can column be wrapped?
var colw[col.length] # final width of columns
foreach row in table:
for i = 0 to col.length:
cell = row[i]
maxw[i] = max(maxw[i], textwidth(cell))
if cell.find(" "):
maxl[i] = max(maxl[i], wordwidth(cell))
var left = width - (col.length - 1) * gutter
var avg = left / col.length
var nflex = 0
# determine whether columns should be flexible and assign
# width of non-flexible cells
for i = 0 to col.length:
flex[i] = (maxw[i] > 2 * avg) # ???
if flex[i]:
nflex++
else:
colw[i] = maxw[i]
left -= colw[i]
# if there is not enough space, make columns that could
# be word-wrapped flexible, too
if left < nflex * avg:
for i = 0 to col.length:
if !flex[i] and wrap[i]:
left += width[i]
colw[i] = 0
flex[i] = true
nflex += 1
# Calculate weights for flexible columns. The max width
# is capped at the page width to treat columns that have to
# be wrapped more or less equal
var tot = 0
for i = 0 to col.length:
if flex[i]:
maxw[i] = min(maxw[i], width) # ???
tot += maxw[i]
# Now assign the actual width for flexible columns. Make
# sure that it is at least as long as the longest word length
for i = 0 to col.length:
if flex[i]:
colw[i] = left * maxw[i] / tot
colw[i] = max(colw[i], maxl[i])
left -= colw[i]
return colw
功能布局(表[]、宽度、边沟、列[])
var maxw[col.length]#所有行的最大文本宽度
var maxl[col.length]#最长字的最大宽度
var flex[col.length]#列是否灵活?
var wrap[col.length]#可以对列进行包装吗?
var colw[col.length]#列的最终宽度
表中的每一行:
对于i=0到列长度:
单元格=行[i]
maxw[i]=max(maxw[i],文本宽度(单元格))
如果是单元格。查找(“”):
maxl[i]=max(maxl[i],字宽(单元格))
左侧变量=宽度-(列长度-1)*边沟
var avg=左/列长度
var nflex=0
#确定列是否应灵活并指定
#非柔性电池的宽度
对于i=0到列长度:
flex[i]=(maxw[i]>2*平均值)#???
如果flex[i]:
nflex++
其他:
colw[i]=maxw[i]
左-=colw[i]
#如果没有足够的空间,请创建可能会
#文字包装也要灵活
如果左侧
我在使用14列表的ITextPDF时遇到了类似的问题。数据是可变的,有些列可以换行,有些列不能换行
我的解决方案是使用split(“”)查找每列中最大的单词。这降低了单词、日期或数字被减半的几率。这是代码。很抱歉,我没有时间将其编辑成更通用的格式,希望它能对其他人有所帮助
//This array will store the largest word found in each of the 14 columns
int[] maxStringLengthPerColumn = new int[14];
for(int i = 0; i < maxStringLengthPerColumn.length; i++)
maxStringLengthPerColumn[i]=0;
//for each row in table...
ArrayList<PdfPRow> rows = table.getRows();
for(int a = 0; a < rows.size(); a++){
//for each cell in row
PdfPCell[] cellsInRow = rows.get(a).getCells();
for(int b = 0; b < cellsInRow.length; b++){
//Split cell contents at " " and find longest word in each cell
String[] splitCell = cellsInRow[b].getPhrase().getContent().split(" ");
//find the longest string left after split
int largestStringSize = 0;
for(int c = 0; c < splitCell.length; c++){
if(splitCell[c].length()>largestStringSize){
largestStringSize=splitCell[c].length();
}
}
if(largestStringSize>maxStringLengthPerColumn[b]){
//I found that adding 4 to the value worked, change this number to fine tune.
maxStringLengthPerColumn[b] = largestStringSize + 4;
}
}
}
/*The pdf library can set width with just an array, you may need to
convert these values to something else depending on the application. For
example if you have a width of 800 pixels, the width of col1 would be
maxStringLengthPerColumn[0] / (sum of maxString0 - 13) * 800*/
table.setWidths(maxStringLengthPerColumn);
//此数组将存储14列中每个列中找到的最大单词
int[]maxStringLengthPerColumn=新的int[14];
对于(int i=0;ilargestStringSize){
largestStringSize=splitCell[c]。长度();
}
}
if(最大StringSize>maxStringLengthPerColumn[b]){
//我发现在值上加4有效,将这个数字改为微调。
MaxStringLength Percolumn[b]=最大StringSize+4;
}
}
}
/*pdf库可以通过一个数组设置宽度,您可能需要
根据应用程序,将这些值转换为其他值。对于
例如,如果宽度为800像素,则wid