创建图表

Excel对象模型中,用Chart对象表示图表,该对象可以作为图表工作表保存在Charts集合中,也可以作为一种图形类型保存在Shapes集合中。VBA中还可以将Chart对象作为嵌入式图表保存在ChartObjects集合中。通过编程创建图表的过程,就是创建Chart对象并利用它本身及与之相关的一系列对象的属性和方法进行编程的过程。[大谦Excel,dqexcel点com]

6.1.1创建图表工作表中的图表

图表工作表中,图表占据整个工作表。使用Excel VBA和Python xlwings的API使用方式可以创建图表并显示在图表工作表中。

【Excel VBA】

用Charts对象的Add方法创建创建图表并显示在一个新的图表工作表中。该方法的语法格式为:

code.vba
Set cht=wb.Charts.Add(Before,After,Count,Type)

其中,wb表示指定的工作簿对象。该方法的参数都可省略,各参数的含义如下:

• Before - 指定工作表对象,新建的工作表将置于此工作表之前。

• After - 指定工作表对象,新建的工作表将置于此工作表之后。

• Count - 要添加的工作表个数。默认值为1。

• Type - 指定要添加的图表类型。

注意:如果Before和After两者都省略,新建的图表工作表将插入到活动工作表之前。

该方法返回一个Chart对象。

下面利用图6-1所示部分省份2011-2016年的GDP数据创建图表并显示在图表工作表中。

Document Image

图6-1 部分省份2011-1016年GDP数据

示例文件的存放路径为Samples\ch18\Excel VBA\创建图表工作表中的图表.xlsm。

code.vba
Sub CreatCharts()
  Dim cht As Chart
  Set cht = Charts.Add   '创建图表工作表中的图表
  With cht   '设置图表属性
    '绑定数据
    .SetSourceData Source:=Sheets("Sheet1").Range("A1:H7"), PlotBy:=xlRows
    .ChartType = xlColumnClustered   '图表类型
    .HasTitle = True   '有标题
    .ChartTitle.Text = "部分省市2011-2016年GDP数据"   '标题文本
  End With
End Sub

运行过程,生成图表工作表如图6-2所示。

Document Image

图6-2 创建图表工作表

【Python xlwings API】

在xlwings API方式下创建图表,创建的是图表工作表中的图表,即创建的图表占据整个工作表。通过Charts集合的Add方法可向集合中添加新的图表工作表,Add方法的语法格式为:

code.vba
wb.api.Charts.Add(Before,After,Count,Type)

其中,wb表示指定的工作簿对象。该方法的参数都可省略,各参数的含义如下:

• Before - 指定工作表对象,新建的工作表将置于此工作表之前。

• After - 指定工作表对象,新建的工作表将置于此工作表之后。

• Count - 要添加的工作表个数。默认值为1。

• Type - 指定要添加的图表类型。

注意:如果Before和After两者都省略,新建的图表工作表将插入到活动工作表之前。

该方法返回一个Chart对象。

下面使用图6-1中相同的数据,用API方式创建复合柱状图。编写Python脚本,脚本文件的存放路径为Samples\ch18\Python\创建图表-xlwings API.py。

code.python
import xlwings as xw  #导入xlwings
import os  #导入os
root = os.getcwd()  #获取当前路径
app = xw.App(visible=True, add_book=False)  #创建Excel应用,不添加工作簿
#打开与本文件相同路径下的数据文件,可写
wb=app.books.open(root+r"/GDP数据.xlsx",read_only=False)
sht=wb.sheets(1)  #获取工作表对象
sht.api.Range("A1:H7").Select()  #选择图表数据
cht=wb.api.Charts.Add()  #添加图表
cht.ChartType= xw.constants.ChartType.xlColumnClustered  #图表类型
cht.HasTitle=True  #有标题
cht.ChartTitle.Text = "部分省市2011-2016年GDP数据"  #标题文本

运行脚本,生成图6-2所示的图表工作表。

代码中,绑定数据的方式使用的是用Select方法选择数据区域,然后用Charts对象的Add方法创建图表工作表。Add方法返回一个Chart对象,用Chart对象的ChartType属性设置图表类型为复合柱状图。注意指定图表类型常数的方式。最后指定图表的标题。

创建嵌入式图表

嵌入式图表可以嵌入普通工作表,与绘图数据和其他图形图表共存。使用Excel VBA中的ChartObjects对象和Python xlwings可以创建嵌入式图表。

【Excel VBA】

利用工作表对象的ChartObjects集合的Add方法可以创建嵌入式图表。该方法的语法格式为:

code.vba
Set chtObj=sht.ChartObjects.Add(Left, Top, Width, Height)

其中,sht表示工作表对象,有4个参数Left, Top, Width和Height分别表示图表的左侧位置、顶部位置、宽度和高度。Left和Width为必需参数。

该方法返回一个ChartObject对象,可以利用该对象的Chart属性对图表进行更多设置。

下面用图6-1中所示的数据创建嵌入式图表。在绘图数据所在的工作表中创建图表。示例文件的存放路径为Samples\ch18\Excel VBA\创建嵌入式图表.xlsm。

code.vba
Sub CreateCharts()
  Dim cht As ChartObject
  '生成ChartObject对象,指定位置和大小
  Set cht = ActiveSheet.ChartObjects.Add(50, 200, 355, 211)
  With cht
    With .Chart   'Chart属性返回Chart对象,用它设置图表属性
      '绑定数据
      .SetSourceData Source:=Sheets("Sheet1").Range("A1:H7"), PlotBy:=xlRows
      .ChartType = xlColumnClustered   '图表类型
      .SetElement msoElementChartTitleCenteredOverlay   '标题居中显示
      .ChartTitle.Text = "部分省市2011-2016年GDP数据"   '标题文本
    End With
  End With
End Sub

运行过程,生成嵌入式图表如图6-3所示。可以用鼠标拖动该图表。

Document Image

图6-3 创建嵌入式图表

【Python xlwings】

利用xlwings包提供的charts对象的add方法可以创建图表。该方法的语法格式为:

code.vba
sht.charts.add(left=0, top=0, width=355, height=211)

其中,sht表示工作表对象,有4个参数:

• left – 表示图表左侧的位置,单位为点,默认值为0。

• top - 表示图表顶端的位置,单位为点,默认值为0。

• width - 表示图表的宽度,单位为点,默认值为355。

• height – 表示图表的高度,单位位点,默认值为211。

该方法返回一个chart对象。

利用图6-1中的数据绘制复合条形柱状图。编写Python脚本,脚本文件的存放路径为Samples\ch18\Python\创建图表-xlwings.py。

code.python
#前面代码省略,请参见Python文件
#......
cht=sht.charts.add(50, 200)  #添加图表
cht.set_source_data(sht.range("A1").expand())  #图表绑定数据
cht.chart_type="column_clustered"  #图表类型
cht.api[1].HasTitle=True  #图表有标题
cht.api[1].ChartTitle.Text="部分省市2011-2016年GDP数据"  #标题文本

运行脚本,生成图表如图6-3中所示。上面代码中,使用charts对象的add方法返回一个表示空白图表的chart对象,图表左上角的位置为(50,200)。用chart对象的set_source_data方法绑定绘图数据。参数中用range对象的expand方法获取单元格A1所在的数据表。用chart_type属性指定图表类型为复合柱状图。最后用API方式指定图表的标题,注意需要设置HasTitle属性的值为True。

代码最后两行为什么要在api后面添加一个索引呢?将脚本各行语句在Python Shell窗口输入运行时,会发现cht.api是一个有两个元素的元组,如下所示:

code.python
>>> cht.api
(<win32com.gen_py.Microsoft Excel 4.0 Object Library.ChartObject instance at 0x101988744>, <win32com.gen_py.None.Chart>)

所以需要通过索引获取对象以后才能引用它的属性进行设置。另外,元组中提供的信息也说明xlwings对win32com进行二次封装时是将Excel类库中的ChartObject对象,即嵌入式图表对象封装为新的chart对象。

用Shapes对象创建图表

使用Excel对象模型中Shapes对象的Add方法也可以创建图表。该方法创建的是一个表示图表的Shape对象,引用它的Chart属性返回一个Chart对象,即图表对象。

【Excel VBA】

使用Shapes对象的AddChart2方法创建图表。该方法的语法格式为:

code.vba
sht.Shapes.AddChart2(Style,XlChartType,Left,Top,Width,Height,NewLayout)

其中,sht为指定工作表。一共有7个参数,均可选。

• Style:图表样式,值为-1时表示各图形类型的默认样式。

• xlChartType:图表类型,值为XlChartType枚举类型,表6- 中列出了一部分。

• Left:图表左侧位置,省略时水平居中。

• Top:图表顶端位置,省略时垂直居中。

• Width:图表的宽度,省略时取默认值354。

• Height:图表的高度,省略时取默认值210。

• NewLayout:表示图表布局,如果值为True,则只有复合图形才会显示图例。

该方法返回一个表示图表的Shape对象。

下面用图6-1中所示的数据创建嵌入式图表。在绘图数据所在的工作表中创建图表。示例文件的存放路径为Samples\ch18\Excel VBA\创建图表-用Shapes对象.xlsm。

code.vba
Sub CreateCharts()
  '用Shapes创建图表
  ActiveSheet.Range("A1").CurrentRegion.Select  '绑定数据
  ActiveSheet.Shapes.AddChart2 -1, xlColumnClustered, _
                          30, 150, 300, 200, True
End Sub

运行过程,生成图6-4所示的图表。

Document Image

图6-4 利用给定数据绘复合柱状图

【Python xlwings API】

在Python中用Shapes对象创建图表,在xlwings的API使用方式下实现。在API使用方式下,使用Shapes对象的AddChart2方法创建图表。该方法的语法格式为:

code.vba
sht.Shapes.AddChart2(Style,XlChartType,Left,Top,Width,Height,NewLayout)

其中,各变量和参数的意义与VBA环境下的相同。该方法返回一个表示图表的Shape对象。

利用图6-1中的数据绘制复合条形柱状图。首先选择数据区域,然后用Shapes对象的AddChart2方法绘制。编写Python脚本,脚本文件的存放路径为Samples\ch18\Python\创建图表-Shapes对象.py。

code.vba
#前面代码省略,请参见Python文件
#......
sht.api.Range("A1").CurrentRegion.Select()  #绑定数据
sht.api.Shapes.AddChart2(-1,xw.constants.ChartType.xlColumnClustered,\
30,150,300,200,True)

生成图6-4所示的图表。

绑定数据

如6.1.1-6.1.3所述,可用两种方法绑定数据。

第一种方法是使用单元格区域的Select方法选择数据。

对于工作表sht,使用类似下面的形式编写代码:

【Excel VBA】

code.python
>>> sht.Range("A1").CurrentRegion.Select

code.python
>>> sht.Range("A1:H7").Select

【Python xlwings API】

code.python
>>> sht.api.Range("A1").CurrentRegion.Select()

code.python
>>> sht.api.Range("A1:H7").Select()

另一种方法是使用chart(Chart)对象的set_source_data(SetSourceData)方法绑定数据。

【Excel VBA】

通过Chart对象的SetSourceData方法,可为指定图表设置源数据区域。其语法格式如下:

code.vba
cht.SetSourceData(Source, PlotBy)

其中,cht为Chart对象,有两个参数,含义如下:

• Source - 为一个Range对象,用来指定图表的源数据区域。

• PlotBy - 指定取数据的方式。值为1时表示按列取数据,值为2时表示按行取数据。

对于工作表sht和图表cht,使用类似下面的形式编写代码:

code.vba
cht.SetSourceData(Source:=Range("A1:H7"), PlotBy:=1)

【Python xlwings】

在xlwings使用方式下,使用chart对象的set_source_data方法绑定数据。例如,对于工作表sht和图表cht,使用类似下面的形式编写代码:

code.python
>>> cht.set_source_data(sht.range("A1").expand())

该方法只有一个参数,为一range对象,指定数据的范围。[大谦Excel,dqexcel点com]

【Python xlwings API】

对于工作表sht和图表cht,使用类似下面的形式编写代码:

code.python
>>> cht.SetSourceData(Source=sht.api.Range("A1:H7"), PlotBy=1)