我用openpyxl库创建了一个简短的python脚本,以将一些数据添加到现有工作簿中,然后保存更改。现有的工作簿中包含许多图表,其中一些图表需要透明的图表区域背景,并且出于设计原因,所有这些图表的边框都已关闭。
当我打开编辑的文件时,所有关于边框和图表区域填充样式的图表样式都将重置为“自动”。有办法防止这种情况发生吗?还是一种在保存之前以编程方式访问工作簿对象中图表集合的方法,并以编程方式为每个图表设置这些属性?
答案 0 :(得分:2)
不幸的是,openpyxl
并没有编辑文件,而是再次读取并重新创建了整个xlsx
文件。如果比较这两个文件,将会发现巨大的差异
$ tree
.
├── [Content_Types].xml
├── _rels
├── docProps
│ ├── app.xml
│ └── core.xml
└── xl
├── _rels
│ └── workbook.xml.rels
├── charts
│ ├── _rels
│ │ └── chart1.xml.rels
│ ├── chart1.xml
│ ├── colors1.xml
│ └── style1.xml
├── drawings
│ ├── _rels
│ │ └── drawing1.xml.rels
│ └── drawing1.xml
├── sharedStrings.xml
├── styles.xml
├── theme
│ └── theme1.xml
├── workbook.xml
└── worksheets
├── _rels
│ └── sheet1.xml.rels
└── sheet1.xml
11 directories, 16 files
openpyxl
重写后,没有任何变化$ tree
.
├── [Content_Types].xml
├── _rels
├── docProps
│ ├── app.xml
│ └── core.xml
└── xl
├── _rels
│ └── workbook.xml.rels
├── charts
│ └── chart1.xml
├── drawings
│ ├── _rels
│ │ └── drawing1.xml.rels
│ └── drawing1.xml
├── styles.xml
├── theme
│ └── theme1.xml
├── workbook.xml
└── worksheets
├── _rels
│ └── sheet1.xml.rels
└── sheet1.xml
10 directories, 12 files
如您所见,colors1.xml
和style1.xml
不会持续存在。这是因为openpyxl
不是xlsx
格式的100%实现
因此,您的选择是使用COM对象(对于Windows)
Use openpyxl to edit a Excel2007 file (.xlsx) without changing its own styles?
答案 1 :(得分:1)
OpenPyxl将不起作用,因为它将在保存文件之前删除图表格式。不保留现有图表格式的原因与OpenPyxl的设计有关。 OpenPyxl类似于针对Linux和Mac OS的Excel的重复实现。它不仅仅是调用现有的COM和Excel-VBA功能。因此,在以后的更新中很难将Excel的广泛图表格式功能添加到该库中。
以下一些 Linux 库可能会有所帮助。
xlutils.copy https://xlutils.readthedocs.io/en/latest/copy.html
pyexcelerator (旧库)
https://sourceforge.net/projects/pyexcelerator/
请参见How to programmatically edit Excel sheets?
是的,pywin32需要Windows操作系统或Windows仿真。这是使用Excel文件的最佳方法,因为您可以完全访问所有Windows COM对象和所有Excel-VBA Worksheets对象(有时会稍作修改)。
也许您可以在Windows仿真中使用pywin32来分离出图表表对象,然后在Linux中使用openpyxl编辑工作表,然后最终使用pywin32重新组装工作簿?请参阅下面的示例pywin32代码。
import win32com.client as win32
excel = win32.gencache.EnsureDispatch('Excel.Application')
wb0 = excel.Workbooks.Open(r'C:\path\source.xlsx')
excel.Visible = True
# Move Chart 1 to a new Workbook, which becomes the ActiveWorkbook.
wb0.Charts('Chart1').Move()
excel.ActiveWorkbook.SaveAs(r'C:\path\chart1.xlsx')
excel.ActiveWorkbook.Close()
wb0.SaveAs(r'C:\path\no_charts.xlsx')
wb0.Close()
excel.Application.Quit()