如何在Openpyxl中修改图表坐标轴格式时保留原有标题
保留Excel坐标轴标题内容的图表格式化方案
工作中需批量格式化50余个特定样式的Excel图表,仅坐标轴标题需根据客户需求手动修改。现有代码可完成图表样式格式化,但存在核心问题:运行时会将坐标轴标题替换为默认值"Default",第二次处理同一文件时,旧图表的自定义标题会被覆盖。需要修改代码实现仅应用格式、保留原有坐标轴标题内容的效果。
原代码问题分析
原代码通过XML模板直接设置坐标轴标题的内容和格式,强制将标题替换为传入的xt_name/yt_name参数值(默认是"Default"),没有读取并保留原有标题文本,导致二次运行时覆盖自定义内容。
修改后的完整代码
import openpyxl as opyxl from openpyxl.styles import Font from openpyxl.chart.text import RichText from openpyxl.drawing.text import Paragraph, ParagraphProperties, CharacterProperties, Font, RegularTextRun from openpyxl.xml.functions import fromstring from openpyxl.chart.shapes import GraphicalProperties def graph_formatting(file, font_style='Times New Roman', fill_color="000000", font_size=1000, bold='0'): wb = opyxl.load_workbook(file) for sheets in wb.chartsheets: dechart = sheets._charts[0] # 获取Y轴原有标题文本,无标题则设为空字符串 y_title_text = "" if dechart.y_axis.title and dechart.y_axis.title.tx and dechart.y_axis.title.tx.rich: # 提取RichText中的文本内容 for para in dechart.y_axis.title.tx.rich.p: for run in para.r: if hasattr(run, 't'): y_title_text += run.t # 构建Y轴标题格式XML,复用原有文本 xml = f""" <txPr> <a:p xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main"> <a:r> <a:rPr b="{bold}" i="0" sz="{font_size}" spc="-1" strike="noStrike"> <a:solidFill> <a:srgbClr val="{fill_color}" /> </a:solidFill> <a:latin typeface="{font_style}" /> </a:rPr> <a:t>{y_title_text}</a:t> </a:r> </a:p> </txPr> """ dechart.y_axis.title.tx.rich = RichText.from_tree(fromstring(xml)) # 获取X轴原有标题文本,无标题则设为空字符串 x_title_text = "" if dechart.x_axis.title and dechart.x_axis.title.tx and dechart.x_axis.title.tx.rich: for para in dechart.x_axis.title.tx.rich.p: for run in para.r: if hasattr(run, 't'): x_title_text += run.t # 构建X轴标题格式XML,复用原有文本 xml = f""" <txPr> <a:p xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main"> <a:r> <a:rPr b="{bold}" i="0" sz="{font_size}" spc="-1" strike="noStrike"> <a:solidFill> <a:srgbClr val="{fill_color}" /> </a:solidFill> <a:latin typeface="{font_style}" /> </a:rPr> <a:t>{x_title_text}</a:t> </a:r> </a:p> </txPr> """ dechart.x_axis.title.tx.rich = RichText.from_tree(fromstring(xml)) # 修改坐标轴标签字体(原逻辑保留) font = Font(typeface=font_style) cp = CharacterProperties(latin=font, sz=font_size, b=False) dechart.x_axis.txPr = RichText(p=[Paragraph(pPr=ParagraphProperties(defRPr=cp), endParaRPr=cp)]) dechart.y_axis.txPr = RichText(p=[Paragraph(pPr=ParagraphProperties(defRPr=cp), endParaRPr=cp)]) # 图表其他样式设置(原逻辑保留) dechart.graphical_properties = GraphicalProperties() dechart.graphical_properties.line.noFill = True dechart.graphical_properties.line.prstDash = None dechart.x_axis.graphicalProperties.line.solidFill = fill_color dechart.y_axis.graphicalProperties.line.noFill = False dechart.y_axis.majorGridlines = None dechart.y_axis.majorTickMark = 'out' dechart.x_axis.majorTickMark = 'out' wb.save(file)
关键改动说明
- 读取原有标题文本:在生成XML模板前,从图表坐标轴标题的
RichText对象中提取已有的文本内容,同时处理无标题的边界情况,避免报错。 - 移除默认标题参数:删除函数参数中的
xt_name和yt_name,不再强制传入默认值,完全依赖原有标题内容。 - XML模板复用文本:将XML中的标题内容部分替换为读取到的原有文本,确保格式应用的同时保留原始标题。
修改后运行代码可实现:
- 保留所有已手动设置的坐标轴标题内容
- 仅对标题应用指定的字体、颜色、大小等格式
- 新增图表未设置标题时,保持为空而非被"Default"填充
内容的提问来源于stack exchange,提问作者Dynasty2468
相关产品推荐
相关产品推荐

