如何解决将copy.deepcopy与python-pptx一起使用以向表中添加列会导致单元属性被破坏
我正在尝试使用python-pptx将列添加到PowerPoint中的表中。许多线程提到了解决方案:
def append_col(prs_obj,sl_i,sh_i):
# prs_obj is a pptx.Presentation('path') object.
# sli_i and sh_i are int indexs to locate a particular table object.
tab = prs_obj.slides[sl_i].shapes[sh_i].table
new_col = copy.deepcopy(tab._tbl.tblGrid.gridCol_lst[-1])
tab._tbl.tblGrid.append(new_col) # copies last grid element
for tr in tab._tbl.tr_lst:
# duplicate last cell of each row
new_tc = copy.deepcopy(tr.tc_lst[-1])
tr.append(new_tc)
cell = _Cell(new_tc,tr.tc_lst)
cell.text = '--'
return tab
运行此命令后,当您打开PowerPoint时,新列将出现在其中,但其中将不包含cell.text。如果单击该单元格并键入,字母将出现在上一列的单元格中。保存powerpoint可让您正常编辑列,但显然您丢失了cell.text(和格式)。
问题更新1-来自@scanny的评论
对于最简单的情况,是(1x3)表,如下所示:| xx |-| xx |在添加该列之前和之后的tab._tbl.xml打印如下:
问题更新2-来自@scanny的评论 我修改了上面的append_col函数,以从复制的gridCol中强制删除extLst元素。这样就消除了在一个单元格中键入内容以及在另一单元格中出现文本的问题。
def append_col(prs_obj,sh_i):
# existing lines removed for brevity
# New Code
tblchildren = tab._tbl.getchildren()
for child in tblchildren:
if isinstance(child,oxml.table.CT_TableGrid):
ws = set()
for j in child:
if j.w not in ws:
ws.add(j.w)
else:
for elem in j:
j.remove(elem)
return tab
但是仍然缺少cell.text(和格式)。此外,手动保存演示文稿会将tab.xml对象改回。手动打开PowerPoint演示文稿前后的屏幕截图为:
AFTER removing extLst,before manual save - xml diff 1
AFTER removing extLst,AFTER manual save - xml diff 2
解决方法
如果您对解决此类问题很认真,则需要对表的此方面对Word XML进行反向工程。
开始的地方是表格的XML转储之前和之后(添加一列),确定Word所做的更改,然后复制那些重要的内容(例如修订号可能不是 ”)。
通过一个较小的示例(例如2 x 2表到2 x 3表)简化了此过程。
您可以使用其.xml
属性获取python-docx XML元素的XML,例如:
print(tab._tbl.xml)
您可以比较深度复制的结果,然后有具体的差异以开始解释结果不起作用。我希望您会发现表项具有唯一的ID,并且当您重复这些ID时,会发生一些时髦的事情。
,在Scanny的帮助下,我提出了以下可行的解决方法:
npm install ../srcofyoulibraryproject
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。