Python 使用熊猫修改Excel文件,对布局的更改最小
我已经读过了,但这里我的问题是针对后面提到的布局的 如何使用Pandas打开Excel文件、进行一些修改并将其保存回:Python 使用熊猫修改Excel文件,对布局的更改最小,python,excel,pandas,openpyxl,xlsxwriter,Python,Excel,Pandas,Openpyxl,Xlsxwriter,我已经读过了,但这里我的问题是针对后面提到的布局的 如何使用Pandas打开Excel文件、进行一些修改并将其保存回: # [step 0] boiler plate stuff df = pd.DataFrame( index=pd.date_range("2020-01-01 11:11:11", periods=100, freq="min"), columns=list('abc')) df['a'] = np.random.ra
# [step 0] boiler plate stuff
df = pd.DataFrame(
index=pd.date_range("2020-01-01 11:11:11", periods=100, freq="min"),
columns=list('abc'))
df['a'] = np.random.randn(100, 1)
df['b'] = df['a'] * 2 + 10
# [step 1] google xlwings, and pip/conda install xlwings
# [step 2] open a new excel sheet, no need to save
# (basically this code will indiscriminally wipe whatever sheet that is active on your desktop)
# [step 3] magic, ...and things you can do
import xlwings as xw
wb = xw.books.active
ws = wb.sheets.active
ws.range('A1').current_region.options(index=1).value = df
# I believe this preserves existing formatting, HOWEVER, it will destory filtering
if 1:
# show casing some formatting you can do
active_window = wb.app.api.ActiveWindow
active_window.FreezePanes = False
active_window.SplitColumn = 2 # const_splitcolumn
active_window.SplitRow = 1
active_window.FreezePanes = True
ws.cells.api.Font.Name = 'consolas'
ws.api.Rows(1).Orientation = 60
ws.api.Columns(1).Font.Bold = True
ws.api.Columns(1).Font.ColorIndex = 26
ws.api.Rows(1).Font.Bold = True
ws.api.Rows(1).Borders.Weight = 4
ws.autofit('c') # 'c' means columns, autofitting columns
ws.range(1,1).api.AutoFilter(1)
- (1) 在不删除的情况下,第一行上有一个
过滤器
- (2) 不修改Excel中显示的列的“显示列宽”
- (3) 不删除某些单元格上可能存在的公式
使用此代码,删除第一行的
过滤器
,并将显示的列宽设置为默认值,这不是很方便(因为我们必须手动为所有列设置正确的宽度)。我认为这不是panda字段,您必须使用它来处理所有格式化、阻塞的行,名称范围等等。主要区别在于不能像pandas那样使用矢量计算,因此需要引入一些循环。我建议使用xlwings
,因为它与excel的COM接口(如内置vba)相连接,所以功能更强大。我从未测试过“过滤或公式保存”,官方文件可能会提供方法
对于我自己的使用,我只是将所有东西都构建到python、过滤、公式中,所以我甚至不去碰excel工作表
演示:
# [step 0] boiler plate stuff
df = pd.DataFrame(
index=pd.date_range("2020-01-01 11:11:11", periods=100, freq="min"),
columns=list('abc'))
df['a'] = np.random.randn(100, 1)
df['b'] = df['a'] * 2 + 10
# [step 1] google xlwings, and pip/conda install xlwings
# [step 2] open a new excel sheet, no need to save
# (basically this code will indiscriminally wipe whatever sheet that is active on your desktop)
# [step 3] magic, ...and things you can do
import xlwings as xw
wb = xw.books.active
ws = wb.sheets.active
ws.range('A1').current_region.options(index=1).value = df
# I believe this preserves existing formatting, HOWEVER, it will destory filtering
if 1:
# show casing some formatting you can do
active_window = wb.app.api.ActiveWindow
active_window.FreezePanes = False
active_window.SplitColumn = 2 # const_splitcolumn
active_window.SplitRow = 1
active_window.FreezePanes = True
ws.cells.api.Font.Name = 'consolas'
ws.api.Rows(1).Orientation = 60
ws.api.Columns(1).Font.Bold = True
ws.api.Columns(1).Font.ColorIndex = 26
ws.api.Rows(1).Font.Bold = True
ws.api.Rows(1).Borders.Weight = 4
ws.autofit('c') # 'c' means columns, autofitting columns
ws.range(1,1).api.AutoFilter(1)
这是(1)、(2)的解决方案,而不是我原来问题的(3)。(如果你对(3)有想法,欢迎发表评论和/或另一个答案)
在此解决方案中,我们将打开输入Excel文件两次:
- 一旦使用
:这有助于保持原始布局(当作为openpyxl
dataframe读取时,它似乎完全被丢弃!)pandas
- 曾经作为
dataframepandas
从df
中获益,这是一个操作/修改数据本身的伟大API。注意:pandas
的数据修改比pandas
更方便,因为我们有矢量化、过滤openpyxl
、通过名称直接访问列df[df['foo']=='bar']
df['foo']
import pandas as pd
from openpyxl.utils.dataframe import dataframe_to_rows
from openpyxl import load_workbook
wb = load_workbook('test.xlsx') # load as openpyxl workbook; useful to keep the original layout
# which is discarded in the following dataframe
df = pd.read_excel('test.xlsx') # load as dataframe (modifications will be easier with pandas API!)
ws = wb.active
df.iloc[1, 1] = 'hello world' # modify a few things
rows = dataframe_to_rows(df, index=False)
for r_idx, row in enumerate(rows, 1):
for c_idx, value in enumerate(row, 1):
ws.cell(row=r_idx, column=c_idx, value=value)
wb.save('test2.xlsx')
如果您使用的机器上安装了Excel,那么我强烈建议您使用灵活的API。这回答了你所有的问题 假设我的程序所在的目录中有一个名为
demo.xlxs
的Excel文件
app.py
这将创建一个初始化xl工作簿实例并打开Excel编辑器,以允许您调用Python命令
假设我们有以下数据框,我们想用它来替换ID和Name列:
new_name
A John_new
B Adams_new
C Mo_new
D Safia_new
wb.sheets['Sheet1']['A1:B1'].value = df
最后,您可以保存并关闭
wb.save()
wb.close()
这就是我注意到的:使用pandas,我们完全失去了输入XLSX的布局,但是我们有一个很好的API来修改数据。使用openpyxl,我们保留了布局,但是如果没有矢量化,数据修改API就不那么方便了。如果有可能把它们混合在一起,使两者都达到最佳效果,那就太好了。。。使用openpyxl,它可以解决(1)、(2),但不能解决(3)。您是否知道如何修改它,使其同时具有我最初问题中的标准(3)?您能否同时提及您当前的操作系统/环境?@Manakin我正在使用Windows+Python 3.7此解决方案有助于解决问题(3)@Robin您是否可以发布一个答案,显示使用您提到的解决方案(使用pandas+openpyxl)的代码示例?只有openpyxl,这很容易;但是这里的困难是使用pandas+openpyxl。
wb.save()
wb.close()