python使用win32com模块向word中插入自带可编辑的图表

解决问题

使用python向word中插入office自带的可编辑的图表,查看python-docx v0.8.10文档还未实现该功能,考虑使用win32com。

前置知识

  • 了解word编程时的几个主要对象和类,包括
    Application对象:应用
    Document对象:文档
    Selection对象:选区
    更多类别查阅文档:https://docs.microsoft.com/zh-cn/dotnet/api/microsoft.office.interop.word?view=word-pia
  • 了解宏录制功能,通过查看宏编辑器里的VBA代码,了解操作使用了哪些对象和方法
  • 这些前置知识可以参考文章https://zhuanlan.zhihu.com/p/67543981,主要解决思路来源于此。

通过在word中录制宏可以了解大部分操作对象,本人使用office365版本的word程序不能录制生成图表和编辑图表的操作。

具体思路

win32模块安装:
pip install pypiwin32

考虑了两种实现思路:

思路一:从Excel应用中将图表copy至word

Excel本身对图表创建和操作相对更方便,且在Ecxel中可以录制创建、编辑等对图表的操作,方便查看使用的对象和方法。
该方法需要分别打开一个Word应用和Excel应用。

步骤

数据准备:

  1. Excel文件中保存生成图表的测试数据。
  2. 在word文档中插入书签,此处方便选择图表插入位置。也可调用Selection对象设置插入位置,具体可参考官方文档说明
    python使用win32com模块向word中插入自带可编辑的图表

具体代码如下:

import win32com
from win32com.client import Dispatch

docApp = win32com.client.Dispatch('Word.Application')
excelAPP = win32com.client.Dispatch('Excel.Application')
docApp.Visible = True
docApp.DisplayAlerts = 0
excelAPP.Visible = True
excelAPP.DisplayAlerts = 0

doc = docApp.Documents.Open('test.docx')
excel = excelAPP.Workbooks.Open('test.xlsx')

# 设置生成图表类型及数据范围
# AddChart2方法说明详见思路二
excel_chart = excel.ActiveSheet.Shapes.AddChart2(201, 51)
excel_chart.Chart.SetSourceData(Source=excel.ActiveSheet.Range("A1:D4"))

# 设置图表样式,此处仅为简单示例,具体需求可通过录制宏参考调用的对象及其属性
excel_chart.Chart.ChartTitle.Text = '测试标题'
excel_chart.Chart.FullSeriesCollection(3).Format.Fill.ForeColor.ObjectThemeColor = 10

# 将excel中的图表复制粘贴到word中
excel_chart.Copy()
doc.Bookmarks("插入图表位置").Select()
# docApp.Selection.Paste() # 直接粘贴,一般默认为使用目标主题和链接数据
docApp.Selection.PasteAndFormat(16) # 保留所粘贴材料的原始格式

doc.Save()
doc.Close()
excel.Save()
excel.Close()
docApp.Quit()
excelAPP.Quit()

思路二:直接在word中插入图表

不需要打开Excel应用,直接在Word中调用图表对象。

步骤

数据准备:

  • 在word文档中插入书签,此处方便选择图表插入位置。也可调用Selection对象设置插入位置,具体可参考官方文档说明

具体代码如下:

import win32com
from win32com.client import Dispatch

docApp = win32com.client.Dispatch('Word.Application')
docApp.Visible = True
docApp.DisplayAlerts = 0
doc = docApp.Documents.Open('test.docx')

# 创建图表,图表的插入位置为预先在word文档中插入的书签,书签名为“插入图表位置”
shape_chart = doc.Shapes.AddChart2(Style=201, Type=51, Top=doc.Bookmarks("插入图表位置").Select())
shape_chart.WrapFormat.Type = 7  # 设置图表为嵌入型

# 设置Word中的图表
chart = shape_chart.Chart
worksheet = chart.ChartData.Workbook.Worksheets(1) #图表数据对应的工作表
chart.SetSourceData("Sheet1!$A$1:$C$4") # 设置数据源范围

# 簇状柱形图测试数据
chart_data = [["","系列A","系列B","系列C","系列D"],
              [2020,2,4,2,3],
              [2019,4,5,3,2]]

# 清空工作表默认数据              
worksheet.Range("A1:D5").value = None

# 填入测试数据
for row_index,row in enumerate(chart_data):
    for column_index,value in enumerate(row):
        worksheet.Cells(row_index+1,column_index+1).Value = value

chart.SetSourceData("Sheet1!$A$1:$E$3") # 设置数据源范围

# 设置图表样式示例
chart.ChartTitle.Text = '测试标题' # 设置标题
chart.FullSeriesCollection(2).Format.Fill.ForeColor.ObjectThemeColor = 10  #设置系列2的填充颜色
 
chart.ChartData.Workbook.Close() # 关闭workbook窗口

doc.Save()
doc.Close()
docApp.Quit()

使用AddChart2方法时,word文档中已插入默认图表,如图所示。
其中,添加图表的方法AddChart2参数考链接,图表类型对应的代码参考链接(或直接参考文末“附录-图表对应代码”)。
python使用win32com模块向word中插入自带可编辑的图表

插入图表效果如下:
python使用win32com模块向word中插入自带可编辑的图表

讨论

  • 首先尝试思路一是发现在Word中没法录制编辑图表的宏借以参考,而在Excel中可录制,因此采用复制图表的方式。
  • 实践发现,思路二也可以通过在Excel中录制宏了解图表对应的对象,Word官方文档中对chart对象的相关属性、方法描述相对简单(很多详细设置没有说明),参考Excel文档中的说明即可。
  • 目前在本地测试发现某些对象不能正常调用,如调整坐标轴的字体格式,调用Chart.Axes(Type=2).Format.TextFrame2TextFrame2时报错,暂未找到解决方案,由此推测还可能存在其它坑。
  • 很多方法的参数(如doc.Shapes.AddChart2(Style=201))或对象的属性值(如图表系列的填充颜色)既可以使用相应数值,也可以使用类型常量。示例代码中全都使用了数字代码,是由于使用常量报错的问题尚未解决。
  • 本博客主要分享解决的思路,代码在本地环境均可运行,不足之处欢迎交流~

附录

图表类型对应代码

XlChartType 代码 说明
xl3DArea -4098 三维面积图
xl3DAreaStacked 78 三维堆积面积图
xl3DAreaStacked100 79 100%堆叠区域
xl3DBarClustered 60 三维簇状条形图
xl3DBarStacked 61 三维堆积条形图
xl3DBarStacked100 62 三维百分比堆积条形图
xl3DColumn -4100 三维柱形图
xl3DColumnClustered 54 三维簇状的柱形图
xl3DColumnStacked 55 三维堆积柱形图
xl3DColumnStacked100 56 三维百分比堆积条形图
xl3DLine -4101 三维折线图
xl3DPie -4102 三维饼图
xl3DPieExploded 70 分离型三维饼图
xlArea 1 区域
xlAreaStacked 76 堆积的面积图
xlAreaStacked100 77 100%堆叠区域
xlBarClustered 57 簇状条形图
xlBarOfPie 71 复合条饼图
xlBarStacked 58 堆积条形的图
xlBarStacked100 59 百分比堆积条形图
xlBubble 15 气泡图
xlBubble3DEffect 87 三维气泡图
xlColumnClustered 51 三维簇状的柱形图
xlColumnStacked 52 堆积的柱形图
xlColumnStacked100 53 百分比堆积柱形
xlCombo -4152
xlComboAreaStackedColumnClustered 115
xlComboColumnClusteredLine 113
xlComboColumnClusteredLineSecondaryAxis 114
xlConeBarClustered 102 簇状条形圆锥图
xlConeBarStacked 103 堆积条形的圆锥图
xlConeBarStacked100 104 百分比堆积条形圆锥图
xlConeCol 105 三维柱形圆锥图
xlConeColClustered 99 柱形簇状圆锥图
xlConeColStacked 100 堆积的柱形圆锥图
xlConeColStacked100 101 百分比堆积柱形圆锥图
xlCylinderBarClustered 95 簇状条形圆柱图
xlCylinderBarStacked 96 堆积条形的圆柱图
xlCylinderBarStacked100 97 百分比堆积条形圆柱图
xlCylinderCol 98 三维柱形圆柱图
xlCylinderColClustered 92 柱形簇状圆锥图
xlCylinderColStacked 93 堆积条形的圆柱图
xlCylinderColStacked100 94 百分比堆积柱形圆柱图
xlDoughnut -4120 圆环图
xlDoughnutExploded 80 分离型圆环图
xlLine 4 Line
xlLineMarkers 65 折线图
xlLineMarkersStacked 66 堆积的折线图
xlLineMarkersStacked100 67 百分比堆积折线图
xlLineStacked 63 堆积的折线图
xlLineStacked100 64 百分比堆积折线图
xlOtherCombinations 116
xlPie 5 饼图
xlPieExploded 69 分离型的饼图
xlPieOfPie 68 复合饼图
xlPyramidBarClustered 109 簇状条形棱锥图
xlPyramidBarStacked 110 堆积条形的棱锥图
xlPyramidBarStacked100 111 百分比堆积条形棱锥图
xlPyramidCol 112 三维柱形棱锥图
xlPyramidColClustered 106 柱形簇状棱锥图
xlPyramidColStacked 107 堆积的柱形棱锥图
xlPyramidColStacked100 108 百分比堆积柱形棱锥图
xlRadar -4151 雷达图
xlRadarFilled 82 填充的雷达图
xlRadarMarkers 81 数据点雷达图
xlStockHLC 88 盘高-盘低-关闭
xlStockOHLC 89 打开高低关闭
xlStockVHLC 90 卷高低关闭
xlStockVOHLC 91 卷-打开-高-低-关闭
xlSuggestedChart -2
xlSurface 83 三维曲面图
xlSurfaceTopView 85 曲面图(俯视图)
xlSurfaceTopViewWireframe 86 曲面图(俯视线框)
xlSurfaceWireframe 84 三维曲面图(线框)
xlXYScatter -4169 散点图
xlXYScatterLines 74 折线散点图
xlXYScatterLinesNoMarkers 75 无数据点折线散点图
xlXYScatterSmooth 72 平滑线散点图
xlXYScatterSmoothNoMarkers 73 无数据点平滑的线与散点图
上一篇:echart 在vue中,首次加载之后,resize事件未生效


下一篇:k8s核心技术-Helm(chart模板的使用下)---K8S_Google工作笔记0049