Is there a way to add a column to a table in PowerPoint slide through Python?
Question:
I have a powerpoint template which I want to use to create a monthly report. The number of columns in one of the table on the slide can change based on some logic and I would like to add new column during runtime.
I was looking for a method to add a column but couldn’t find one. The python-pptx documentation lists an add(before) method under _ColumnCollection class but I think it is not yet available.
Does anyone know of any way to achieve this?
Answers:
Create a new table of the desired shape.
>>> shape = table_placeholder.insert_table(rows=..., cols=...)
>>> table = shape.table
Copy the contents from your last table to the new table. Also, add new values here. Example code:
>>> cell_old = table_old.cell(0, 0)
>>> cell_new = table_new.cell(0, 0)
>>> cell_new.text = cell_old.text
Delete your old table.
I wrote a function that changes the old table to a new table
with this function, you can extend the new table and fill same values from the old table
Imagine we have a table that has 2 rows and 4 columns
[1,2,3,4]
[1,2,3,4]
and you want to extend it 4 rows and 6 columns and fill the same values from the old table
[1,2,3,4,5,6]
[1,2,3,4,5,6]
[1,2,3,4,5,6]
[1,2,3,4,5,6]
My Code
def changeTable(new_table,old_table):
rowIndex = 0
cellIndex = 0
for row in old_table.rows:
for cell in row.cells:
new_table.cell(rowIndex,cellIndex).text = cell.text
cellIndex = cellIndex + 1
cellIndex = 0
rowIndex = rowIndex + 1
old_table = shp.table
new_table = slide.shapes.add_table(4,6,shp.left,shp.top,shp.width,shp.height).table
changedTable = changeTable(new_table,old_table)
Or use other approach:
from pptx.oxml.xmlchemy import OxmlElement
def _sub_element(parent, tagname, **kwargs):
element = OxmlElement(tagname)
element.attrib.update(kwargs)
parent.append(element)
return element
def _sub_element_insert(parent, index, tagname, **kwargs):
element = OxmlElement(tagname)
element.attrib.update(kwargs)
parent.insert(index, element)
return element
def insert_column(shape, at_position, width):
table = shape.table
tbl = table._tbl
trs = tbl.xpath(r"a:tr")
for tr in trs:
tc = _sub_element_insert(tr, at_position, "a:tc")
txBody = _sub_element(tc, "a:txBody")
bodyPr = _sub_element(txBody, "a:bodyPr")
lstStyle = _sub_element(txBody, "a:lstStyle")
p = _sub_element(txBody, "a:p")
tcPr = _sub_element(tc, "a:tcPr", marL="0", marR="0", marT="0", marB="0", anchor="ctr")
tblGrid = tbl.tblGrid
gridCol = _sub_element_insert(tblGrid, at_position, "a:gridCol", w=str(width*12700))
The width is in pts.
This, in addition to inserting a column, can also add one – just set the position one greater than the existing column’s count.
I have a powerpoint template which I want to use to create a monthly report. The number of columns in one of the table on the slide can change based on some logic and I would like to add new column during runtime.
I was looking for a method to add a column but couldn’t find one. The python-pptx documentation lists an add(before) method under _ColumnCollection class but I think it is not yet available.
Does anyone know of any way to achieve this?
Create a new table of the desired shape.
>>> shape = table_placeholder.insert_table(rows=..., cols=...)
>>> table = shape.table
Copy the contents from your last table to the new table. Also, add new values here. Example code:
>>> cell_old = table_old.cell(0, 0)
>>> cell_new = table_new.cell(0, 0)
>>> cell_new.text = cell_old.text
Delete your old table.
I wrote a function that changes the old table to a new table
with this function, you can extend the new table and fill same values from the old table
Imagine we have a table that has 2 rows and 4 columns
[1,2,3,4]
[1,2,3,4]
and you want to extend it 4 rows and 6 columns and fill the same values from the old table
[1,2,3,4,5,6]
[1,2,3,4,5,6]
[1,2,3,4,5,6]
[1,2,3,4,5,6]
My Code
def changeTable(new_table,old_table):
rowIndex = 0
cellIndex = 0
for row in old_table.rows:
for cell in row.cells:
new_table.cell(rowIndex,cellIndex).text = cell.text
cellIndex = cellIndex + 1
cellIndex = 0
rowIndex = rowIndex + 1
old_table = shp.table
new_table = slide.shapes.add_table(4,6,shp.left,shp.top,shp.width,shp.height).table
changedTable = changeTable(new_table,old_table)
Or use other approach:
from pptx.oxml.xmlchemy import OxmlElement
def _sub_element(parent, tagname, **kwargs):
element = OxmlElement(tagname)
element.attrib.update(kwargs)
parent.append(element)
return element
def _sub_element_insert(parent, index, tagname, **kwargs):
element = OxmlElement(tagname)
element.attrib.update(kwargs)
parent.insert(index, element)
return element
def insert_column(shape, at_position, width):
table = shape.table
tbl = table._tbl
trs = tbl.xpath(r"a:tr")
for tr in trs:
tc = _sub_element_insert(tr, at_position, "a:tc")
txBody = _sub_element(tc, "a:txBody")
bodyPr = _sub_element(txBody, "a:bodyPr")
lstStyle = _sub_element(txBody, "a:lstStyle")
p = _sub_element(txBody, "a:p")
tcPr = _sub_element(tc, "a:tcPr", marL="0", marR="0", marT="0", marB="0", anchor="ctr")
tblGrid = tbl.tblGrid
gridCol = _sub_element_insert(tblGrid, at_position, "a:gridCol", w=str(width*12700))
The width is in pts.
This, in addition to inserting a column, can also add one – just set the position one greater than the existing column’s count.