【问题标题】:How to write data into existing '.xlsx' file which has multiple sheets如何将数据写入具有多个工作表的现有“.xlsx”文件
【发布时间】:2016-01-13 12:48:52
【问题描述】:

我必须将数据更新/追加到现有的 xlsx 文件中。

xlsx 文件包含多个工作表。 例如,我想将一些数据附加到现有工作表“Sheet1”中,如何做到这一点

【问题讨论】:

  • 简单地“更新/追加数据”是not going to work,所以您可能需要打开文件并将其内容存储在某处。该链接提供了一个示例,说明如何打开工作簿并循环浏览工作表。
  • 我知道复制数据然后重写到新文件并附加数据。我想有什么办法可以像我不理解的文本文件一样简单地附加数据,我问了一个正确的问题,为什么人们给它负面评价
  • 如果反对者gave their reason(s) to downvote 肯定会更好,这是肯定的。我认为您可以通过 (i) 解释您已经尝试过的内容(XlsxWriter 和/或 openpyxl,两者都应该在 Web 上很容易找到)和 (ii) 示例输入/代码/输出来避免投票。另外:如果您知道如何重写新文件并附加数据,我不会在我的第一条评论中建议这种可能性:)

标签: python excel openpyxl xlsx xlsxwriter


【解决方案1】:

要将新的数据行附加到现有电子表格,您可以使用openpyxl 模块。这将:

  1. 从文件中加载现有工作簿。
  2. 使用ws.get_highest_row() 确定正在使用的最后一行
  3. 在下一个空行中添加新行。
  4. 将更新后的电子表格写回到文件中

例如:

import openpyxl

file = 'input.xlsx'
new_row = ['data1', 'data2', 'data3', 'data4']

wb = openpyxl.load_workbook(filename=file)
ws = wb['Sheet1']     # Older method was  .get_sheet_by_name('Sheet1')
row = ws.get_highest_row() + 1

for col, entry in enumerate(new_row, start=1):
    ws.cell(row=row, column=col, value=entry)

wb.save(file)

注意,可以在 XlsxWriter 的文档中看到:

XlsxWriter 仅设计为文件编写器。它无法读取或修改 一个现有的 Excel 文件。

此方法不需要安装 Windows / Excel,但在支持级别方面存在一些限制。

【讨论】:

  • 我同意,XlsxWriter 仅用于文件写入,不用于更新现有文件
  • 目前 openpyxl 存在一些限制......它无法处理图形和其他一些对象。值得查看文档并检查您的工作表不会受到这些限制的影响。另一种选择是试试看;)
  • xlwings 使用 Excel COM API,因此不应影响图形等不受支持的元素。但是,如果您只是使用简单的 Excel 工作簿,那么 openpyxl 是一个不错的选择。我相信它会有所改善......
【解决方案2】:

试试xlwings(目前可从http://xlwings.org获得)它既适合读写excel文件。

您需要的一切都在quickstart tutorial 中。这样的东西应该是你想要的。

import xlwings as xw

with open("FileName.xlsx", "w") as file:
    wb = xw.Book(file)  # Creates a connection with workbook
    xw.Range('A1:D1').value = [1,2,3,4]

选择工作表

为了读取和写入数据到特定的工作表。您可以激活工作表,然后致电Range('cell_ref')

Sheet('Sheet1').activate();

使用 Range 选择单元格

选择当前工作表上的单个单元格

a = xw.Range('A1').value;
xw.Range('A1').value = float(a)+5;

显式选择一系列单元格

xw.Range('A1:E8').value = [new_cell_values_as_list_of_lists];
xw.Range('Named range').value = [new_cell_values_as_list_of_lists];

自动选择从“A1”开始并向右和向下移动的连续填充单元格范围...直到找到空单元格。

Range('A1').table.value;

也可以使用以下命令选择一行或一列:

Range('A1').vertical.value;
Range('A1').horizontal.value;

创建范围对象的其他方法(来自 api doc enter link description here

Range('A1')          Range('Sheet1', 'A1')          Range(1, 'A1')
Range('A1:C3')       Range('Sheet1', 'A1:C3')       Range(1, 'A1:C3')
Range((1,2))         Range('Sheet1, (1,2))          Range(1, (1,2))
Range((1,1), (3,3))  Range('Sheet1', (1,1), (3,3))  Range(1, (1,1), (3,3))
Range('NamedRange')  Range('Sheet1', 'NamedRange')  Range(1, 'NamedRange')

【讨论】:

  • 是的,尽管如果此链接无效,则可能是因为 xlwings 不再可用。在这一点上,如果我将快速入门中的部分内容复制到这篇文章中,那是不敬的,不是吗?
  • @djmcorrie 答案不仅适合您,还适合所有关注您的人。没有任何上下文或与解决 OP 问题的直接关系(例如显示用于解决 OP 问题的工具)的答案在此站点上没有用,具体取决于答案的严重性,要么被否决或被删除。我删除了这个以响应一个表明这种情况的标志;我做到了。然后这个答案得到了极大的改善,所以我取消了它。这就是 Stack Overflow 上涉及第三方工具的答案应该是这样的。
  • 好的,谢谢乔治,下次我会努力回答得更好;)
  • 看起来 xlwings 被重写了,所以这个答案不再有效。 这是 NOT 复制第 3 方文档部分的论据。
  • 感谢 Jason 的提醒,我已经更新了答案以反映当前文档......具有讽刺意味的是,URL 也发生了变化。所以我想这两种方法都不是完美的。虽然我个人认为两者可能是一个很好的平衡,因为它提供了更多的机会来获取所需的信息。
猜你喜欢
  • 2019-04-16
  • 1970-01-01
  • 2019-01-16
  • 1970-01-01
  • 2021-12-23
  • 1970-01-01
  • 2020-11-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多