import six import pandas as pd from math import * from pptx import Presentation from pptx.util import Cm, Pt round_to_n = lambda x, n: round(x, -int(floor(log10(abs(x)))) + (n - 1)) def _do_formatting(value, format_str): """Format value according to format_str, and deal sensibly with format_str if it is missing or invalid. """ if format_str == '': if type(value) in six.integer_types: format_str = ',' elif type(value) is float: format_str = 'f' elif type(value) is str: format_str = 's' elif format_str[0] == '.': if format_str.endswith('R'): if type(value) in six.integer_types: value = round_to_n(value, int(format_str[1])) format_str = ',' if not format_str.endswith('G'): format_str = format_str + "G" try: value = format(value, format_str) except: value = format(value, '') return value def process_position_parameter(param): """Process positioning parameters (left, top, width, height) given to df_to_table. If an integer, returns the right instance of the Cm class to allow it to be treated as cm. If missing, then default to 4cm. Otherwise, pass through whatever it gets. """ if param is None: return Cm(4) elif type(param) is int: return Cm(param) else: return param def df_to_table(slide, df, left=None, top=None, width=None, height=None, colnames=None, col_formatters=None, rounding=None, name=None): """Converts a Pandas DataFrame to a PowerPoint table on the given Slide of a PowerPoint presentation. The table is a standard Powerpoint table, and can easily be modified with the Powerpoint tools, for example: resizing columns, changing formatting etc. Parameters ---------- slide: ``pptx.slide.Slide`` slide object from the python-pptx library containing the slide on which you want the table to appear df: pandas ``DataFrame`` DataFrame with the data left: int, optional Position of the left-side of the table, either as an integer in cm, or as an instance of a pptx.util Length class (pptx.util.Inches for example). Defaults to 4cm. top: int, optional Position of the top of the table, takes parameters as above. width: int, optional Width of the table, takes parameters as above. height: int, optional Height of the table, takes parameters as above. col_formatters: list, optional A n_columns element long list containing format specifications for each column. For example ['', ',', '.2'] does no special formatting for the first column, uses commas as thousands separators in the second column, and formats the third column as a float with 2 decimal places. rounding: list, optional A n_columns element long list containing a number for each integer column that requires rounding that is then multiplied by -1 and passed to round(). The practical upshot of this is that you can give something like ['', 3, ''], which does nothing for the 1st and 3rd columns (as they aren't integer values), but for the 2nd column, rounds away the 3 right-hand digits (eg. taking 25437 to 25000). name: str, optional A name to be given to the table in the Powerpoint file. This is not displayed, but can help extract the table later to make further changes. Returns ------- pptx.shapes.graphfrm.GraphicFrame The python-pptx table (GraphicFrame) object that was created (which can then be used to do further manipulation if desired) """ left = process_position_parameter(left) top = process_position_parameter(top) width = process_position_parameter(width) height = process_position_parameter(height) rows, cols = df.shape shp = slide.shapes.add_table(rows+1, cols, left, top, width, height) if colnames is None: colnames = list(df.columns) # Insert the column names for col_index, col_name in enumerate(colnames): shp.table.cell(0,col_index).text = col_name m = df.values for row in range(rows): for col in range(cols): val = m[row, col] if col_formatters is None: text = str(val) else: text = _do_formatting(val, col_formatters[col]) shp.table.cell(row+1, col).text = text if name is not None: shp.name = name return shp def df_to_powerpoint(filename, df, **kwargs): """Converts a Pandas DataFrame to a table in a new, blank PowerPoint presentation. Creates a new PowerPoint presentation with the given filename, with a single slide containing a single table with the Pandas DataFrame data in it. The table is a standard Powerpoint table, and can easily be modified with the Powerpoint tools, for example: resizing columns, changing formatting etc. Parameters ---------- filename: Filename to save the PowerPoint presentation as df: pandas ``DataFrame`` DataFrame with the data **kwargs All other arguments that can be taken by ``df_to_table()`` (such as ``col_formatters`` or ``rounding``) can also be passed here. Returns ------- pptx.shapes.graphfrm.GraphicFrame The python-pptx table (GraphicFrame) object that was created (which can then be used to do further manipulation if desired) """ pres = Presentation() blank_slide_layout = pres.slide_layouts[6] slide = pres.slides.add_slide(blank_slide_layout) table = df_to_table(slide, df, **kwargs) pres.save(filename) return table