一个表格(table)对象由多个行(row)对象组成,一个行(row)对象又由多个单元格(cell)对象组成。单元格对象包含段落对象,有了段落对象我们就可以添加文字并设置样式。
分为两种情况:
a:固定的行和列
b:不固定的行和列
写法一:
from docx import Document
from docx.enum.text import WD_PARAGRAPH_ALIGNMENT
from docx.shared import RGBColor
document = Document()
t1 = document.add_table(rows=4, cols=2, style='Colorful List')
# 添加表头
t1.rows[0].cells[0].text = "类别"
t1.rows[0].cells[1].text = "代号"
t1.rows[1].cells[0].text = "A"
t1.rows[1].cells[1].text = "001"
t1.rows[2].cells[0].text = "B"
t1.rows[2].cells[1].text = "002"
t1.rows[3].cells[0].text = "C"
t1.rows[3].cells[1].text = "003"
run1 = t1.rows[0].cells[0].paragraphs[0].add_run('类别')
t1.rows[0].cells[0].paragraphs[0].alignment = WD_PARAGRAPH_ALIGNMENT.CENTER
run1.font.color.rgb = RGBColor(0, 255, 0)
run1.bold=True
# 保存表格
document.save('表格1.docx')
from docx import Document
import numpy as np
from docx.enum.text import WD_PARAGRAPH_ALIGNMENT
from docx.shared import RGBColor
arr = np.array([['类别1', '代号1'], ['A', '001'], ['B', '002'], ['C', '003']])
document = Document()
t1 = document.add_table(rows=4, cols=2, style='Colorful List')
# 循环添加
for i, row in enumerate(t1.rows):
print(i)
for j, cell in enumerate(row.cells):
# 获取单元格中的段落对象
paragraph = cell.paragraphs[0]
paragraph.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER
# 这里的run可以设置一些属性
run = paragraph.add_run(arr[i, j])
if i == 2:
run.font.color.rgb = RGBColor(0, 255, 0)
# 保存表格
document.save('表格2.docx')
提前并不确定表格的行列,需要根据数据情况临时添加。则可以先创建一个1*1的表格,然后向右增加列以及向下增加行
老的工作流程:
打开两个表,在表中对应位置填写个人信息,保存。这样一来,当需要填写的信息比较多的时候,工作就会繁琐
新的工作流程:
利用python-docx编写脚本,运行脚本-输入个人信息-自动生成两个word模板
脚本用到的python-docx库的功能:
(1)、创建与合并表格
(2)、添加文本
(3)、设置文本属性(如大小、加粗、下划线、居中等)
安装python-docx已经说过了
创建一个新的文档
"""
创建一个新的文档
"""
document = Document()
"""
零.设置正文的字型
"""
document.styles['Normal'].font.name = "Times New Roman"
document.styles['Normal'].element.rPr.rFonts.set(qn('w:eastAsia'), u'宋体')
document1 = Document('word模版1.docx')
table = document1.tables[0]
for row, obj_row in enumerate(table.rows):
for col, cell in enumerate(obj_row.cells):
cell.text = cell.text + "%d,%d" % (row, col)
document1.save("有行和列标记的word模版1.docx")
"""
一.添加一个37行,13列共481个单元格的表格
"""
table = document.add_table(rows=37, cols=13, style="Table Grid")
"""
二.合并单元格
"""
# 第一行
table.cell(0, 0).merge(table.cell(2, 2))
table.cell(0, 3).merge(table.cell(2, 6))
table.cell(0, 7).merge(table.cell(2, 9))
table.cell(0, 10).merge(table.cell(2, 12))
# 第二行
table.cell(3, 0).merge(table.cell(5, 2))
table.cell(3, 3).merge(table.cell(5, 5))
table.cell(3, 6).merge(table.cell(5, 6))
table.cell(3, 7).merge(table.cell(5, 9))
table.cell(3, 10).merge(table.cell(5, 10))
table.cell(3, 11).merge(table.cell(5, 12))
# 第三行
table.cell(6, 0).merge(table.cell(8, 2))
table.cell(6, 3).merge(table.cell(8, 12))
# 第四行
table.cell(9, 0).merge(table.cell(12, 2))
table.cell(9, 3).merge(table.cell(12, 6))
table.cell(9, 7).merge(table.cell(10, 9))
table.cell(11, 7).merge(table.cell(12, 9))
table.cell(9, 10).merge(table.cell(10, 12))
table.cell(11, 10).merge(table.cell(12, 12))
# 第五行
table.cell(13, 0).merge(table.cell(18, 2))
table.cell(13, 3).merge(table.cell(18, 12))
# 第六行
table.cell(19, 0).merge(table.cell(24, 2))
table.cell(19, 3).merge(table.cell(24, 12))
# 第七行
table.cell(25, 0).merge(table.cell(30, 2))
table.cell(25, 3).merge(table.cell(30, 12))
# 第八行
table.cell(31, 0).merge(table.cell(36, 2))
table.cell(31, 3).merge(table.cell(36, 12))
"""
接收学生输入的内容
"""
departments = input('院系:')
specialty = input('专业:')
name = input('姓名:')
gender = input('性别:')
school_num = input('学号:')
school_time_year_month1 = input('在校起始时间年月:')
school_time_year_month2 = input('在校截止时间年月:')
home_address = input('家庭通讯地址:')
home_num = input('家庭联系方式:')
personal_tel = input('个人联系方式:')
reason = input('本人申请理由:')
# 1.获取合并单元格后的每一行的所有单元格
hdr_cells0 = table.rows[0].cells
hdr_cells3 = table.rows[3].cells
hdr_cells6 = table.rows[6].cells
hdr_cells9 = table.rows[9].cells
hdr_cells12 = table.rows[12].cells
hdr_cells15 = table.rows[15].cells
hdr_cells21 = table.rows[21].cells
hdr_cells27 = table.rows[27].cells
hdr_cells32 = table.rows[32].cells
def add_content_center(cell, con):
"""
填写非固定信息
向单元格写入内容,字体不加粗
:param cell:
:param con:
:return:
"""
p = cell.add_paragraph('')
p.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER
cell.text = con
cell.paragraphs[0].alignment = WD_PARAGRAPH_ALIGNMENT.CENTER
cell.vertical_alignment = WD_CELL_VERTICAL_ALIGNMENT.CENTER
def add_content_center_bold(cell, con):
"""
填写固定信息
向单元格写入内容,字体加粗
:param cell:
:param con:
:return:
"""
cell.text = con
cell.paragraphs[0].alignment = WD_PARAGRAPH_ALIGNMENT.CENTER
cell.vertical_alignment = WD_CELL_VERTICAL_ALIGNMENT.CENTER
cell.vertical_alignment = WD_PARAGRAPH_ALIGNMENT.CENTER
cell.paragraphs[0].runs[0].font.bold = True
# 第一行的内容
add_content_center_bold(hdr_cells0[0], "院(系)")
add_content_center(hdr_cells0[3], departments + '院')
add_content_center_bold(hdr_cells0[7], '专业班级')
add_content_center(hdr_cells0[10], specialty)
# 第二行的内容
add_content_center_bold(hdr_cells3[0], "姓名")
add_content_center(hdr_cells3[3], name)
add_content_center_bold(hdr_cells3[6], "性别")
add_content_center(hdr_cells3[7], gender)
add_content_center_bold(hdr_cells3[10], '学号')
add_content_center(hdr_cells3[11], school_num)
# 第三行内容
add_content_center_bold(hdr_cells6[0], "在校时间")
add_content_center(hdr_cells6[3], school_time_year_month1 + "-" + school_time_year_month2)
# 第四行
add_content_center_bold(hdr_cells9[0], "家庭通讯地址")
add_content_center(hdr_cells9[3], home_address)
add_content_center_bold(hdr_cells9[7], "家庭联系方式")
add_content_center(hdr_cells9[10], home_num)
add_content_center_bold(table.rows[12].cells[7], "个人联系方式")
add_content_center(table.rows[12].cells[10], personal_tel)
# 第五行
add_content_center_bold(hdr_cells15[0], "本人申请理由")
add_content_center(hdr_cells15[3], reason + "\n\n学生本人签名\n\n\t\t年\t月\t日")
# 第六行
# hdr_cells21[0].vertical_alignment = WD_CELL_VERTICAL_ALIGNMENT.CENTER
add_content_center_bold(hdr_cells21[0], "院系领导意见")
add_content_center(hdr_cells21[3], "\n\n领导签字\n\n\t\t年\t月\t日")
# 第七行
add_content_center_bold(hdr_cells27[0], "学生处意见")
add_content_center(hdr_cells27[3], "\n\n领导签字\n\n\t\t年\t月\t日")
# 第八行
add_content_center_bold(hdr_cells32[0], "主管校领导审批")
add_content_center(hdr_cells32[3], "\n\n领导签字\n\n\t\t年\t月\t日")
from docx import Document
from docx.enum.table import WD_TABLE_ALIGNMENT, WD_CELL_VERTICAL_ALIGNMENT
from docx.enum.text import WD_PARAGRAPH_ALIGNMENT
from docx.oxml.ns import qn
from docx.shared import RGBColor, Pt
"""
接收学生输入的内容
"""
departments = input('院系:')
specialty = input('专业:')
name = input('姓名:')
gender = input('性别:')
school_num = input('学号:')
school_time_year_month1 = input('在校起始时间年月:')
school_time_year_month2 = input('在校截止时间年月:')
home_address = input('家庭通讯地址:')
home_num = input('家庭联系方式:')
personal_tel = input('个人联系方式:')
reason = input('本人申请理由:')
"""
创建一个新的文档
"""
document = Document()
"""
零.设置正文的字型
"""
document.styles['Normal'].font.name = "Times New Roman"
document.styles['Normal'].element.rPr.rFonts.set(qn('w:eastAsia'), u'宋体')
"""
一.添加一个37行,13列共481个单元格的表格
"""
table = document.add_table(rows=37, cols=13, style="Table Grid")
"""
二.合并单元格
"""
# 第一行
table.cell(0, 0).merge(table.cell(2, 2))
table.cell(0, 3).merge(table.cell(2, 6))
table.cell(0, 7).merge(table.cell(2, 9))
table.cell(0, 10).merge(table.cell(2, 12))
# 第二行
table.cell(3, 0).merge(table.cell(5, 2))
table.cell(3, 3).merge(table.cell(5, 5))
table.cell(3, 6).merge(table.cell(5, 6))
table.cell(3, 7).merge(table.cell(5, 9))
table.cell(3, 10).merge(table.cell(5, 10))
table.cell(3, 11).merge(table.cell(5, 12))
# 第三行
table.cell(6, 0).merge(table.cell(8, 2))
table.cell(6, 3).merge(table.cell(8, 12))
# 第四行
table.cell(9, 0).merge(table.cell(12, 2))
table.cell(9, 3).merge(table.cell(12, 6))
table.cell(9, 7).merge(table.cell(10, 9))
table.cell(11, 7).merge(table.cell(12, 9))
table.cell(9, 10).merge(table.cell(10, 12))
table.cell(11, 10).merge(table.cell(12, 12))
# 第五行
table.cell(13, 0).merge(table.cell(18, 2))
table.cell(13, 3).merge(table.cell(18, 12))
# 第六行
table.cell(19, 0).merge(table.cell(24, 2))
table.cell(19, 3).merge(table.cell(24, 12))
# 第七行
table.cell(25, 0).merge(table.cell(30, 2))
table.cell(25, 3).merge(table.cell(30, 12))
# 第八行
table.cell(31, 0).merge(table.cell(36, 2))
table.cell(31, 3).merge(table.cell(36, 12))
"""
三. 把模版的固定位置添加内容
1.获取合并单元格后的每一行的所有单元格
2.依次向每一行的每一个合并后的单元格添加内容
"""
# 1.获取合并单元格后的每一行的所有单元格
hdr_cells0 = table.rows[0].cells
hdr_cells3 = table.rows[3].cells
hdr_cells6 = table.rows[6].cells
hdr_cells9 = table.rows[9].cells
hdr_cells12 = table.rows[12].cells
hdr_cells15 = table.rows[15].cells
hdr_cells21 = table.rows[21].cells
hdr_cells27 = table.rows[27].cells
hdr_cells32 = table.rows[32].cells
# 2
def add_content_center(cell, con):
"""
填写非固定信息
向单元格写入内容,字体不加粗
:param cell:
:param con:
:return:
"""
p = cell.add_paragraph('')
p.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER
cell.text = con
cell.paragraphs[0].alignment = WD_PARAGRAPH_ALIGNMENT.CENTER
cell.vertical_alignment = WD_CELL_VERTICAL_ALIGNMENT.CENTER
def add_content_center_bold(cell, con):
"""
填写固定信息
向单元格写入内容,字体加粗
:param cell:
:param con:
:return:
"""
cell.text = con
cell.paragraphs[0].alignment = WD_PARAGRAPH_ALIGNMENT.CENTER
cell.vertical_alignment = WD_CELL_VERTICAL_ALIGNMENT.CENTER
cell.vertical_alignment = WD_PARAGRAPH_ALIGNMENT.CENTER
cell.paragraphs[0].runs[0].font.bold = True
# 第一行的内容
add_content_center_bold(hdr_cells0[0], "院(系)")
add_content_center(hdr_cells0[3], departments + '院')
add_content_center_bold(hdr_cells0[7], '专业班级')
add_content_center(hdr_cells0[10], specialty)
# 第二行的内容
add_content_center_bold(hdr_cells3[0], "姓名")
add_content_center(hdr_cells3[3], name)
add_content_center_bold(hdr_cells3[6], "性别")
add_content_center(hdr_cells3[7], gender)
add_content_center_bold(hdr_cells3[10], '学号')
add_content_center(hdr_cells3[11], school_num)
# 第三行内容
add_content_center_bold(hdr_cells6[0], "在校时间")
add_content_center(hdr_cells6[3], school_time_year_month1 + "-" + school_time_year_month2)
# 第四行
add_content_center_bold(hdr_cells9[0], "家庭通讯地址")
add_content_center(hdr_cells9[3], home_address)
add_content_center_bold(hdr_cells9[7], "家庭联系方式")
add_content_center(hdr_cells9[10], home_num)
add_content_center_bold(table.rows[12].cells[7], "个人联系方式")
add_content_center(table.rows[12].cells[10], personal_tel)
# 第五行
add_content_center_bold(hdr_cells15[0], "本人申请理由")
add_content_center(hdr_cells15[3], reason + "\n\n学生本人签名\n\n\t\t年\t月\t日")
# 第六行
# hdr_cells21[0].vertical_alignment = WD_CELL_VERTICAL_ALIGNMENT.CENTER
add_content_center_bold(hdr_cells21[0], "院系领导意见")
add_content_center(hdr_cells21[3], "\n\n领导签字\n\n\t\t年\t月\t日")
# 第七行
add_content_center_bold(hdr_cells27[0], "学生处意见")
add_content_center(hdr_cells27[3], "\n\n领导签字\n\n\t\t年\t月\t日")
# 第八行
add_content_center_bold(hdr_cells32[0], "主管校领导审批")
add_content_center(hdr_cells32[3], "\n\n领导签字\n\n\t\t年\t月\t日")
# document1 = Document('word模版1.docx')
# table = document1.tables[0]
# for row, obj_row in enumerate(table.rows):
# for col, cell in enumerate(obj_row.cells):
# cell.text = cell.text + "%d,%d" % (row, col)
# document1.save("有行和列标记的word模版1.docx")
document.save("word模版1.docx")
注意:先生成一个37行13列的表格写入word,然后用document1 = Document(‘word模版1.docx’)打开这个文档,在每个单元格中写入对应的下标,方便我们合并单元格
结果:
官方的pythondocx库仍然不支持该选项。 但是,您可以尝试自己实现它。您正在查找的属性名为cell shading,位于cell properties下
解决方案: 将着色元素(w:shd)添加到单元格属性(w:tcPr)
编写了一个简单的函数,它可以实现以下功能:
def _set_cell_background(cell, fill, color=None, val=None):
"""
@fill: Specifies the color to be used for the background
@color: Specifies the color to be used for any foreground
pattern specified with the val attribute
@val: Specifies the pattern to be used to lay the pattern
color over the background color.
"""
from docx.oxml.shared import qn # feel free to move these out
from docx.oxml.xmlchemy import OxmlElement
cell_properties = cell._element.tcPr
try:
cell_shading = cell_properties.xpath('w:shd')[0] # in case there's already shading
except IndexError:
cell_shading = OxmlElement('w:shd') # add new w:shd element to it
if fill:
cell_shading.set(qn('w:fill'), fill) # set fill property, respecting namespace
if color:
pass # TODO
if val:
pass # TODO
cell_properties.append(cell_shading) # finally extend cell props with shading element
如果需要,可以随意扩展其他属性
因此,根据您的示例,一旦有了表,在保存文档之前,请添加以下行:
_set_cell_background(table.rows[0].cells[0], 'FF0000')
doc.save("Testing.docx")