3

I have a table which is generated by, and placed in a PPT file, using the pptx module python-pptx. I want to add a line between each row of the table in my PPT file.

enter image description here

My current code:

prs = Presentation('existing-presentation.pptx')
slide = prs.slides.add_slide(prs.slide_layouts[0])
title = slide.shapes.title
title.text = "Slide Title"
df_to_table(slide, df)
prs.save(output)

def df_to_table(slide, df, colnames=None):

    rows, cols = df.shape
    placeholder = slide.placeholders[10]
    res = placeholder.insert_table(rows+1, cols)    
    res.table.columns[0].width = Pt(50)


    if colnames is None:
        colnames = list(df.columns)

    # Insert the column names
    for col_index, col_name in enumerate(colnames):
        # Column names can be tuples
        if not isinstance(col_name, str):
            col_name = " ".join(col_name)
        res.table.cell(0, col_index).text = col_name
        res.table.cell(0, col_index).text_frame.paragraphs[0].font.size=Pt(8)
        res.table.cell(0, col_index).text_frame.paragraphs[0].font.name='Arial'
        res.table.cell(0, col_index).text_frame.paragraphs[0].font.color.rgb=RGBColor(0, 0, 0)
        res.table.cell(0, col_index).fill.solid()
        res.table.cell(0, col_index).fill.fore_color.rgb=RGBColor(255, 255, 255)

    m = df.as_matrix()

    for row in range(rows):
        for col in range(cols):
            val = m[row, col]
            text = str(val)
            res.table.cell(row + 1, col).text = text
            res.table.cell(row + 1, col).text_frame.paragraphs[0].font.size=Pt(8)
            res.table.cell(row + 1, col).text_frame.paragraphs[0].font.name='Arial'
            res.table.cell(row + 1, col).text_frame.paragraphs[0].font.color.rgb=RGBColor(0, 0, 0)
            res.table.cell(row + 1, col).fill.solid()
            res.table.cell(row + 1, col).fill.fore_color.rgb=RGBColor(255, 255, 255) 
            res.table.rows[row+1].height = Pt(0.5)

            if col == 0: #ignore first col with names
                continue
            else:
                res.table.columns[col].width = Pt(55)
halfer
  • 19,824
  • 17
  • 99
  • 186

2 Answers2

1

The pptx.shapes.table._Cell object (such as received from table.cell(n, m)) includes a .fill property, but unfortunately not yet a .borders property. I'm sure this will come in the fullness of time, but it's not there yet.

In the meantime you'll need to dig down into the lxml layer under _Cell.

As a start, you can print out the XML of the cell element like this:

tc = cell._tc
print tc.xml

You could create a very small document containing a table with the borders you want and then use this to examine it. Then you can add the required elements using lxml calls. If you search around using "python-pptx workaround function" you'll find some examples from other folks who've done that sort of thing.

scanny
  • 26,423
  • 5
  • 54
  • 80
  • tried this: res.table.cell(row + 1, col)._tc.set('prstDash', 'solid') but no luck :( –  Mar 11 '16 at 08:45
0

Does not directly fit your question, but maybe your need...

Looking in the API of Table, you can shade the rows alternatively with the horz_banding attribute of the Table object. Try adding in your function (app 5th line, before the if statement)

res.table.horz_banding=true
Loic Mouchard
  • 1,121
  • 7
  • 22
  • Thank you for the suggestion. Unfortunately I am bound by a style guide which dictates that the background is to be plain white (as shown) and rows separated by black lines (thickness 0.75pt) –  Mar 10 '16 at 12:43
  • Did you set the format of the expected table (with borders) as standard in the presentation you are modifying? see : http://python-pptx.readthedocs.org/en/latest/user/presentations.html "a lot of how a presentation looks is determined by the parts that are left....." – Loic Mouchard Mar 10 '16 at 13:08