Пример #1
0
 /// <summary>
 /// Create table
 /// </summary>
 /// <param name="rows">table rows</param>
 /// <returns>new table</returns>
 private DomTable CreateTable(ArrayList rows)
 {
     if (rows.Count > 0)
     {
         var table = new DomTable();
         var index = 0;
         foreach (DomTableRow row in rows)
         {
             row.RowIndex = index;
             index++;
             table.AppendChild(row);
         }
         rows.Clear();
         foreach (DomTableRow tableRow in table.Elements)
         {
             foreach (DomTableCell cell in tableRow.Elements)
                 CombineTable(cell);
         }
         return table;
     }
     throw new ArgumentException("rows");
 }
Пример #2
0
        private void UpdateTableCells(DomTable table, bool fixTableCellSize)
        {
            // Number of table column
            var columns = 0;
            // Flag of cell merge
            var merge = false;
            // Right position of all cells
            var rights = new ArrayList();

            // Right position of table
            var tableLeft = 0;
            for (var count = table.Elements.Count - 1; count >= 0; count--)
            {
                var tableRow = (DomTableRow) table.Elements[count];
                if (tableRow.Elements.Count == 0)
                    table.Elements.RemoveAt(count);
            }

            if (table.Elements.Count == 0)
                Debug.WriteLine("");

            foreach (DomTableRow tableRow in table.Elements)
            {
                var lastCellX = 0;

                columns = Math.Max(columns, tableRow.Elements.Count);
                if (tableRow.HasAttribute(Consts.Irow))
                {
                    tableRow.RowIndex = tableRow.Attributes[Consts.Irow];
                }
                tableRow.IsLastRow = tableRow.HasAttribute(Consts.Lastrow);
                tableRow.Header = tableRow.HasAttribute(Consts.Trhdr);
                // Read row height
                if (tableRow.HasAttribute(Consts.Trrh))
                {
                    tableRow.Height = tableRow.Attributes[Consts.Trrh];
                    if (tableRow.Height == 0)
                        tableRow.Height = DefaultRowHeight;
                    else if (tableRow.Height < 0)
                        tableRow.Height = -tableRow.Height;
                }
                else
                    tableRow.Height = DefaultRowHeight;

                // Read default padding of cell
                tableRow.PaddingLeft = tableRow.HasAttribute(Consts.Trpaddl) ? tableRow.Attributes[Consts.Trpaddl] : int.MinValue;
                tableRow.PaddingTop = tableRow.HasAttribute(Consts.Trpaddt) ? tableRow.Attributes[Consts.Trpaddt] : int.MinValue;
                tableRow.PaddingRight = tableRow.HasAttribute(Consts.Trpaddr) ? tableRow.Attributes[Consts.Trpaddr] : int.MinValue;
                tableRow.PaddingBottom = tableRow.HasAttribute(Consts.Trpaddb) ? tableRow.Attributes[Consts.Trpaddb] : int.MinValue;

                if (tableRow.HasAttribute(Consts.Trleft))
                    tableLeft = tableRow.Attributes[Consts.Trleft];

                if (tableRow.HasAttribute(Consts.Trcbpat))
                    tableRow.Format.BackColor = ColorTable.GetColor(
                        tableRow.Attributes[Consts.Trcbpat],
                        Color.Transparent);

                var widthCount = 0;
                foreach (DomTableCell cell in tableRow.Elements)
                {
                    // Set cell's dispaly format
                    if (cell.HasAttribute(Consts.Clvmgf))
                        merge = true;

                    if (cell.HasAttribute(Consts.Clvmrg))
                        merge = true;

                    cell.PaddingLeft = cell.HasAttribute(Consts.Clpadl) ? cell.Attributes[Consts.Clpadl] : int.MinValue;
                    cell.PaddingRight = cell.HasAttribute(Consts.Clpadr) ? cell.Attributes[Consts.Clpadr] : int.MinValue;
                    cell.PaddingTop = cell.HasAttribute(Consts.Clpadt) ? cell.Attributes[Consts.Clpadt] : int.MinValue;
                    cell.PaddingBottom = cell.HasAttribute(Consts.Clpadb) ? cell.Attributes[Consts.Clpadb] : int.MinValue;

                    // Whether display border line
                    cell.Format.LeftBorder = cell.HasAttribute(Consts.Clbrdrl);
                    cell.Format.TopBorder = cell.HasAttribute(Consts.Clbrdrt);
                    cell.Format.RightBorder = cell.HasAttribute(Consts.Clbrdrr);
                    cell.Format.BottomBorder = cell.HasAttribute(Consts.Clbrdrb);

                    if (cell.HasAttribute(Consts.Brdrcf))
                    {
                        cell.Format.BorderColor = ColorTable.GetColor(
                            cell.GetAttributeValue(Consts.Brdrcf, 1),
                            Color.Black);
                    }

                    for (var count = cell.Attributes.Count - 1; count >= 0; count--)
                    {
                        var name3 = cell.Attributes.GetItem(count).Name;
                        if (name3 == Consts.Brdrtbl
                            || name3 == Consts.Brdrnone
                            || name3 == Consts.Brdrnil)
                        {
                            for (var count2 = count - 1; count2 >= 0; count2--)
                            {
                                var name2 = cell.Attributes.GetItem(count2).Name;
                                if (name2 == Consts.Clbrdrl)
                                {
                                    cell.Format.LeftBorder = false;
                                    break;
                                }

                                if (name2 == Consts.Clbrdrt)
                                {
                                    cell.Format.TopBorder = false;
                                    break;
                                }

                                if (name2 == Consts.Clbrdrr)
                                {
                                    cell.Format.RightBorder = false;
                                    break;
                                }

                                if (name2 == Consts.Clbrdrb)
                                {
                                    cell.Format.BottomBorder = false;
                                    break;
                                }
                            }
                        }
                    }

                    // Vertial alignment
                    if (cell.HasAttribute(Consts.Clvertalt))
                        cell.VerticalAlignment = RtfVerticalAlignment.Top;
                    else if (cell.HasAttribute(Consts.Clvertalc))
                        cell.VerticalAlignment = RtfVerticalAlignment.Middle;
                    else if (cell.HasAttribute(Consts.Clvertalb))
                        cell.VerticalAlignment = RtfVerticalAlignment.Bottom;

                    // Background color
                    cell.Format.BackColor = cell.HasAttribute(Consts.Clcbpat) ? ColorTable.GetColor(cell.Attributes[Consts.Clcbpat], Color.Transparent) : Color.Transparent;
                    if (cell.HasAttribute(Consts.Clcfpat))
                        cell.Format.BorderColor = ColorTable.GetColor(cell.Attributes[Consts.Clcfpat], Color.Black);

                    // Cell's width
                    var cellWidth = 2763; // cell's default with is 2763 Twips(570 Document)
                    if (cell.HasAttribute(Consts.Cellx))
                    {
                        cellWidth = cell.Attributes[Consts.Cellx] - lastCellX;
                        if (cellWidth < 100)
                            cellWidth = 100;
                    }

                    var right = lastCellX + cellWidth;
                    // fix cell's right position , if this position is very near with another cell's
                    // right position( less then 45 twips or 3 pixel), then consider these two position
                    // is the same , this can decrease number of table columns
                    foreach (var t in rights)
                    {
                        if (Math.Abs(right - (int) t) < 45)
                        {
                            right = (int) t;
                            cellWidth = right - lastCellX;
                            break;
                        }
                    }

                    cell.Left = lastCellX;
                    cell.Width = cellWidth;

                    widthCount += cellWidth;

                    if (rights.Contains(right) == false)
                    {
                        // becase of convert twips to unit of document may cause truncation error.
                        // This may cause rights.Contains mistake . so scale cell's with with
                        // native twips unit , after all computing , convert to unit of document.
                        rights.Add(right);
                    }
                    lastCellX = lastCellX + cellWidth;
                } //foreach
                tableRow.Width = widthCount;
            } //foreach

            if (rights.Count == 0)
            {
                // can not detect cell's width , so consider set cell's width
                // automatic, then set cell's default width.
                var cols = 1;
                foreach (DomTableRow row in table.Elements)
                    cols = Math.Max(cols, row.Elements.Count);

                var w = ClientWidth/cols;

                for (var count = 0; count < cols; count++)
                    rights.Add(count*w + w);
            }

            // Computing cell's rowspan and colspan , number of rights array is the number of table columns.

            rights.Add(0);
            rights.Sort();

            // Add table column instance
            for (var count = 1; count < rights.Count; count++)
            {
                var col = new DomTableColumn {Width = (int) rights[count] - (int) rights[count - 1]};
                table.Columns.Add(col);
            }

            for (var rowIndex = 1; rowIndex < table.Elements.Count; rowIndex++)
            {
                var row = (DomTableRow) table.Elements[rowIndex];
                for (var colIndex = 0; colIndex < row.Elements.Count; colIndex++)
                {
                    var cell = (DomTableCell) row.Elements[colIndex];
                    if (cell.Width == 0)
                    {
                        // If current cell not special width , then use the width of cell which
                        // in the same colum and in the last row
                        var preRow = (DomTableRow) table.Elements[rowIndex - 1];
                        if (preRow.Elements.Count > colIndex)
                        {
                            var preCell = (DomTableCell) preRow.Elements[colIndex];
                            cell.Left = preCell.Left;
                            cell.Width = preCell.Width;
                            CopyStyleAttribute(cell, preCell.Attributes);
                        }
                    }
                }
            }

            if (merge == false)
            {
                // If not detect cell merge , maby exist cell merge in the same row
                foreach (DomTableRow row in table.Elements)
                {
                    if (row.Elements.Count < table.Columns.Count)
                    {
                        // If number of row's cells not equals the number of table's columns
                        // then exist cell merge.
                        merge = true;
                        break;
                    }
                }
            }

            if (merge)
            {
                // Detect cell merge , begin merge operation

                // Because of in rtf format,cell which merged by another cell in the same row ,
                // does no written in rtf text , so delay create those cell instance .
                foreach (DomTableRow row in table.Elements)
                {
                    if (row.Elements.Count != table.Columns.Count)
                    {
                        // If number of row's cells not equals number of table's columns ,
                        // then consider there are hanppend  horizontal merge.
                        var cells = row.Elements.ToArray();
                        foreach (var domElement in cells)
                        {
                            var cell = (DomTableCell) domElement;
                            var index = rights.IndexOf(cell.Left);
                            var index2 = rights.IndexOf(cell.Left + cell.Width);
                            var intColSpan = index2 - index;
                            // detect vertical merge
                            var verticalMerge = cell.HasAttribute(Consts.Clvmrg);

                            if (verticalMerge == false)
                            {
                                // If this cell does not merged by another cell abover ,
                                // then set colspan
                                cell.ColSpan = intColSpan;
                            }

                            if (row.Elements.LastElement == cell)
                            {
                                cell.ColSpan = table.Columns.Count - row.Elements.Count + 1;
                                intColSpan = cell.ColSpan;
                            }

                            for (var count = 0; count < intColSpan - 1; count++)
                            {
                                var newCell = new DomTableCell {Attributes = cell.Attributes.Clone()};
                                row.Elements.Insert(row.Elements.IndexOf(cell) + 1, newCell);
                                if (verticalMerge)
                                {
                                    // This cell has been merged.
                                    newCell.Attributes[Consts.Clvmrg] = 1;
                                    newCell.OverrideCell = cell;
                                }
                            }
                        }

                        if (row.Elements.Count != table.Columns.Count)
                        {
                            // If the last cell has been merged. then supply new cells.
                            var lastCell = (DomTableCell) row.Elements.LastElement;
                            if (lastCell == null)
                                Console.WriteLine("");

                            for (var count = row.Elements.Count; count < rights.Count; count++)
                            {
                                var newCell = new DomTableCell();
                                if (lastCell != null) CopyStyleAttribute(newCell, lastCell.Attributes);
                                row.Elements.Add(newCell);
                            }
                        }
                    }
                }

                // Set cell's vertial merge.
                foreach (DomTableRow tableRow in table.Elements)
                {
                    foreach (DomTableCell tableCell in tableRow.Elements)
                    {
                        if (tableCell.HasAttribute(Consts.Clvmgf) == false)
                        {
                            //if this cell does not mark vertial merge , then next cell
                            continue;
                        }
                        // if this cell mark vertial merge.
                        var colIndex = tableRow.Elements.IndexOf(tableCell);
                        for (var rowIndex = table.Elements.IndexOf(tableRow) + 1;
                            rowIndex < table.Elements.Count;
                            rowIndex++)
                        {
                            var row2 = (DomTableRow) table.Elements[rowIndex];
                            if (colIndex >= row2.Elements.Count)
                            {
                                Console.Write("");
                            }
                            var cell2 = (DomTableCell) row2.Elements[colIndex];
                            if (cell2.HasAttribute(Consts.Clvmrg))
                            {
                                if (cell2.OverrideCell != null)
                                    // If this cell has been merge by another cell( must in the same row )
                                    // then break the circle
                                    break;

                                // Increase vertial merge.
                                tableCell.RowSpan++;
                                cell2.OverrideCell = tableCell;
                            }
                            else
                                // if this cell not mark merged by another cell , then break the circel
                                break;
                        }
                    }
                }

                // Set cell's OverridedCell information
                foreach (DomTableRow tableRow in table.Elements)
                {
                    foreach (DomTableCell tableCell in tableRow.Elements)
                    {
                        if (tableCell.RowSpan > 1 || tableCell.ColSpan > 1)
                        {
                            for (var rowIndex = 1; rowIndex <= tableCell.RowSpan; rowIndex++)
                            {
                                for (var colIndex = 1; colIndex <= tableCell.ColSpan; colIndex++)
                                {
                                    var r = table.Elements.IndexOf(tableRow) + rowIndex - 1;
                                    var c = tableRow.Elements.IndexOf(tableCell) + colIndex - 1;
                                    var cell2 = (DomTableCell) table.Elements[r].Elements[c];
                                    if (tableCell != cell2)
                                    {
                                        cell2.OverrideCell = tableCell;
                                    }
                                }
                            }
                        }
                    }
                }
            }

            if (fixTableCellSize)
            {
                // Fix table's left position use the first table column
                if (table.Columns.Count > 0)
                    ((DomTableColumn) table.Columns[0]).Width -= tableLeft;
            }
        }