Algorithm 从合并单元格中查找原始行高和列宽
我有一些由框架生成的表格,我有单元格的大小和坐标。但是,我现在需要将其导出到另一种格式,并且这种特定格式没有每个单元格的大小,它只有行和列的大小 例如,我有一个3×6的表格,有很多合并的单元格:Algorithm 从合并单元格中查找原始行高和列宽,algorithm,Algorithm,我有一些由框架生成的表格,我有单元格的大小和坐标。但是,我现在需要将其导出到另一种格式,并且这种特定格式没有每个单元格的大小,它只有行和列的大小 例如,我有一个3×6的表格,有很多合并的单元格: [0]{CellSize(0,0):w:8.5H:7.111111} [1] {CellSize(0,1):w:48.5h:3.88889} [2] {CellSize(1,0):w:26.83333 h:3.22222} [3] {细胞大小(1,1):w:4.166667 h:3.22222} [4
- [0]{CellSize(0,0):w:8.5H:7.111111}
- [1] {CellSize(0,1):w:48.5h:3.88889}
- [2] {CellSize(1,0):w:26.83333 h:3.22222}
- [3] {细胞大小(1,1):w:4.166667 h:3.22222}
- [4] {细胞大小(1,2):w:4.416667 h:3.22222}
- [5] {细胞大小(1,3):w:8.5H:3.2222}
- [6] {细胞大小(1,4):w:4.583333 h:3.22222}
- [7] {细胞大小(2,0):w:8.5H:3.2222}
- [8] {细胞大小(2,1):w:26.83333 h:3.22222}
- [9] {细胞大小(2,2):w:4.166667 h:3.22222}
- [10] {细胞大小(2,3):w:4.416667 h:3.22222}
- [11] {细胞大小(2,4):w:8.5H:3.2222}
- [12] {细胞大小(2,5):w:4.583333 h:3.22222}
rowHeights = [3.888889, 3.222222, 3.222222]
colWidths = [8.5, 26.83333, 4.166667, 4.416667, 8.5, 4.583333]
我最初的尝试无效
//rows
float[] rowSize = new float[table.RowsNumber];
for (int i = 0; i < table.RowsNumber; i++)
rowSize[i] = float.MaxValue;
foreach (var cellSize in cellSizes)
if (cellSize.height < rowSize[cellSize.row])
rowSize[cellSize.row] = cellSize.height;
//cols
float[] colSize = new float[table.ColumnsNumber];
for (int i = 0; i < table.ColumnsNumber; i++)
colSize[i] = float.MaxValue;
foreach (var cellSize in cellSizes)
if (cellSize.width < colSize[cellSize.column])
colSize[cellSize.column] = cellSize.width;
这将为上表和其他几个测试用例提供正确的数字,但我相当肯定,它并不适用于所有情况。如果我正确理解了您的问题
you don't need to initilize the respective arrays
List<float> rowSize = new List<float>();
for( int i =0 ; i <= cellSizes.Length-1 ;i++)
{
if (cellSize[i+1].height <= cellSize[i].height)
rowSize.Add(cellSize[i+1].height);
else
rowSize.Add(cellSize[i].height);
}
不需要初始化相应的数组
列表行大小=新列表();
对于(inti=0;i来说,这比我预期的要难一些
我唯一能想到的方法是做一个二维网格,然后计算出细胞的正确位置
Diagram.CellSize[,] correctPositions = new Diagram.CellSize[table.RowsNumber,table.ColumnsNumber];
int rowoffset = 0;
int currow = -1;
//Needs to be processed in order, or the algorithm wont work
foreach (var cellSize in cellSizes.OrderBy(c => c.row).ThenBy(c => c.column).ToList())
{
if (currow != cellSize.row)
{
rowoffset = 0;
currow = cellSize.row;
}
//find out if the cell above us is actually rowspanned
int rowabove = cellSize.row - 1;
if (rowabove >= 0 && correctPositions[rowabove, cellSize.column + rowoffset].rowspan > 1)
{
correctPositions[cellSize.row, cellSize.column + rowoffset] =
new Diagram.CellSize
{
row = -1,
//keep track of the rowspan, so we just need to look 1 cell up
rowspan = correctPositions[rowabove, cellSize.column + rowoffset].rowspan - 1
};
rowoffset++;
}
//then set this cell
correctPositions[cellSize.row, cellSize.column + rowoffset] = cellSize;
for (int i = 1; i < cellSize.colspan; i++)
{
//adjust the current rowspan
rowoffset++;
correctPositions[cellSize.row, cellSize.column + rowoffset] =
new Diagram.CellSize
{
row = -1,
//keep track of the rowspan, if a cell has both rowspan and cell span
rowspan = cellSize.rowspan
};
}
}
Diagram.CellSize[,]correctPositions=新的Diagram.CellSize[table.RowsNumber,table.columnsumber];
int rowoffset=0;
int currow=-1;
//需要按顺序处理,否则算法无法工作
foreach(在cellSizes.OrderBy(c=>c.row.ThenBy(c=>c.column.ToList())中使用var cellSize)
{
if(currow!=cellSize.row)
{
rowoffset=0;
currow=cellSize.row;
}
//看看我们上面的单元格是不是真的被划过了
int rowover=cellSize.row-1;
如果(RowOver>=0&&correctPositions[RowOver,cellSize.column+rowoffset].rowspan>1)
{
更正位置[cellSize.row,cellSize.column+rowoffset]=
新图表。单元格大小
{
行=-1,
//跟踪行跨度,所以我们只需要查找1个单元格
rowspan=correctPositions[RowUpper,cellSize.column+rowoffset]。rowspan-1
};
rowoffset++;
}
//然后设置这个单元格
correctPositions[cellSize.row,cellSize.column+rowoffset]=cellSize;
对于(int i=1;i
现在我可以使用原始位置进行处理
//rows, find the first col in each row that is not merged and not spanned
for (int i = 0; i < table.RowsNumber; i++)
{
for (int j = 0; j < table.ColumnsNumber; j++)
{
var cell = correctPositions[i, j];
if (cell.row == -1 || cell.rowspan > 1)
continue;
table.SetRowHeight(i, (int) ((cell.height*ppSlideHeight)/100));
break;
}
}
//cols, find the first row in each col that is not merged and not spanned
for (int j = 0; j < table.ColumnsNumber; j++)
{
for (int i = 0; i < table.RowsNumber; i++)
{
var cell = correctPositions[i, j];
if (cell.row == -1 || cell.colspan > 1)
continue;
table.SetColumnWidth(j, (int) ((cell.width*ppSlideWidth)/100));
break;
}
}
//行,查找每行中未合并和未跨越的第一个列
对于(int i=0;i1)
持续
表.设置行高(i,(int)((单元格高度*ppSlideHeight)/100));
打破
}
}
//cols,查找每个col中未合并和未跨越的第一行
对于(int j=0;j1)
持续
表.SetColumnWidth(j,(int)((单元格宽度*ppSlideWidth)/100));
打破
}
}
当一行中的所有单元格都被行跨距隔开或列跨距隔开时(例如,一个包含2列的表,其中两列的行跨距均为2),该功能将不起作用性能是一个问题吗?不完全是。单元格的数量很少超过上述数量,可能是上述数量的两倍。所以我想你的方法是可以的。也许你可以放弃同时对COL和ROW进行循环测试,但代码会变得稍微复杂一些,如果性能不是问题,那么维护总是很容易。除非它没有给出正确的答案回答…由于合并单元格,0列与1列的大小不正确。对不起,我没有检查数字。
//rows, find the first col in each row that is not merged and not spanned
for (int i = 0; i < table.RowsNumber; i++)
{
for (int j = 0; j < table.ColumnsNumber; j++)
{
var cell = correctPositions[i, j];
if (cell.row == -1 || cell.rowspan > 1)
continue;
table.SetRowHeight(i, (int) ((cell.height*ppSlideHeight)/100));
break;
}
}
//cols, find the first row in each col that is not merged and not spanned
for (int j = 0; j < table.ColumnsNumber; j++)
{
for (int i = 0; i < table.RowsNumber; i++)
{
var cell = correctPositions[i, j];
if (cell.row == -1 || cell.colspan > 1)
continue;
table.SetColumnWidth(j, (int) ((cell.width*ppSlideWidth)/100));
break;
}
}