如何根据 openpyxl 中的值(负值或正值)更改图表的颜色?

How to change chart's color based on value (negative or positive values) in openpyxl?

如何在 openpyxl 中根据值(负值或正值)更改图表的颜色?
对我来说真的很难。

from openpyxl import Workbook
from openpyxl.styles import Border, Side, PatternFill, Font, GradientFill,Alignment, Color, numbers
from openpyxl.chart import BarChart, Reference

book = Workbook()
sheet = book.active
rows = [
['Number', 'Batch 1'],
['a', 40],
['b', -40],
['c', 50],
['d', -30],
['e', -25],
['f', 30],
]

for row in rows:
    sheet.append(row)

chart = BarChart()
chartCats = Reference(sheet, min_col=1, min_row=2, max_row=7)
chartData = Reference(sheet, min_col=2, min_row=1, max_col=2, max_row=7)
chart.add_data(chartData, titles_from_data = True)
chart.set_categories(chartCats)
chart.type = 'bar'
chart.style = 27
chart.height = 10
chart.width = 15
chart.legend = None
chart.x_axis.tickLblPos = "low"
chart.y_axis.number_format = '#,##0'
chart.y_axis.majorGridlines = None
sheet.add_chart(chart, 'A1')
book.save('test.xlsx')

上面的代码创建了标题为“Batch1”的图表。但我想要“Batch2”,其中负值和正值显示不同的颜色。

目前无法使用 openpyxl 完成此操作。按照 https://www.extendoffice.com/documents/excel/2218-excel-chart-negative-values-different-color.html 的说明,我在 Excel 中创建了一个图表,并对数据系列应用了差异格式。虽然 openpyxl 确实支持系列的 invertIfNegative 属性,但原始 OOXML 规范不允许数据系列的其他颜色。这是使用对原始规范的扩展来完成的。

这可以用 class

来实现
openpyxl.chart.marker.DataPoint()

和属性图形属性。这是基于您的代码的示例。我使用的OpenPyXl版本是2.5.1.

import openpyxl
from openpyxl import Workbook
from openpyxl.styles import Border, Side, PatternFill, Font, GradientFill,Alignment, Color, numbers
from openpyxl.chart import BarChart, Reference

book = Workbook()
sheet = book.active
rows = [
['Number', 'Batch 1'],
['a', 40],
['b', -40],
['c', 50],
['d', -30],
['e', -25],
['f', 30],
]

for row in rows:
    sheet.append(row)

chart = BarChart()
chartCats = Reference(sheet, min_col=1, min_row=2, max_row=7)
chartData = Reference(sheet, min_col=2, min_row=1, max_col=2, max_row=7)
chart.add_data(chartData, titles_from_data = True)
chart.set_categories(chartCats)
chart.type = 'bar'
chart.style = 27
chart.height = 10
chart.width = 15
chart.legend = None
chart.x_axis.tickLblPos = "low"
chart.y_axis.number_format = '#,##0'
chart.y_axis.majorGridlines = None

series = chart.series[0]
for i in range(len(rows)-1):
    if rows[i+1][1] < 0:
        pt = openpyxl.chart.marker.DataPoint(idx=i)
        pt.graphicalProperties.line.solidFill = 'A2B966'
        pt.graphicalProperties.solidFill = 'A2B966'
        series.dPt.append(pt)

sheet.add_chart(chart, 'A1')
book.save('test.xlsx')