Writes worksheet to an Excel Worksheet COM object.
        Requires :py:module:`pywin32` to be installed.

        :param workbook: xltable.Workbook this sheet belongs to.
        :param worksheet: Excel COM Worksheet instance to write to.
        :param xl_app: Excel COM Excel Application to write to.
        :param bool clear: If a worksheet is provided, clear worksheet before writing.
        :param bool rename: If a worksheet is provided, rename self to match the worksheet.
        :param bool resize_columns: Resize sheet columns after writing.

def to_excel(self,
                 workbook=None,
                 worksheet=None,
                 xl_app=None,
                 clear=True,
                 rename=True,
                 resize_columns=True):
        """
        Writes worksheet to an Excel Worksheet COM object.
        Requires :py:module:`pywin32` to be installed.

        :param workbook: xltable.Workbook this sheet belongs to.
        :param worksheet: Excel COM Worksheet instance to write to.
        :param xl_app: Excel COM Excel Application to write to.
        :param bool clear: If a worksheet is provided, clear worksheet before writing.
        :param bool rename: If a worksheet is provided, rename self to match the worksheet.
        :param bool resize_columns: Resize sheet columns after writing.
        """
        from win32com.client import Dispatch, constants, gencache

        if xl_app is None:
            if worksheet is not None:
                xl_app = worksheet.Parent.Application
            elif workbook is not None and hasattr(workbook.workbook_obj, "Application"):
                xl_app = workbook.workbook_obj.Application
            else:
                xl_app = Dispatch("Excel.Application")

        xl = xl_app = gencache.EnsureDispatch(xl_app)

        # Create a workbook if there isn't one already
        if not workbook:
            from .workbook import Workbook
            workbook = Workbook(worksheets=[self])

        if worksheet is None:
            # If there's no worksheet then call Workbook.to_excel which will create one
            return workbook.to_excel(xl_app=xl_app, resize_columns=resize_columns)

        if rename:
            self.__name = worksheet.Name

        # set manual calculation and turn off screen updating while we update the cells
        calculation = xl.Calculation
        screen_updating = xl.ScreenUpdating
        xl.Calculation = constants.xlCalculationManual
        xl.ScreenUpdating = False
        try:
            # clear the worksheet and reset the styles
            if clear:
                worksheet.Cells.ClearContents()
                worksheet.Cells.Font.Bold = False
                worksheet.Cells.Font.Size = 11
                worksheet.Cells.Font.Color = 0x000000
                worksheet.Cells.Interior.ColorIndex = 0
                worksheet.Cells.NumberFormat = "General"

            # get any array formula tables
            array_formula_tables = []
            for table, (row, col) in self.__tables.values():
                if isinstance(table, ArrayFormula):
                    array_formula_tables.append((row, col, row + table.height, col + table.width))

            def _is_in_array_formula_table(row, col):
                """returns True if this formula cell is part of an array formula table"""
                for top, left, bottom, right in array_formula_tables:
                    if bottom >= row >= top and left <= col <= right:
                        return True
                return False

            origin = worksheet.Range("A1")
            xl_cell = origin
            for r, row in enumerate(self.iterrows(workbook)):
                row = _to_pywintypes(row)

                # set the value and formulae to the excel range (it's much quicker to
                # write a row at a time and update the formula than it is it do it
                # cell by cell)
                if clear:
                    xl_row = worksheet.Range(xl_cell, xl_cell.Offset(1, len(row)))
                    xl_row.Value = row
                else:
                    for c, value in enumerate(row):
                        if value is not None:
                            xl_cell.Offset(1, 1 + c).Value = value

                for c, value in enumerate(row):
                    if isinstance(value, str):
                        if value.startswith("="):
                            formula_value = self.__formula_values.get((r, c), 0)
                            xl_cell.Offset(1, 1 + c).Value = formula_value
                            xl_cell.Offset(1, 1 + c).Formula = value
                        elif value.startswith("{=") \
                        and not _is_in_array_formula_table(r, c):
                            formula_value = self.__formula_values.get((r, c), 0)
                            xl_cell.Offset(1, 1 + c).Value = formula_value
                            xl_cell.Offset(1, 1 + c).FormulaArray = value

                # move to the next row
                xl_cell = xl_cell.Offset(2, 1)

            # set any array formulas
            for table, (row, col) in self.__tables.values():
                if isinstance(table, ArrayFormula):
                    data = table.get_data(workbook, row, col)
                    height, width = data.shape
                    upper_left = origin.Offset(row+1, col+1)
                    lower_right = origin.Offset(row + height, col + width)

                    xl_range = worksheet.Range(upper_left, lower_right)
                    xl_range.FormulaArray = table.formula.get_formula(workbook, row, col)

            # set any formatting
            for (row, col), style in self._get_all_styles().items():
                r = origin.Offset(1 + row, 1 + col)
                if style.bold:
                    r.Font.Bold = True
                if style.excel_number_format is not None:
                    r.NumberFormat = style.excel_number_format
                if style.size is not None:
                    r.Font.Size = style.size
                if style.text_color is not None:
                    r.Font.Color = _to_bgr(style.text_color)
                if style.bg_color is not None:
                    r.Interior.Color = _to_bgr(style.bg_color)
                if style.text_wrap or style.border:
                    raise Exception("text wrap and border not implemented")

            # add any charts
            for chart, (row, col) in self.__charts:
                top_left = origin.Offset(1 + row, 1 + col)
                xl_chart = worksheet.ChartObjects().Add(top_left.Left, top_left.Top, 360, 220).Chart
                xl_chart.ChartType = _to_excel_chart_type(chart.type, chart.subtype)
                if chart.title:
                    xl_chart.ChartTitle = chart.title
                for series in chart.iter_series(self, row, col):
                    xl_series = xl_chart.SeriesCollection().NewSeries()
                    xl_series.Values = "=%s!%s" % (self.name, series["values"].lstrip("="))
                    if "categories" in series:
                        xl_series.XValues = "=%s!%s" % (self.name, series["categories"].lstrip("="))
                    if "name" in series:
                        xl_series.Name = series["name"]

        finally:
            xl.ScreenUpdating = screen_updating
            xl.Calculation = calculation

        if resize_columns:
            try:
                worksheet.Cells.EntireColumn.AutoFit()
            except:
                pass