說明
如圖,表格中已有Sheet 數(shù)據(jù),每組用一行空白隔開。
本工具為每組各生成一個(gè)柱形圖,從上向下放置在新創(chuàng)建的Sheet 圖表 中。
具體的生成過程和方法見下面的具體代碼及注釋。

數(shù)據(jù).png

圖表.png
具體代碼
生成excel條形圖.py
import os
import sys
from openpyxl import load_workbook
from openpyxl import chart
from openpyxl.chart import BarChart, Reference, Series
from openpyxl.chart.series import SeriesLabel
if __name__ == "__main__":
# 柱形圖的樣式風(fēng)格
BarChartStyle = 1
# 每個(gè)柱形圖的名稱
TitleNameCol = 1
TitleNameSuffix = '1-6月興趣班報(bào)名人數(shù)對比'
# X軸的單位,一般是日期,如1、2、3、4月
CategoriesCnt = 6
MinCategoriesCol = 2
MaxCategoriesCol = MinCategoriesCol + CategoriesCnt - 1
# 每個(gè)x的單位中有幾類值,這幾類值的名字、(柱子的)顏色分別是什么
SeriesCnt = 5
SeriesTitles = ['2021年','2022年','2023年','2024年','2025年']
SeriesColors = ['5B9BD5','ED7D31','FF0000','00FF00','0000FF']
# 類型的Title在哪個(gè)位置顯示:'b', 'tr'(右上 top right), 'l', 'r', 't'
SeriesTitlePos = 'b'
# 圖的高和寬。高的1約等于2個(gè)row的高度,比2個(gè)row小
ChartHeight = 15
ChartHeightToRowFactor = 2
ChartWidth = 20
# 每個(gè)x的單位中的幾類值(柱子)之間的重疊程度(負(fù)數(shù)表示不重疊且有間隔)
ChartPerBarInSeriesOverlap = -20
# 表格文件放在和當(dāng)前py文件同目錄下
dir = os.path.dirname(sys.argv[0])
fileName = 'TestChart.xlsx'
filePath = os.path.join(dir,fileName)
workbook = load_workbook(filePath)
# 表格中已有一個(gè)sheet,名為'數(shù)據(jù)',基于此生成各柱形圖。創(chuàng)建一個(gè)新sheet'圖表'用于放置柱形圖
dataSheet = workbook['數(shù)據(jù)']
chartSheet = workbook.create_sheet('圖表')
# 一共要繪制幾張柱形圖?每個(gè)柱形圖數(shù)據(jù)上方是一個(gè)空行(依此找到各圖對應(yīng)的第一行數(shù)據(jù))
rowNums = []
for row in dataSheet.iter_rows():
curCell = row[0]
if curCell.value is None:
rowNums.append(curCell.row+1)
print(f'要生成的柱形圖的數(shù)量為{len(rowNums)},各圖對應(yīng)的數(shù)據(jù)的第一行的行號分別為{rowNums}')
# 依次生成各柱形圖
for i in range(len(rowNums)):
# 生成柱形圖的具體步驟
rowNum = rowNums[i]
# 對于每組(一張柱形圖對應(yīng)一組)數(shù)據(jù),第一行是本組的category,下面的幾行是具體數(shù)據(jù)
categories = Reference(dataSheet, min_row=rowNum, max_row=rowNum, min_col=MinCategoriesCol, max_col=MaxCategoriesCol)
valueBeginRow = rowNum+1
values = Reference(dataSheet, min_row=valueBeginRow, max_row=rowNum+SeriesCnt, min_col=MinCategoriesCol,max_col=MaxCategoriesCol)
titleName = dataSheet.cell(valueBeginRow,TitleNameCol).value
curChart = BarChart()
curChart.style = BarChartStyle
curChart.title = f"{titleName}{TitleNameSuffix}"
curChart.anchor = f'A{(1+i*ChartHeight)*ChartHeightToRowFactor}'
curChart.height = ChartHeight
curChart.width = ChartWidth
curChart.overlap = ChartPerBarInSeriesOverlap
# 一行對應(yīng)一組(Category)數(shù)據(jù)
curChart.add_data(values, from_rows=True)
curChart.set_categories(categories)
# series(各類柱子)的說明顯示在上下左右哪個(gè)位置
curChart.legend.position = SeriesTitlePos
# 設(shè)置各series說明的內(nèi)容和各series的顏色
for i in range(SeriesCnt):
curChart.series[i].title =SeriesLabel(v=SeriesTitles[i])
curChart.series[i].graphicalProperties.solidFill = SeriesColors[i]
# 每個(gè)柱子上方顯示且只顯示數(shù)值
curChart.dLbls=chart.label.DataLabelList()
curChart.dLbls.showSerName = False
curChart.dLbls.showCatName = False
curChart.dLbls.showLegendKey = False
curChart.dLbls.showVal = True
# 把畫好的柱形圖設(shè)置到sheet中
chartSheet.add_chart(curChart)
# 保存表格文件
workbook.save(filePath)
print('柱形圖生成完成!')