纳速健身

 找回密码
 注册

扫一扫,访问微社区

查看: 9|回复: 0

[Python] [python之word操作]通过python-docx给word文档中的指定位置添加表格和表格属性设置方法

[复制链接]
发表于 2021-1-10 19:07:43 | 显示全部楼层 |阅读模式
需求1.读取一个已有的word文档。docx格式。
2.在该word文档中,通过一个给定的文字。找到该位置。在该位置的下方添加一个表格。例如在图中“BUG情况表”的下方插入一个表格

word%E6%96%87%E6%A1%A3%E6%88%AA%E5%9B%BE.png

3.表格内容如下。要求添加完该表格后,如果表格内容发生变更。还能再次通过该程序,修改表格里的数据。

excel%E6%96%87%E6%A1%A3%E6%88%AA%E5%9B%BE.png

设计通过python-docx读取word文档。通过document.paragraphs定位指定文字的位置。通过xlwings读取excel的内容,存成list[list[]]。通过docx的add_table增加一个表格,并且更改表头颜色,合并表格等操作通过识别表头的第一行,判断是否是已经存在这个表格,来决定是否要删除原表格代码

  1. # -*- coding: UTF-8 -*-
  2. import sys
  3. from copy import deepcopy

  4. import xlwings
  5. from docx import Document
  6. from docx.oxml.ns import nsdecls
  7. from docx.oxml import parse_xml

  8. def copy_table_after(table, paragraph):
  9.     tbl, p = table._tbl, paragraph._p
  10.     new_tbl = deepcopy(tbl)
  11.     p.addnext(new_tbl)

  12. def move_table_after(table, paragraph):
  13.     tbl, p = table._tbl, paragraph._p
  14.     p.addnext(tbl)


  15. def get_excel_date(filename):
  16.     '''
  17.     获得excel里的所有内容,返回list
  18.     :param filename:  excel路径
  19.     :return: list[list[]]
  20.     '''
  21.     app = xlwings.App(visible=False, add_book=True)
  22.     app.display_alerts = False
  23.     app.screen_updating = False
  24.     wb = app.books.open(filename)
  25.     sht = wb.sheets[0]
  26.     rng = sht.range('A1')
  27.     # 把excel里的数据读取成 年-月-日 时:分:秒的格式
  28.     my_date_handler = lambda year, month, day, hour, minute, second, **kwargs: "%04i-%02i-%02i %02i:%02i:%02i" % (
  29.         year, month, day, hour, minute, second)
  30.     # 取出所有内容,这里用ig这个变量,是为了庆祝I.G获得LOL S8赛季总冠军
  31.     ig = rng.current_region.options(index=False, numbers=int, empty='N/A', dates=my_date_handler)
  32.     result = ig.value
  33.     wb.close()
  34.     app.quit()
  35.     return result

  36. def delete_table_with_title(document,expect_text):
  37.     allTables = document.tables
  38.     for activeTable in allTables:
  39.         if activeTable.cell(0, 0).paragraphs[0].text == expect_text:
  40.             print('删除成功')
  41.             activeTable._element.getparent().remove(activeTable._element)

  42. def insert_table_after_text(file_name,excel_name,expect_text):
  43.     document = Document(file_name)
  44.     # 因为docx读出来的都是unicode类型的,所以我们要用unicode类型的进行查找
  45.     expect_text=expect_text.decode('utf-8')
  46.     delete_table_with_title(document,expect_text)
  47.     target = None
  48.     for paragraph in document.paragraphs:
  49.         paragraph_text = paragraph.text
  50.         if paragraph_text.endswith(expect_text):
  51.             target = paragraph
  52.             break
  53.     if target is not None:
  54.         records = get_excel_date(excel_name)
  55.         # 获得excel数据的栏数,初始化一个空的table
  56.         col = len(records[0])
  57.         table = document.add_table(rows=1, cols=col)
  58.         table.style = 'Table Grid'
  59.         # 给table加一个表头,并且合并第一栏
  60.         shading_elm_1 = parse_xml(r'<w:shd {} w:fill="D9E2F3"/>'.format(nsdecls('w')))
  61.         table.rows[0].cells[0]._tc.get_or_add_tcPr().append(shading_elm_1)
  62.         table.rows[0].cells[0].text=expect_text
  63.         table_row=table.rows[0]
  64.         first=table_row.cells[0]
  65.         end=table_row.cells[-1]
  66.         first.merge(end)
  67.         # 合并结束,开始把excel里的内容添加到table里
  68.         for tr_list in records:
  69.             row_cells = table.add_row().cells
  70.             index = 0
  71.             for td_list in tr_list:
  72.                 row_cells[index].text = td_list
  73.                 index = index + 1
  74.         # 把添加的table移动到指定的位置
  75.         move_table_after(table, target)
  76.         # 保存
  77.     document.save(file_name)
  78. if __name__ == '__main__':
  79.     insert_table_after_text('demo2.docx', 'demo.xlsx',"BUG情况表")
复制代码


最终效果

%E6%88%90%E5%8A%9F%E6%B7%BB%E5%8A%A0%E8%A1%A8%E6%A0%BC.png




python-docx的表格属性设置方法


怕搞忘,记下来。

pydocx的表格设置:

1.字体设置

  1.     for i in range(len(tab.rows)):
  2.         tab.rows[i].height = Cm(2)
  3.         for j in range(len(tab.columns)):
  4.             tab.cell(i,j).width = Cm(4)
  5.             tab.cell(i,j).vertical_alignment = WD_ALIGN_VERTICAL.CENTER
  6.             for par in tab.cell(i,j).paragraphs:
  7.                 print(par.text)
  8.                 # par.paragraph_format.styles.font.size=Pt(12)
  9.                 for run in par.runs:
  10.                     run.font.size = Pt(12)
  11.                     run.font.name = 'Times New Roman'
  12.                     run.font.name = u'宋体'
  13.                     run._element.rPr.rFonts.s
复制代码

直接用tab.style设置未生效,需要进cell的paragraph对run进行字体设置,可行。

2.段落段落设置

  1. tab.style.paragraph_format.space_before = Pt(5)
  2.     tab.style.paragraph_format.space_after = Pt(5)
  3.     tab.style.paragraph_format.alignment = WD_ALIGN_PARAGRAPH.CENTER
  4.     tab.style.paragraph_format.line_spacing_rule = WD_LINE_SPACING.SINGLE
复制代码

3.表格内容居中

https://python-docx.readthedocs. ... ticalAlignment.html

  1.     for i in range(len(tab.rows)):
  2.         tab.rows[i].height = Cm(2)
  3.         for j in range(len(tab.columns)):
  4.             tab.cell(i,j).width = Cm(4)
  5.             tab.cell(i,j).vertical_alignment = WD_ALIGN_VERTICAL.CENTER
复制代码

需要在cell中对对起进行设置,有TOP,CENTER,BOTTOM三种,分别对应垂直方向的位置。

4.表格居中

    tab.alignment=WD_ALIGN_PARAGRAPH.CENTER
直接对tab使用alignment,设置为居中;

5.表格高度、宽度

高度对ROWS进行设置

  1.     for i in range(len(tab.rows)):
  2.         tab.rows[i].height = Cm(2)
复制代码

宽度需要对进到cell对每个cell进行设置,因为每个列中如果有一个cell宽度较大,则按最大的,所以同列中要一样宽。

  1.     for i in range(len(tab.rows)):
  2.         tab.rows[i].height = Cm(2)
  3.         for j in range(len(tab.columns)):
  4.             tab.cell(i,j).width = Cm(4)
  5.             tab.cell(i,j).vertical_alignment = WD_ALIGN_VERTICAL.CENTER
复制代码

以上表格应该够了。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表