使用 openpyxl 操作现有 excel table
Manipulate existing excel table using openpyxl
我目前正在磨练我的 python/excel 技能,运行 遇到了 openpyxl
的问题。
我正在尝试打开工作簿,替换现有 table 中的行,然后再次保存工作簿。
理想情况下,我还希望首先能够从 table 中删除所有行(尽管保留 table 结构)。
我的初始工作簿包含一个名为“inputData”的sheet。在此我有一个名为“数据”的 table,其中包含列 A
、B
、C
和 2 行数据。
我还有一个名为“input.csv”的 csv 文件,其中包含相同的列但有 4 行数据。
当我运行我的代码时,数据被写入工作sheet,但是table结构没有扩展以包含两行新数据。
关于如何使用 openpyxl 更改命名 table 结构的数据源的任何想法?
import csv
from openpyxl import load_workbook
from openpyxl.worksheet.table import Table, TableStyleInfo
wb = load_workbook(filename = 'workbook.xlsx')
ws = wb["inputData"]
with open('input.csv', newline='', encoding='utf-8-sig') as f:
reader = csv.reader(f, delimiter=';')
for i, row in enumerate(reader):
if not i == 0:
for j, cell in enumerate(row):
ws.cell(row=i+1, column=j+1).value = cell
wb.save('output.xlsx')
我找到了问题的答案。
我可以从 openpyxl 访问 table,更改 ref(范围)然后再次保存。
这使我能够在同一个 table 中输入更多数据,并在我的其他工作中使用我的公式sheet 将新数据考虑在内。
这将是一个非常有用的功能,当我需要将大量数据推送到现有 excel sheet 而不破坏引用时。
import csv
from openpyxl import load_workbook
from openpyxl.worksheet.table import Table, TableStyleInfo
tableName = 'Data'
style = TableStyleInfo(name="TableStyleMedium9", showFirstColumn=False,
showLastColumn=False, showRowStripes=True, showColumnStripes=False)
def colnum_string(n):
string = ""
while n > 0:
n, remainder = divmod(n - 1, 26)
string = chr(65 + remainder) + string
return string
wb = load_workbook(filename = 'workbook.xlsx')
ws = wb["inputData"]
with open('input.csv', newline='', encoding='utf-8-sig') as f:
reader = csv.reader(f, delimiter=';')
for i, row in enumerate(reader):
for j, cell in enumerate(row):
if not i == 0:
ws.cell(row=i+1, column=j+1).value = float(cell)
else:
ws.cell(row=i+1, column=j+1).value = cell
maxRef = [i,j]
for i, table in enumerate(ws._tables):
if table.name == tableName:
tableRef = i
resTable = Table(displayName="Data", ref="A1:{}{}".format(colnum_string(maxRef[0]), maxRef[1]))
resTable.tableStyleInfo = style
ws._tables[tableRef] = resTable
wb.save('output.xlsx')
首先感谢您的关注。我尝试在现有 excel 文件(模板副本)中扩展现有 table。我只是未能将 table 扩展到我实际放入数据的范围(备注:某些 table 元素包含我需要保留的公式)
我所做的是,打开 excel 文件,将数据复制并粘贴到正确的工作表和正确的单元格中。这按预期工作。不起作用的是扩展 table 的范围,它最初仅覆盖第一行(header 除外)。
使用上面的代码,我能够识别 table 并且我尝试复制样式:
for i, table in enumerate(ws._tables):
if table.name == 'Template':
tableRef = i
mystyle = table.tableStyleInfo
resTable = Table(displayName="Template", ref="A7:{}{}".format(colnum_string(maxRef[1]), maxRef[0]))
resTable.tableStyleInfo = mystyle
ws._tables[tableRef] = resTable
我可能会忽略这里的某些内容,因为它不起作用。 table 不扩展。非常感谢任何帮助。
为了更好的理解问题:
Table header 是 A7:BA7
第一(空)行,一些带有公式和格式的元素:A8:BA8
复制数据后的最终数据范围(作为例子,计算正确):A8:BA255
2020 年用 openpyxl==3.0.5 偶然发现了这个问题
希望也可以将我的解决方案分享给可能处于相同情况的其他人。
目标:从 data.csv 读取新数据并添加到现有 file.xlsx,因此公式仍然有效。列名保持不变。
输入:
- XLSX 模板文件,一个 sheet 上有公式,另一个 sheet 上有数据 (file.xlsx)
- data.csv 有新数据
输出:包含新数据的 XLSX 文件和更新的 table 公式中使用的范围
"""python imports"""
import openpyxl
import pandas
"""Load input workbook"""
wb = openpyxl.load_workbook(filename='file.xlsx')
"""Activate worksheet named 'data'."""
ws = wb['data']
"""Read in new data from data1.csv to pandas.dataframe"""
new_dataframe = pandas.read_csv("data1.csv")
"""Iterate over dataframe rows and write values to worksheet"""
for i, row in new_dataframe.iterrows():
# ws.append leaves first line empty
# to get data written from first row, need to use writing to cell
if i == 0:
for c, value in enumerate(row, start=1):
ws.cell(row=2, column=c).value = value
else:
current_row = [row.col1, row.col2, row.col3]
ws.append(current_row)
"""Change table range"""
ws.tables['MyTable'].ref = "A1:E5"
"""Save workbook"""
wb.save(filename='file.xlsx')
Ethan 问题的答案:如何改变范围:
# Find right table
my_table = ws.tables['Template']
# Change range
my_table.ref = ref="A7:{}{}".format(column_string(maxRef[1], maxRef[0]))
# change style
my_table.tableStyleInfo = my_style
wb.save('WorkbookName')
我目前正在磨练我的 python/excel 技能,运行 遇到了 openpyxl
的问题。
我正在尝试打开工作簿,替换现有 table 中的行,然后再次保存工作簿。
理想情况下,我还希望首先能够从 table 中删除所有行(尽管保留 table 结构)。
我的初始工作簿包含一个名为“inputData”的sheet。在此我有一个名为“数据”的 table,其中包含列 A
、B
、C
和 2 行数据。
我还有一个名为“input.csv”的 csv 文件,其中包含相同的列但有 4 行数据。
当我运行我的代码时,数据被写入工作sheet,但是table结构没有扩展以包含两行新数据。
关于如何使用 openpyxl 更改命名 table 结构的数据源的任何想法?
import csv
from openpyxl import load_workbook
from openpyxl.worksheet.table import Table, TableStyleInfo
wb = load_workbook(filename = 'workbook.xlsx')
ws = wb["inputData"]
with open('input.csv', newline='', encoding='utf-8-sig') as f:
reader = csv.reader(f, delimiter=';')
for i, row in enumerate(reader):
if not i == 0:
for j, cell in enumerate(row):
ws.cell(row=i+1, column=j+1).value = cell
wb.save('output.xlsx')
我找到了问题的答案。
我可以从 openpyxl 访问 table,更改 ref(范围)然后再次保存。
这使我能够在同一个 table 中输入更多数据,并在我的其他工作中使用我的公式sheet 将新数据考虑在内。
这将是一个非常有用的功能,当我需要将大量数据推送到现有 excel sheet 而不破坏引用时。
import csv
from openpyxl import load_workbook
from openpyxl.worksheet.table import Table, TableStyleInfo
tableName = 'Data'
style = TableStyleInfo(name="TableStyleMedium9", showFirstColumn=False,
showLastColumn=False, showRowStripes=True, showColumnStripes=False)
def colnum_string(n):
string = ""
while n > 0:
n, remainder = divmod(n - 1, 26)
string = chr(65 + remainder) + string
return string
wb = load_workbook(filename = 'workbook.xlsx')
ws = wb["inputData"]
with open('input.csv', newline='', encoding='utf-8-sig') as f:
reader = csv.reader(f, delimiter=';')
for i, row in enumerate(reader):
for j, cell in enumerate(row):
if not i == 0:
ws.cell(row=i+1, column=j+1).value = float(cell)
else:
ws.cell(row=i+1, column=j+1).value = cell
maxRef = [i,j]
for i, table in enumerate(ws._tables):
if table.name == tableName:
tableRef = i
resTable = Table(displayName="Data", ref="A1:{}{}".format(colnum_string(maxRef[0]), maxRef[1]))
resTable.tableStyleInfo = style
ws._tables[tableRef] = resTable
wb.save('output.xlsx')
首先感谢您的关注。我尝试在现有 excel 文件(模板副本)中扩展现有 table。我只是未能将 table 扩展到我实际放入数据的范围(备注:某些 table 元素包含我需要保留的公式)
我所做的是,打开 excel 文件,将数据复制并粘贴到正确的工作表和正确的单元格中。这按预期工作。不起作用的是扩展 table 的范围,它最初仅覆盖第一行(header 除外)。
使用上面的代码,我能够识别 table 并且我尝试复制样式:
for i, table in enumerate(ws._tables):
if table.name == 'Template':
tableRef = i
mystyle = table.tableStyleInfo
resTable = Table(displayName="Template", ref="A7:{}{}".format(colnum_string(maxRef[1]), maxRef[0]))
resTable.tableStyleInfo = mystyle
ws._tables[tableRef] = resTable
我可能会忽略这里的某些内容,因为它不起作用。 table 不扩展。非常感谢任何帮助。
为了更好的理解问题:
Table header 是 A7:BA7
第一(空)行,一些带有公式和格式的元素:A8:BA8
复制数据后的最终数据范围(作为例子,计算正确):A8:BA255
2020 年用 openpyxl==3.0.5 偶然发现了这个问题 希望也可以将我的解决方案分享给可能处于相同情况的其他人。
目标:从 data.csv 读取新数据并添加到现有 file.xlsx,因此公式仍然有效。列名保持不变。
输入:
- XLSX 模板文件,一个 sheet 上有公式,另一个 sheet 上有数据 (file.xlsx)
- data.csv 有新数据
输出:包含新数据的 XLSX 文件和更新的 table 公式中使用的范围
"""python imports"""
import openpyxl
import pandas
"""Load input workbook"""
wb = openpyxl.load_workbook(filename='file.xlsx')
"""Activate worksheet named 'data'."""
ws = wb['data']
"""Read in new data from data1.csv to pandas.dataframe"""
new_dataframe = pandas.read_csv("data1.csv")
"""Iterate over dataframe rows and write values to worksheet"""
for i, row in new_dataframe.iterrows():
# ws.append leaves first line empty
# to get data written from first row, need to use writing to cell
if i == 0:
for c, value in enumerate(row, start=1):
ws.cell(row=2, column=c).value = value
else:
current_row = [row.col1, row.col2, row.col3]
ws.append(current_row)
"""Change table range"""
ws.tables['MyTable'].ref = "A1:E5"
"""Save workbook"""
wb.save(filename='file.xlsx')
Ethan 问题的答案:如何改变范围:
# Find right table
my_table = ws.tables['Template']
# Change range
my_table.ref = ref="A7:{}{}".format(column_string(maxRef[1], maxRef[0]))
# change style
my_table.tableStyleInfo = my_style
wb.save('WorkbookName')