コード例 #1
0
ファイル: TableHelper.cs プロジェクト: xw-fighting/DocxToPdf
        /// <summary>
        /// Get cell width, this should be called after ParseTable().
        /// </summary>
        /// <param name="cellId"></param>
        /// <returns></returns>
        public float GetCellWidth(TableHelperCell cell)
        {
            float ret = 0f;

            if (cell != null)
            {
                for (int i = 0; i < cell.ColSpan; i++)
                {
                    ret += this.TableColumnsWidth[cell.colId + i];
                }
            }
            return(ret);
        }
コード例 #2
0
ファイル: TableHelper.cs プロジェクト: xw-fighting/DocxToPdf
        private void adjustTableColumnsWidth()
        {
            if (this.table == null)
            {
                return;
            }

            // Get table total width
            float totalWidth = -1f;
            bool  autoWidth  = false;

            Word.TableWidth tableWidth = this.styleHelper.GetAppliedElement <Word.TableWidth>(this.table);
            if (tableWidth != null && tableWidth.Type != null)
            {
                switch (tableWidth.Type.Value)
                {
                case Word.TableWidthUnitValues.Nil:
                case Word.TableWidthUnitValues.Auto:     // fits the contents
                default:
                    autoWidth = true;
                    break;

                case Word.TableWidthUnitValues.Dxa:
                    if (tableWidth.Width != null)
                    {
                        totalWidth = Tools.ConvertToPoint(tableWidth.Width.Value, Tools.SizeEnum.TwentiethsOfPoint, -1f);
                    }
                    break;

                case Word.TableWidthUnitValues.Pct:
                    if (tableWidth.Width != null)
                    {
                        totalWidth = this.styleHelper.PrintablePageWidth * Tools.Percentage(tableWidth.Width.Value);
                        //if (table.Parent.GetType() == typeof(Word.Body))
                        //    totalWidth = (float)((pdfDoc.PageSize.Width - pdfDoc.LeftMargin - pdfDoc.RightMargin) * percentage(tableWidth.Width.Value));
                        //else
                        //    totalWidth = this.getCellWidth(table.Parent as Word.TableCell) * percentage(tableWidth.Width.Value);
                    }
                    break;
                }
            }
            Console.WriteLine("Table total width: " + totalWidth);

            if (!autoWidth)
            {
                scaleTableColumnsWidth(ref this.tableColumnsWidth, totalWidth);
            }
            else
            {
                totalWidth = this.tableColumnsWidth.Sum();
            }

            for (int i = 0; i < this.RowLength; i++)
            {
                // Get all cells in this row
                List <TableHelperCell> cellsInRow = this.cells.FindAll(c => c.rowId == i);
                if (cellsInRow.Count <= 0)
                {
                    continue;
                }

                // Get if any gridBefore & gridAfter
                int             skipGridsBefore = 0, skipGridsAfter = 0;
                float           skipGridsBeforeWidth = 0f, skipGridsAfterWidth = 0f;
                TableHelperCell head = cellsInRow.FirstOrDefault(c => c.rowStart);
                if (head != null)
                {
                    if (head.row.TableRowProperties != null)
                    {
                        // w:gridBefore
                        var tmpGridBefore = head.row.TableRowProperties.Elements <Word.GridBefore>().FirstOrDefault();
                        if (tmpGridBefore != null && tmpGridBefore.Val != null)
                        {
                            skipGridsBefore = tmpGridBefore.Val.Value;
                        }

                        // w:wBefore
                        var tmpGridBeforeWidth = head.row.TableRowProperties.Elements <Word.WidthBeforeTableRow>().FirstOrDefault();
                        if (tmpGridBeforeWidth != null && tmpGridBeforeWidth.Width != null)
                        {
                            skipGridsBeforeWidth = Tools.ConvertToPoint(Convert.ToInt32(tmpGridBeforeWidth.Width.Value), Tools.SizeEnum.TwentiethsOfPoint, -1f);
                        }

                        // w:gridAfter
                        var tmpGridAfter = head.row.TableRowProperties.Elements <Word.GridAfter>().FirstOrDefault();
                        if (tmpGridAfter != null && tmpGridAfter.Val != null)
                        {
                            skipGridsAfter = tmpGridAfter.Val.Value;
                        }

                        // w:wAfter
                        var tmpGridAfterWidth = head.row.TableRowProperties.Elements <Word.WidthAfterTableRow>().FirstOrDefault();
                        if (tmpGridAfterWidth != null && tmpGridAfterWidth.Width != null)
                        {
                            skipGridsAfterWidth = Tools.ConvertToPoint(Convert.ToInt32(tmpGridAfterWidth.Width.Value), Tools.SizeEnum.TwentiethsOfPoint, -1f);
                        }
                    }
                }

                int j = 0;
                int edgeEnd = 0;

                // -------
                // gridBefore
                edgeEnd = skipGridsBefore;
                for (; j < edgeEnd; j++)
                {
                    // deduce specific columns width from required width
                    skipGridsBeforeWidth -= this.tableColumnsWidth[j];
                }
                if (skipGridsBeforeWidth > 0f)
                {
                    // if required width is larger than the total width of specific columns,
                    // the remaining required width adds to the last specific column
                    this.tableColumnsWidth[edgeEnd - 1] += skipGridsBeforeWidth;
                }

                // ------
                // cells
                while (j < (cellsInRow.Count - skipGridsAfter))
                {
                    float reqCellWidth            = 0f;
                    Word.TableCellWidth cellWidth = this.styleHelper.GetAppliedElement <Word.TableCellWidth>(cellsInRow[j].cell);
                    if (cellWidth != null && cellWidth.Type != null)
                    {
                        switch (cellWidth.Type.Value)
                        {
                        case Word.TableWidthUnitValues.Auto:
                            //// TODO: calculate the items width
                            //if (cellsInRow[j].elements.Count > 0)
                            //{
                            //    iTSText.IElement element = cellsInRow[j].elements[0];
                            //}
                            break;

                        case Word.TableWidthUnitValues.Nil:
                        default:
                            break;

                        case Word.TableWidthUnitValues.Dxa:
                            if (cellWidth.Width != null)
                            {
                                reqCellWidth = Tools.ConvertToPoint(cellWidth.Width.Value, Tools.SizeEnum.TwentiethsOfPoint, -1f);
                            }
                            break;

                        case Word.TableWidthUnitValues.Pct:
                            if (cellWidth.Width != null)
                            {
                                reqCellWidth = Tools.Percentage(cellWidth.Width.Value) * totalWidth;
                            }
                            break;
                        }
                    }

                    // check row span
                    int spanCount = 1;
                    if (cellsInRow[j].cell != null)
                    {
                        Word.TableCell tmpCell = cellsInRow[j].cell;
                        if (tmpCell.TableCellProperties != null)
                        {
                            Word.GridSpan span = tmpCell.TableCellProperties.Elements <Word.GridSpan>().FirstOrDefault();
                            spanCount = (span != null && span.Val != null) ? span.Val.Value : 1;
                        }
                    }

                    edgeEnd = j + spanCount;
                    for (; j < edgeEnd; j++)
                    {
                        // deduce specific columns width from required width
                        reqCellWidth -= this.tableColumnsWidth[j];
                    }
                    if (reqCellWidth > 0f)
                    {
                        // if required width is larger than the total width of specific columns,
                        // the remaining required width adds to the last specific column
                        this.tableColumnsWidth[edgeEnd - 1] += reqCellWidth;
                    }
                }

                // ------
                // gridAfter
                edgeEnd = j + skipGridsAfter;
                for (; j < edgeEnd; j++)
                {
                    // deduce specific columns width from required width
                    skipGridsAfterWidth -= this.tableColumnsWidth[j];
                }
                if (skipGridsAfterWidth > 0f)
                {
                    // if required width is larger than the total width of specific columns,
                    // the remaining required width adds to the last specific column
                    this.tableColumnsWidth[edgeEnd - 1] += skipGridsAfterWidth;
                }

                if (!autoWidth) // fixed table width, adjust width to fit in
                {
                    scaleTableColumnsWidth(ref this.tableColumnsWidth, totalWidth);
                }
                else // auto table width
                {
                    totalWidth = this.tableColumnsWidth.Sum();
                }
            }
        }
コード例 #3
0
ファイル: TableHelper.cs プロジェクト: xw-fighting/DocxToPdf
        // TODO: get row height (not total row height): http://kuujinbo.info/iTextSharp/rowHeights.aspx

        public void ParseTable(Word.Table t)
        {
            if (t == null)
            {
                return;
            }

            this.table             = t;
            this.tableColumnsWidth = this.getTableGridCols(this.table);
            this.colLen            = this.tableColumnsWidth.Count();

            int cellId = 0;
            int rowId  = 0;

            foreach (Word.TableRow row in table.Elements <Word.TableRow>())
            {
                bool rowStart = true;

                // w:gridBefore
                Word.GridBefore tmpGridBefore   = (Word.GridBefore)StHelper.GetAppliedElement <Word.GridBefore>(row);
                int             skipGridsBefore = (tmpGridBefore != null && tmpGridBefore.Val != null) ? tmpGridBefore.Val.Value : 0;

                // w:gridAfter
                Word.GridAfter tmpGridAfter   = (Word.GridAfter)StHelper.GetAppliedElement <Word.GridAfter>(row);
                int            skipGridsAfter = (tmpGridAfter != null && tmpGridAfter.Val != null) ? tmpGridAfter.Val.Value : 0;

                int colId = 0;

                // gridBefore (with same cellId and set as blank)
                if (skipGridsBefore > 0)
                {
                    for (int i = 0; i < skipGridsBefore; i++)
                    {
                        cells.Add(new TableHelperCell(this, cellId, rowId, colId));
                        colId++; // increase for each cells.Add()
                        Debug.Write(String.Format("{0:X} ", cellId));
                    }
                    cellId++;
                }

                foreach (Word.TableCell col in row.Elements <Word.TableCell>())
                {
                    int _cellId    = cellId;
                    int _cellcount = 1;

                    TableHelperCell basecell = new TableHelperCell(this, _cellId, rowId, colId);
                    if (rowStart)
                    {
                        basecell.rowStart = true;
                        rowStart          = false;
                    }
                    basecell.row  = row;
                    basecell.cell = col;

                    // process rowspan and colspan
                    if (col.TableCellProperties != null)
                    {
                        // colspan
                        if (col.TableCellProperties.GridSpan != null)
                        {
                            _cellcount = col.TableCellProperties.GridSpan.Val;
                        }

                        // rowspan
                        if (col.TableCellProperties.VerticalMerge != null)
                        {
                            // "continue": get cellId from (rowId-1):(colId)
                            if (col.TableCellProperties.VerticalMerge.Val == null ||
                                col.TableCellProperties.VerticalMerge.Val == "continue")
                            {
                                _cellId = cells[(this.ColumnLength * (rowId - 1)) + colId].cellId;
                            }
                            // "restart": the begin of rowspan
                            else
                            {
                                _cellId = cellId;
                            }
                        }
                    }
                    basecell.cellId = _cellId;

                    cells.Add(basecell);
                    colId++; // increase for each cells.Add()
                    Debug.Write(String.Format("{0:X} ", _cellId));

                    for (int i = 1; i < _cellcount; i++)
                    {            // Add spanned cells
                        cells.Add(new TableHelperCell(this, _cellId, rowId, colId));
                        colId++; // increase for each cells.Add()
                        Debug.Write(String.Format("{0:X} ", _cellId));
                    }

                    // The latest cellId was used, then we must increase it for future usage
                    if (cellId == _cellId)
                    {
                        cellId++;
                    }
                }
                int rowEndIndex  = cells.Count - 1;
                int rowEndCellId = cells[rowEndIndex].cellId;
                while (rowEndIndex > 0 && cells[rowEndIndex - 1].cellId == rowEndCellId)
                {
                    rowEndIndex--;
                }
                cells[rowEndIndex].rowEnd = true;

                // gridAfter (with same cellId and set as blank)
                if (skipGridsAfter > 0 && colId < this.ColumnLength)
                {
                    for (int i = 0; i < skipGridsAfter; i++)
                    {
                        cells.Add(new TableHelperCell(this, cellId, rowId, colId));
                        colId++; // increase for each cells.Add()
                        Debug.Write(String.Format("{0:X} ", cellId));
                    }
                    cellId++;
                }

                rowId++;
                Debug.Write("\n");
            }
            this.rowLen = rowId;

            // ====== Adjust table columns width by their content ======

            this.adjustTableColumnsWidth();

            // ====== Resolve cell border conflict ======

            // prepare table conditional formatting (border), which will be used in
            // applyCellBorders() so must be called before applyCellBorders()
            this.rollingUpTableBorders();
            for (int r = 0; r < this.RowLength; r++)
            {
                // The following handles the situation where
                // if table innerV is set, and cnd format for first row specifies nill border, then nil border wins.
                // if table innerH is set, and cnd format for first columns specifies nil border, then table innerH wins.

                //// TODO: if row's cellspacing is not zero then bypass this row
                //Word.TableCellSpacing tcspacing = _CvrtCell.GetTableRow(cells, r).TableRowProperties.Descendants<Word.TableCellSpacing>().FirstOrDefault();
                //if (tcspacing.Type.Value != Word.TableWidthUnitValues.Nil)
                //    continue;

                for (int c = 0; c < this.ColumnLength; c++)
                {
                    TableHelperCell me = this.GetCell(r, c);
                    if (me.Blank)
                    {
                        continue;
                    }

                    if (me.Borders == null)
                    {
                        me.Borders = this.applyCellBorders(me.cell.Descendants <Word.TableCellBorders>().FirstOrDefault(),
                                                           (me.colId == 0) | me.rowStart,
                                                           (me.colId + this.GetColSpan(me.cellId) == this.ColumnLength) | me.rowEnd,
                                                           (me.rowId == 0),
                                                           (me.rowId + this.GetRowSpan(me.cellId) == this.RowLength)
                                                           );
                    }
                    int colspan = this.GetColSpan(me.cellId);
                    int rowspan = this.GetRowSpan(me.cellId);

                    // Process the cells at the right side of me
                    //   Can bypass column-spanned cells because they never exist
                    if ((c + (colspan - 1) + 1) < this.ColumnLength) // not last column
                    {
                        List <TableHelperCell> rights = new List <TableHelperCell>();
                        for (int i = 0; i < rowspan; i++)
                        {
                            TableHelperCell tmp = this.GetCell(r + i, c + (colspan - 1) + 1);
                            if (tmp != null && !tmp.Blank)
                            {
                                rights.Add(tmp);
                            }
                        }

                        if (rights.Count > 0)
                        {
                            foreach (TableHelperCell right in rights)
                            {
                                if (right.Borders == null)
                                {
                                    right.Borders = this.applyCellBorders(right.cell.Descendants <Word.TableCellBorders>().FirstOrDefault(),
                                                                          (right.colId == 0) | right.rowStart,
                                                                          (right.colId + this.GetColSpan(right.cellId) == this.ColumnLength) | right.rowEnd,
                                                                          (right.rowId == 0),
                                                                          (right.rowId + this.GetRowSpan(right.cellId) == this.RowLength)
                                                                          );
                                }

                                bool meWin = compareBorder(me.Borders, right.Borders, compareDirection.Horizontal);
                                if (meWin)
                                {
                                    StyleHelper.CopyAttributes(right.Borders.LeftBorder, me.Borders.RightBorder);
                                }
                            }
                            me.Borders.RightBorder.ClearAllAttributes();
                        }
                    }

                    // Process the cells below me
                    //   Can't bypass row-spanned cells because they still have tcBorders property
                    if ((r + 1) < this.RowLength) // not last row
                    {
                        List <TableHelperCell> bottoms = new List <TableHelperCell>();
                        for (int i = 0; i < colspan; i++)
                        {
                            TableHelperCell tmp = this.GetCell(r + 1, c + i);
                            if (tmp != null && !tmp.Blank)
                            {
                                bottoms.Add(tmp);
                            }
                        }

                        foreach (TableHelperCell bottom in bottoms)
                        {
                            if (bottom.Borders == null)
                            {
                                bottom.Borders = this.applyCellBorders(bottom.cell.Descendants <Word.TableCellBorders>().FirstOrDefault(),
                                                                       (bottom.colId == 0) | bottom.rowStart,
                                                                       (bottom.colId + this.GetColSpan(bottom.cellId) == this.ColumnLength) | bottom.rowEnd,
                                                                       (bottom.rowId == 0),
                                                                       (bottom.rowId + this.GetRowSpan(bottom.cellId) == this.RowLength)
                                                                       );
                            }

                            bool meWin = compareBorder(me.Borders, bottom.Borders, compareDirection.Vertical);
                            if (meWin)
                            {
                                StyleHelper.CopyAttributes(bottom.Borders.TopBorder, me.Borders.BottomBorder);
                            }
                        }
                    }
                }
            }

            if (this.cells.Count > 0)
            { // re-process each cell's border conflict with its bottom cell
                for (int i = 0; i < this.cells[this.cells.Count - 1].cellId; i++)
                {
                    TableHelperCell me = this.GetCellByCellId(i);
                    if (me.Blank) // ignore gridBefore/gridAfter cells
                    {
                        continue;
                    }

                    if (me.RowSpan > 1)
                    { // merge bottom border from the last cell of row-spanned cells
                        TableHelperCell meRowEnd = this.GetCell(me.rowId + (me.RowSpan - 1), me.colId);
                        if (meRowEnd != null && meRowEnd.Borders != null && meRowEnd.Borders.BottomBorder != null)
                        {
                            StyleHelper.CopyAttributes(me.Borders.BottomBorder, meRowEnd.Borders.BottomBorder);
                        }
                    }

                    if (me.rowId + me.RowSpan < this.RowLength)
                    { // if me is not at the last row, compare the border with the cell below it
                        TableHelperCell bottom = this.GetCellByCellId(this.GetCell(me.rowId + me.RowSpan, me.colId).cellId);
                        bool            meWin  = compareBorder(me.Borders, bottom.Borders, compareDirection.Vertical);
                        if (!meWin)
                        {
                            me.Borders.BottomBorder.ClearAllAttributes();
                        }
                    }
                }
            }
        }