有一个基于一个word版本的报告自动生成的需求,原本计划内容全部自动生成,调研发现内容过于庞大,且实现复杂度较高,所以采取一个折中方案,通过修改一个模板文件实现,将内容通过插入和替换方式加入,以下为部分核心代码。仅仅记录一下,另外有一个巨坑 ,python的docx是基于office的,不支持WPS 不支持WPS 不支持WPS。
生成段落内容,并插入到指定位置。支持设定段落样式
def add_doc_paragraph_tp(document, para_content,after_p=None,style_name=None, font_size=None, font_name=None, format_size=None,font_bold=False):
'''
添加段落,默认只添加内容不设置格式,当传递格式时,可根据自定义设置
:param document:
:param para_content: 段落内容
:param after_p: 欲将创建的段落移动至该段落后
:param styles: 段落样式
:param font_size: 字体大小
:param font_name: 字体名称
:param format_size: 缩进大小
:return:
'''
p = document.add_paragraph()
p_format = p.paragraph_format # 段落格式
# if pa_style:
# p.style = document.styles[pa_style]
p_run = p.add_run(para_content)
p_run.font.name = font_name if font_name else u'宋体中文正文'
p_run.font.size = Pt(font_size) if font_size else Pt(10.5)
if font_bold:
p_run.font.bold = True
if style_name:
p.style = document.styles[style_name]
else:
# if ('Heading'not in pa_style) or ('List' not in pa_style):
p_format.first_line_indent = Cm(format_size) if format_size else Cm(0.74)
if after_p:
move_paragraph_after(p,after_p)
return p
调用方法
result_data_content_para = add_doc_paragraph_tp(report_template, ' 我是文本内容',after_p=result_data_para,font_size=10.5, font_name='宋体', font_bold=True)
生成表格内容
def add_df_table(df,document,after_p=None,query_name=None,type=None,width_dict=None):
'''
通过dataframe添加表格
:param df: dataframe
:param document:
:param query_name: 查询字段
:param type: 查询条件
:return:
'''
cos_list = df.columns.values.tolist() #列名转list
if type:
cos_list.remove(query_name) #剔除条件列
table_df = df.loc[df[query_name]==type] #根据条件进行筛选
# table_df = df.query('@query_name == @type')
table_df = table_df[cos_list] #过滤得到需要的数据
else:
table_df = df
table_row_count = table_df.shape[0]+1 # 创建docx table, 行数为原df行数 + 1(第1行表头)
if table_row_count == 1:
table_row_count = table_row_count+1
table_col_count = table_df.shape[1] # 列数位df 的列数
table = document.add_table(table_row_count, table_col_count)
table_title_background_colour(table,table_col_count,'C0C0C0') #设置表头格式
table.style = 'Table Grid' # 表格格式
#添加docx表头里的文字 = 提取的df.columns
table_title(table,table_df) #添加表格标题
#设定单元格宽度
if width_dict:
for col_num in range(len(width_dict)):
table.cell(0, col_num).width = Inches(width_dict[col_num])
#填充数据
for i in range(table_df.shape[0]):
for j in range(table_df.shape[-1]):
if pd.isnull(table_df.iat[i, j]):
cell_v = '待补充'
else:
cell_v = str(table_df.values[i, j])
# print(table_df.values[i, j])
run = table.cell(i+1, j).paragraphs[0].add_run(cell_v)
run.font.name = '宋体' # 字体
run.font.size = Pt(10)
table.cell(i+1, j).paragraphs[0].alignment = WD_ALIGN_PARAGRAPH.CENTER # 水平居中
table.cell(i+1, j).vertical_alignment = WD_ALIGN_VERTICAL.CENTER # 垂直据中国
if after_p:
move_table_after(table,after_p)
return table
基于Key值合并单元格
def merge_table(merge_df,merge_table,merge_cols_index,merge_cols_list):
'''
:param merge_df: 待合并单元和的dataframe
:param merge_table: 待合并单元格
:param merge_cols_index: 合并单元格参考列的index
:param merge_cols_list: 待合并单元的列index 为list类型,支持多列根据参照列合并
:return:
'''
for merge_cols in merge_cols_list:
merge_dict = {}
# merge_end_index = 1
for i in range(merge_df.shape[0]):
current_inx = i + 1
# 当达到最大index后,next_inx和current_inx 保持一致,其他情况next则执行+1操作
if current_inx == merge_df.shape[0]:
next_inx = current_inx
else:
merge_end_inx = next_inx = current_inx + 1
current_cell = merge_table.cell(current_inx, merge_cols_index)
next_cell = merge_table.cell(next_inx, merge_cols_index)
# 获取需要合并的字段及其First、END值
if current_cell.text not in merge_dict.keys():
# 当字段没有在字典中时,初始化first和end值,置为该字段第一次出现的位置
merge_first_inx = current_inx
merge_end_inx = current_inx
else:
if current_cell.text != next_cell.text:
# 当下一行数据和当前行数据不一致时,说明有新的数据产生,此时将下一行inx-1就是需要合并的最后一行inx
merge_end_inx = next_inx - 1
merge_dict[current_cell.text] = [merge_first_inx, merge_end_inx]
for merge_item in merge_dict:
first_cell = merge_table.cell(merge_dict[merge_item][0], merge_cols)
end_cell = merge_table.cell(merge_dict[merge_item][1], merge_cols)
merge_cell = first_cell.merge(end_cell)
merge_cell.text = first_cell.text.split('\n')[0]
return merge_table
本文介绍了一个简化版的报告自动生成方案,通过修改Word模板实现内容插入,重点展示了如何添加段落和表格,以及合并单元格的技巧,以降低复杂度并兼容WPS文档。
2815

被折叠的 条评论
为什么被折叠?



