Word处理——python-docx表格插入
一、表格创建基础
1.1 创建基本表格
from docx import Document
doc = Document()
# 创建表格(3行4列)
table = doc.add_table(rows=3, cols=4)
# 填充数据
data = [
['姓名', '年龄', '城市', '职业'],
['张三', '25', '北京', '工程师'],
['李四', '30', '上海', '设计师']
]
for i, row_data inenumerate(data):
row = table.rows[i]
for j, value inenumerate(row_data):
row.cells[j].text = str(value)
doc.save('basic_table.docx')
1.2 表格样式
from docx import Document
doc = Document()
# 创建表格并应用样式
table = doc.add_table(rows=4, cols=4)
table.style = 'Light Grid Accent 1'# 应用表格样式
# 填充数据
data = [
['产品', 'Q1', 'Q2', 'Q3'],
['产品A', '100', '120', '110'],
['产品B', '80', '90', '100'],
['产品C', '120', '110', '130']
]
for i, row_data inenumerate(data):
row = table.rows[i]
for j, value inenumerate(row_data):
row.cells[j].text = str(value)
# 查看可用样式
print("可用表格样式:")
for style in doc.styles:
if style.type == 2: # 表格样式
print(f" {style.name}")
doc.save('styled_table.docx')
二、表格属性设置
2.1 行和列操作
from docx import Document
from docx.shared import Inches
doc = Document()
# 创建表格
table = doc.add_table(rows=3, cols=3)
# 设置行高
for row in table.rows:
row.height = Inches(0.5)
# 设置列宽
table.columns[0].width = Inches(1.5)
table.columns[1].width = Inches(2.0)
table.columns[2].width = Inches(1.5)
# 填充数据
data = [
['列1', '列2', '列3'],
['数据1', '数据2', '数据3'],
['数据4', '数据5', '数据6']
]
for i, row_data inenumerate(data):
row = table.rows[i]
for j, value inenumerate(row_data):
row.cells[j].text = str(value)
doc.save('table_properties.docx')
2.2 单元格合并
from docx import Document
doc = Document()
# 创建表格
table = doc.add_table(rows=5, cols=5)
# 水平合并(合并第一行)
table.cell(0, 0).merge(table.cell(0, 4))
table.cell(0, 0).text = '水平合并标题'
# 垂直合并(合并第一列)
table.cell(1, 0).merge(table.cell(4, 0))
table.cell(1, 0).text = '垂直合并'
# 合并块(合并2x2区域)
table.cell(1, 1).merge(table.cell(2, 2))
table.cell(1, 1).text = '2x2合并块'
# 填充其他数据
for i inrange(1, 5):
for j inrange(1, 5):
if table.cell(i, j).text == '':
table.cell(i, j).text = f'({i},{j})'
doc.save('merged_table.docx')
三、表格内容格式化
3.1 单元格文本格式
from docx import Document
from docx.shared import Pt, RGBColor
from docx.enum.text import WD_ALIGN_PARAGRAPH, WD_PARAGRAPH_ALIGNMENT
doc = Document()
table = doc.add_table(rows=3, cols=3)
# 表头
headers = ['姓名', '年龄', '城市']
for i, header inenumerate(headers):
cell = table.cell(0, i)
cell.text = header
# 设置表头样式
for paragraph in cell.paragraphs:
paragraph.alignment = WD_ALIGN_PARAGRAPH.CENTER
for run in paragraph.runs:
run.bold = True
run.font.size = Pt(14)
run.font.color.rgb = RGBColor(255, 255, 255)
# 设置表头背景色(通过单元格属性)
from docx.oxml import OxmlElement
shading = OxmlElement('w:shd')
shading.set('{http://schemas.openxmlformats.org/wordprocessingml/2006/main}val', 'solid')
shading.set('{http://schemas.openxmlformats.org/wordprocessingml/2006/main}color', 'auto')
shading.set('{http://schemas.openxmlformats.org/wordprocessingml/2006/main}fill', '4472C4')
cell._tc.get_or_add_tcPr().append(shading)
# 数据行
data = [['张三', '25', '北京'], ['李四', '30', '上海']]
for i, row_data inenumerate(data, start=1):
for j, value inenumerate(row_data):
cell = table.cell(i, j)
cell.text = value
cell.paragraphs[0].alignment = WD_ALIGN_PARAGRAPH.CENTER
doc.save('formatted_table.docx')
3.2 单元格内多个段落
from docx import Document
from docx.shared import Pt, RGBColor
from docx.enum.text import WD_ALIGN_PARAGRAPH
doc = Document()
table = doc.add_table(rows=2, cols=2)
# 单元格内添加多个段落
cell = table.cell(0, 0)
p1 = cell.add_paragraph('第一段内容')
p1.alignment = WD_ALIGN_PARAGRAPH.CENTER
p2 = cell.add_paragraph('第二段内容')
p2.alignment = WD_ALIGN_PARAGRAPH.CENTER
# 添加带格式的段落
cell = table.cell(0, 1)
p = cell.add_paragraph()
run = p.add_run('粗体文本')
run.bold = True
run.font.size = Pt(14)
p = cell.add_paragraph()
p.add_run('普通文本')
# 添加列表样式
cell = table.cell(1, 0)
cell.add_paragraph('项目1', style='List Bullet')
cell.add_paragraph('项目2', style='List Bullet')
cell.add_paragraph('项目3', style='List Bullet')
doc.save('multi_paragraph_table.docx')
四、高级表格操作
4.1 动态表格生成
from docx import Document
from docx.shared import Inches, Pt
classDynamicTable:
"""动态表格生成器"""
def__init__(self, doc):
self.doc = doc
defcreate_table(self, headers, data, title=None):
"""创建表格"""
# 如果有标题,先添加标题
if title:
self.doc.add_heading(title, level=2)
# 创建表格
table = self.doc.add_table(rows=1, cols=len(headers))
table.style = 'Light Grid Accent 1'
# 添加表头
for i, header inenumerate(headers):
table.rows[0].cells[i].text = header
# 添加数据
for row_data in data:
row = table.add_row()
for i, value inenumerate(row_data):
row.cells[i].text = str(value)
return table
defcreate_summary_table(self, data, summary_fields):
"""创建汇总表"""
table = self.doc.add_table(rows=1, cols=2)
table.style = 'Light Shading Accent 1'
for key, value in data.items():
row = table.add_row()
row.cells[0].text = key
row.cells[1].text = str(value)
return table
# 使用
doc = Document()
dt = DynamicTable(doc)
# 创建数据表
headers = ['产品', '销量', '单价', '总价']
data = [
['产品A', '100', '50', '5000'],
['产品B', '80', '60', '4800'],
['产品C', '120', '45', '5400']
]
dt.create_table(headers, data, '销售数据表')
# 创建汇总表
summary_data = {
'总销量': 300,
'总销售额': 15200,
'平均单价': 51.67
}
dt.create_summary_table(summary_data, None)
doc.save('dynamic_table.docx')
4.2 表格样式预设
from docx import Document
from docx.shared import Pt, RGBColor
from docx.enum.text import WD_ALIGN_PARAGRAPH
from docx.oxml import OxmlElement
classTableStyler:
"""表格样式预设"""
@staticmethod
defapply_header_style(cell):
"""应用表头样式"""
# 文本样式
for paragraph in cell.paragraphs:
paragraph.alignment = WD_ALIGN_PARAGRAPH.CENTER
for run in paragraph.runs:
run.bold = True
run.font.size = Pt(12)
run.font.color.rgb = RGBColor(255, 255, 255)
# 背景色
shading = OxmlElement('w:shd')
shading.set('{http://schemas.openxmlformats.org/wordprocessingml/2006/main}val', 'solid')
shading.set('{http://schemas.openxmlformats.org/wordprocessingml/2006/main}color', 'auto')
shading.set('{http://schemas.openxmlformats.org/wordprocessingml/2006/main}fill', '4472C4')
cell._tc.get_or_add_tcPr().append(shading)
@staticmethod
defapply_center_style(cell):
"""应用居中样式"""
for paragraph in cell.paragraphs:
paragraph.alignment = WD_ALIGN_PARAGRAPH.CENTER
@staticmethod
defapply_left_style(cell):
"""应用左对齐样式"""
for paragraph in cell.paragraphs:
paragraph.alignment = WD_ALIGN_PARAGRAPH.LEFT
@staticmethod
defapply_right_style(cell):
"""应用右对齐样式"""
for paragraph in cell.paragraphs:
paragraph.alignment = WD_ALIGN_PARAGRAPH.RIGHT
@staticmethod
defapply_highlight_style(cell):
"""应用高亮样式"""
shading = OxmlElement('w:shd')
shading.set('{http://schemas.openxmlformats.org/wordprocessingml/2006/main}val', 'solid')
shading.set('{http://schemas.openxmlformats.org/wordprocessingml/2006/main}color', 'auto')
shading.set('{http://schemas.openxmlformats.org/wordprocessingml/2006/main}fill', 'FFFF00')
cell._tc.get_or_add_tcPr().append(shading)
@staticmethod
defstyle_table(table, header_rows=1):
"""为整个表格应用样式"""
for i, row inenumerate(table.rows):
for cell in row.cells:
if i < header_rows:
TableStyler.apply_header_style(cell)
else:
TableStyler.apply_center_style(cell)
# 使用
doc = Document()
table = doc.add_table(rows=3, cols=4)
# 填充数据
data = [
['姓名', '年龄', '城市', '职业'],
['张三', '25', '北京', '工程师'],
['李四', '30', '上海', '设计师']
]
for i, row_data inenumerate(data):
row = table.rows[i]
for j, value inenumerate(row_data):
row.cells[j].text = value
# 应用样式
TableStyler.style_table(table, header_rows=1)
doc.save('styled_table_preset.docx')
五、实战案例
5.1 销售报表生成
from docx import Document
from docx.shared import Inches, Pt, RGBColor
from docx.enum.text import WD_ALIGN_PARAGRAPH
from datetime import datetime
classSalesReport:
"""销售报表生成器"""
def__init__(self):
self.doc = Document()
self._setup_styles()
def_setup_styles(self):
"""设置样式"""
styles = self.doc.styles
title_style = styles.add_style('ReportTitle', 1)
title_style.font.size = Pt(18)
title_style.font.bold = True
title_style.paragraph_format.alignment = WD_ALIGN_PARAGRAPH.CENTER
subtitle_style = styles.add_style('ReportSubtitle', 1)
subtitle_style.font.size = Pt(12)
subtitle_style.font.color.rgb = RGBColor(128, 128, 128)
subtitle_style.paragraph_format.alignment = WD_ALIGN_PARAGRAPH.CENTER
defadd_title(self, title, subtitle=None):
"""添加标题"""
p = self.doc.add_paragraph(title, style='ReportTitle')
if subtitle:
self.doc.add_paragraph(subtitle, style='ReportSubtitle')
defadd_summary(self, data):
"""添加汇总信息"""
self.doc.add_heading('汇总信息', level=2)
table = self.doc.add_table(rows=1, cols=2)
table.style = 'Light Shading Accent 1'
for key, value in data.items():
row = table.add_row()
row.cells[0].text = key
row.cells[1].text = str(value)
defadd_sales_table(self, data, title=None):
"""添加销售数据表"""
if title:
self.doc.add_heading(title, level=2)
table = self.doc.add_table(rows=1, cols=len(data[0]))
table.style = 'Light Grid Accent 1'
# 表头
for i, header inenumerate(data[0]):
table.rows[0].cells[i].text = header
# 数据
for row_data in data[1:]:
row = table.add_row()
for i, value inenumerate(row_data):
row.cells[i].text = str(value)
return table
defadd_monthly_summary(self, months_data):
"""添加月度汇总"""
self.doc.add_heading('月度销售汇总', level=2)
table = self.doc.add_table(rows=1, cols=3)
table.style = 'Light Grid Accent 1'
headers = ['月份', '总销售额', '订单数']
for i, header inenumerate(headers):
table.rows[0].cells[i].text = header
for month_data in months_data:
row = table.add_row()
row.cells[0].text = month_data['month']
row.cells[1].text = f"¥{month_data['sales']:,}"
row.cells[2].text = str(month_data['orders'])
defsave(self, filename):
"""保存文件"""
self.doc.save(filename)
# 使用
report = SalesReport()
report.add_title('2024年度销售报告', f'生成时间: {datetime.now().strftime("%Y-%m-%d")}')
# 汇总信息
report.add_summary({
'总销售额': '¥152,000',
'总订单数': '1,200',
'平均客单价': '¥126.67',
'客户数': '350'
})
# 销售数据
sales_data = [
['产品', 'Q1', 'Q2', 'Q3', 'Q4', '合计'],
['产品A', '10,000', '12,000', '11,000', '13,000', '46,000'],
['产品B', '8,000', '9,000', '10,000', '11,000', '38,000'],
['产品C', '12,000', '11,000', '13,000', '14,000', '50,000']
]
report.add_sales_table(sales_data, '产品销售数据')
# 月度汇总
months_data = [
{'month': '1月', 'sales': 12000, 'orders': 100},
{'month': '2月', 'sales': 14000, 'orders': 120},
{'month': '3月', 'sales': 13000, 'orders': 110}
]
report.add_monthly_summary(months_data)
report.save('sales_report.docx')
5.2 数据导出工具
from docx import Document
from docx.shared import Inches, Pt
import pandas as pd
classDataExporter:
"""数据导出工具"""
def__init__(self):
self.doc = Document()
defexport_dataframe(self, df, title=None):
"""导出DataFrame到Word表格"""
if title:
self.doc.add_heading(title, level=2)
# 创建表格
table = self.doc.add_table(rows=1, cols=len(df.columns))
table.style = 'Light Grid Accent 1'
# 表头
for i, col inenumerate(df.columns):
table.rows[0].cells[i].text = str(col)
# 数据
for _, row in df.iterrows():
table_row = table.add_row()
for i, value inenumerate(row):
table_row.cells[i].text = str(value)
return table
defexport_summary(self, df, title='数据摘要'):
"""导出数据摘要"""
self.doc.add_heading(title, level=2)
# 基本统计
stats = {
'行数': len(df),
'列数': len(df.columns),
'列名': ', '.join(df.columns),
'缺失值总数': df.isnull().sum().sum()
}
table = self.doc.add_table(rows=1, cols=2)
table.style = 'Light Shading Accent 1'
for key, value in stats.items():
row = table.add_row()
row.cells[0].text = key
row.cells[1].text = str(value)
# 数值列统计
numeric_cols = df.select_dtypes(include=['float64', 'int64']).columns
iflen(numeric_cols) > 0:
self.doc.add_heading('数值统计', level=3)
stats_table = self.doc.add_table(rows=1, cols=len(numeric_cols) + 1)
stats_table.style = 'Light Grid Accent 1'
# 统计指标
stats_row = stats_table.rows[0]
stats_row.cells[0].text = '指标'
for i, col inenumerate(numeric_cols, start=1):
stats_row.cells[i].text = col
# 统计值
for stat_name, stat_func in [('均值', 'mean'), ('中位数', 'median'), ('标准差', 'std')]:
row = stats_table.add_row()
row.cells[0].text = stat_name
for i, col inenumerate(numeric_cols, start=1):
value = getattr(df[col], stat_func)()
row.cells[i].text = f'{value:.2f}'
defsave(self, filename):
"""保存文档"""
self.doc.save(filename)
# 使用
df = pd.DataFrame({
'姓名': ['张三', '李四', '王五'],
'年龄': [25, 30, 28],
'工资': [8000, 12000, 9500],
'部门': ['技术', '销售', '技术']
})
exporter = DataExporter()
exporter.export_dataframe(df, '员工信息表')
exporter.export_summary(df, '员工数据摘要')
exporter.save('data_export.docx')
六、总结
# 快速参考
# 1. 创建表格
table = doc.add_table(rows=3, cols=3)
# 2. 填充数据
row = table.rows[0]
row.cells[0].text = '内容'
# 3. 添加行
row = table.add_row()
# 4. 合并单元格
table.cell(0, 0).merge(table.cell(0, 2))
# 5. 设置列宽
table.columns[0].width = Inches(1.5)
# 6. 设置行高
row.height = Inches(0.5)
# 7. 应用样式
table.style = 'Light Grid Accent 1'
# 8. 单元格格式
cell.paragraphs[0].alignment = WD_ALIGN_PARAGRAPH.CENTER
# 9. 添加多个段落
cell.add_paragraph('新段落')
# 10. 表格遍历
for row in table.rows:
for cell in row.cells:
print(cell.text)
python-docx提供了完整的Word表格操作功能,包括创建、样式设置、数据填充等。掌握表格操作可以生成包含结构化数据的专业文档,适用于报表生成、数据导出等场景。结合样式预设和动态生成,可以提高文档创建的效率和质量。
夜雨聆风