使用python-docx设置Word文档页眉页脚图片宽度与叠放位置
问题解答
该需求完全可以实现,你现有代码的核心问题如下:
- 页脚图片直接调用
mydoc.add_picture(),会插入到正文末尾,没有放到页脚区域 - 页眉两张图片默认是行内元素,无法实现层叠、错位对齐效果
- 硬编码图片宽度为5英寸,没有适配页面实际可用宽度
修改后可运行代码
from docx import Document from docx.shared import Inches, Pt from docx.enum.style import WD_STYLE_TYPE from docx.oxml import OxmlElement, qn from docx.oxml.ns import nsdecls # 辅助函数:设置图片为浮动布局,设置绝对位置 def set_picture_float(picture, x_pos, y_pos): # 获取图片的ct_Pic元素 pic = picture._inline # 添加浮动属性 anchor = OxmlElement('wp:anchor') anchor.set('distT', '0') anchor.set('distB', '0') anchor.set('distL', '0') anchor.set('distR', '0') anchor.set('simplePos', '0') anchor.set('relativeHeight', '1') anchor.set('behindDoc', '0') # 0表示在前景,1表示在背景 anchor.set('locked', '0') anchor.set('layoutInCell', '1') anchor.set('allowOverlap', '1') # 设置位置相对于页面左上角 simple_pos = OxmlElement('wp:simplePos') simple_pos.set('x', '0') simple_pos.set('y', '0') anchor.append(simple_pos) position_h = OxmlElement('wp:positionH') position_h.set('relativeFrom', 'page') pos_x = OxmlElement('wp:posOffset') pos_x.text = str(int(x_pos * 914400)) # 英寸转EMU单位 position_h.append(pos_x) anchor.append(position_h) position_v = OxmlElement('wp:positionV') position_v.set('relativeFrom', 'page') pos_y = OxmlElement('wp:posOffset') pos_y.text = str(int(y_pos * 914400)) position_v.append(pos_y) anchor.append(position_v) # 复制原有inline的大小等属性 extent = OxmlElement('wp:extent') extent.set('cx', str(pic.extent.cx)) extent.set('cy', str(pic.extent.cy)) anchor.append(extent) effect_extent = OxmlElement('wp:effectExtent') effect_extent.set('l', '0') effect_extent.set('t', '0') effect_extent.set('r', '0') effect_extent.set('b', '0') anchor.append(effect_extent) wrap_square = OxmlElement('wp:wrapNone') anchor.append(wrap_square) doc_pr = OxmlElement('wp:docPr') doc_pr.set('id', '1') doc_pr.set('name', 'Picture 1') anchor.append(doc_pr) c_nv_pr = OxmlElement('wp:cNvGraphicFramePr') anchor.append(c_nv_pr) graphic = OxmlElement('a:graphic') graphic.set(nsdecls('a'), 'http://schemas.openxmlformats.org/drawingml/2006/main') graphic_data = OxmlElement('a:graphicData') graphic_data.set('uri', 'http://schemas.openxmlformats.org/drawingml/2006/picture') graphic_data.append(pic.graphic.graphicData.pic) graphic.append(graphic_data) anchor.append(graphic) # 替换原有inline元素为anchor元素 pic.getparent().replace(pic, anchor) # 原有逻辑 docpath="/Users/ricardosimoes/Desktop/DESKTOP/Jira/my_word_file.docx" mydoc = Document() section = mydoc.sections[0] # 计算页面可用宽度(页面总宽 - 左右边距) page_usable_width = section.page_width - section.left_margin - section.right_margin # titulo.png的高度设为1英寸,后续logo对齐用 titulo_height = Inches(1) # 页眉设置 header = section.header paragraph_h = header.paragraphs[0] # 先加titulo.png,宽度适配页面全宽 runheader = paragraph_h.add_run() titulo_pic = runheader.add_picture("client_report/report_img/titulo.png", width=page_usable_width, height=titulo_height) # 再加titulo_logo.png,设置为浮动,对齐到titulo.png左下角 # X坐标为左边距,Y坐标为页眉上边距 + titulo.png高度 - logo高度(logo高度可自行调整) logo_height = Inches(0.3) runheader_logo = paragraph_h.add_run() logo_pic = runheader_logo.add_picture("client_report/report_img/titulo_logo.png", height=logo_height) set_picture_float(logo_pic, section.left_margin.inches, (section.top_margin + titulo_height - logo_height).inches) # 页脚设置(修正原来的错误,把bottom.png放到页脚里) footer = section.footer paragraph_f = footer.paragraphs[0] runfooter = paragraph_f.add_run() runfooter.add_picture("client_report/report_img/bottom.png", width=page_usable_width, height=Inches(1)) # 你原有其他样式、背景设置的代码 styles = mydoc.styles style = styles.add_style('Tahoma',WD_STYLE_TYPE.PARAGRAPH) style.font.name = 'Tahoma' style.font.size = Pt(11) shd = OxmlElement('w:background') shd.set(qn('w:color'), '#0000FF') shd.set(qn('w:themeColor'), 'text1') shd.set(qn('w:themeTint'), 'F2') mydoc.element.insert(0, shd) shd1 = OxmlElement('w:displayBackgroundShape') mydoc.settings.element.insert(0, shd1) mydoc.save(docpath)
关键修改说明
- 自动计算页面可用宽度,titulo.png和bottom.png的宽度直接使用该值,自动适配页面全宽
- 通过修改图片的XML属性实现浮动布局,将titulo_logo.png设置为绝对定位,坐标对齐titulo.png的左下角
- 修正了页脚图片的插入逻辑,将bottom.png正确插入到页脚区域而非正文
内容的提问来源于stack exchange,提问作者mrpy
相关产品推荐
相关产品推荐

