从合并的单元格中查找原始行高和列宽

时间:2010-12-28 07:27:43

标签: algorithm

我有一些由框架生成的表,我有单元格的大小和坐标。但是,我现在需要将其导出为另一种格式,并且此特定格式没有按单元格大小调整,只有行和列的大小调整。

例如,我有这个3乘6的表,有很多合并的单元格:

  • [0] {CellSize(0,0):w:8.5 h:7.111111}
  • [1] {CellSize(0,1):w:48.5 h:3.888889}
  • [2] {CellSize(1,0):w:26.83333 h:3.222222}
  • [3] {CellSize(1,1):w:4.166667 h:3.222222}
  • [4] {CellSize(1,2):w:4.416667 h:3.222222}
  • [5] {CellSize(1,3):w:8.5 h:3.222222}
  • [6] {CellSize(1,4):w:4.583333 h:3.222222}
  • [7] {CellSize(2,0):w:8.5 h:3.222222}
  • [8] {CellSize(2,1):w:26.83333 h:3.222222}
  • [9] {CellSize(2,2):w:4.166667 h:3.222222}
  • [10] {CellSize(2,3):w:4.416667 h:3.222222}
  • [11] {CellSize(2,4):w:8.5 h:3.222222}
  • [12] {CellSize(2,5):w:4.583333 h:3.222222}

我最终想要的是两个阵列:

  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;

任何人都有更好的主意吗?

编辑:

我设法找到原始表的rowspan和cellspan,然后执行此操作:

  float[] rowSize = new float[table.RowsNumber];
  foreach (var cellSize in cellSizes)
    if (cellSize.rowspan == 1)
      rowSize[cellSize.row] = cellSize.height;

  float[] colSize = new float[table.ColumnsNumber];
  foreach (var cellSize in cellSizes)
    if (cellSize.colspan == 1)
      colSize[cellSize.column] = cellSize.width;

这将为上表和其他几个测试用例提供正确的数字,但我相当确定它在所有情况下都不起作用。

2 个答案:

答案 0 :(得分:0)

如果我理解你的问题

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);
    }

列类似

答案 1 :(得分:0)

这比我预期的要难一些......

我想出的唯一方法是制作一个二维网格,然后计算单元格的正确位置。

  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
              };
     }
  }

现在我可以使用原来的位置进行处理......

  //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;
     }
  }

当一行中的所有单元格都被排成行或者被淘汰时(例如,一个带有2个cols的表,其中两个cols的行跨度为2),它将无法工作。