【问题标题】:python xlsxwriter extract value from cellpython xlsxwriter 从单元格中提取值
【发布时间】:2020-07-12 18:46:57
【问题描述】:

是否可以提取我已写入 xlsxwriter.worksheet 的数据?

import xlsxwriter

output = "test.xlsx"
workbook = xlsxwriter.Workbook(output)
worksheet = workbook.add_worksheet()


worksheet.write(0, 0, 'top left')
if conditional:
    worksheet.write(1, 1, 'bottom right')

for row in range(2):
  for col in range(2):
    # Now how can I check if a value was written at this coordinate?
    # something like worksheet.get_value_at_row_col(row, col)

workbook.close()

【问题讨论】:

    标签: python-3.x xlsxwriter


    【解决方案1】:

    是否可以提取我已写入 xlsxwriter.worksheet 的数据?

    是的。尽管 XlsxWriter 是只写的,但它会将表值存储在内部结构中,并且仅在执行 workbook.close() 时将它们写入文件。

    每个工作表都有一个table 属性。它是一个字典,包含所有填充行的条目(从 0 开始的行号是键)。这些条目又是字典,包含行中所有填充单元格的条目(从 0 开始的列号是键)。

    因此,table[row][col] 将在所需位置为您提供条目(但仅在有条目的情况下,否则它将失败)。

    请注意,这些条目仍然不是您要查找的文本、数字或公式,而是命名的元组,其中也包含单元格格式。您可以键入检查条目并根据其性质提取内容。以下是type(entry) 的可能结果以及可访问的命名元组的字段:

    • xlsxwriter.worksheet.cell_string_tuple:字符串,格式
    • xlsxwriter.worksheet.cell_number_tuple:数字,格式
    • xlsxwriter.worksheet.cell_blank_tuple: 格式
    • xlsxwriter.worksheet.cell_boolean_tuple: 布尔值,格式
    • xlsxwriter.worksheet.cell_formula_tuple:公式、格式、值
    • xlsxwriter.worksheet.cell_arformula_tuple:公式、格式、值、范围

    对于数字、布尔值和公式,可以通过读取命名元组的相应字段来访问其内容。

    对于数组公式,内容仅出现在输出范围的左上角单元格中,而其余单元格由值为 0 的数字条目表示。

    对于字符串,情况就比较复杂了,因为Excel的存储概念有一个共享的字符串表,而各个单元格条目只指向这个表的一个索引。共享字符串表可以作为工作表的str_table.string_table 属性访问。它是一个字典,其中键是字符串,值是关联的索引。为了通过索引访问字符串,您可以从字典中生成一个排序列表,如下所示:

    shared_strings = sorted(worksheet.str_table.string_table, key=worksheet.str_table.string_table.get)
    

    我从上面扩展了您的示例,以包含所有已解释的功能。现在看起来像这样:

    import xlsxwriter
    
    output = "test.xlsx"
    workbook = xlsxwriter.Workbook(output)
    worksheet = workbook.add_worksheet()
    
    worksheet.write(0, 0, 'top left')
    worksheet.write(0, 1, 42)
    worksheet.write(0, 2, None)
    worksheet.write(2, 1, True)
    worksheet.write(2, 2, '=SUM(X5:Y7)')
    worksheet.write_array_formula(2,3,3,4, '{=TREND(X5:X7,Y5:Y7)}')
    worksheet.write(4,0, 'more text')
    worksheet.write(4,1, 'even more text')
    worksheet.write(4,2, 'more text')
    worksheet.write(4,3, 'more text')
    
    for row in range(5):
      row_dict = worksheet.table.get(row, None)
      for col in range(5):
        if row_dict != None:
          col_entry = row_dict.get(col, None)
        else:
          col_entry = None
        print(row,col,col_entry)
    
    shared_strings = sorted(worksheet.str_table.string_table, key=worksheet.str_table.string_table.get)
    
    print()
    if type(worksheet.table[0][0]) == xlsxwriter.worksheet.cell_string_tuple:
      print(shared_strings[worksheet.table[0][0].string])
    
    # type checking omitted for the rest...
    print(worksheet.table[0][1].number)
    print(bool(worksheet.table[2][1].boolean))
    print('='+worksheet.table[2][2].formula)
    print('{='+worksheet.table[2][3].formula+'}')
    
    workbook.close()
    

    【讨论】:

    • 我是 XlsxWriter 的作者。这是一个很好的逆向工程或概念证明,但我建议不要在实践中这样做。不保证数据在通过 XlsxWriter API 后将被维护或将被维护,无论是明确的还是隐含的。处理此类用例的最佳方法是跟踪库外的数据。 Python 有一个丰富的工具包来处理数据,这比依赖于不是为了跟踪数据而编写的库的内部结构要好。
    • 感谢您提供这么方便的python模块,XlsxWriter真的帮了我很多!我完全同意,一般来说,在 XlsxWriter 之外跟踪您的数据要容易得多。我只是在研究列宽的自动调整解决方案时偶然发现了这些内部结构,在填充表格时不需要经常注意......(准确地说,在这个答案中:stackoverflow.com/a/53091320)。
    • 一种更安全但可能更冗长的处理此问题的方法是继承并覆盖默认工作表类并添加一些自动调整代码,例如以下示例:xlsxwriter.readthedocs.io/example_inheritance2.html
    【解决方案2】:

    是否可以提取我已写入 xlsxwriter.worksheet 的数据?

    没有。 XlsxWriter 是只写的。如果您需要跟踪您的数据,您需要在 XlsxWriter 之外的您自己的代码中进行。

    【讨论】:

    • 虽然我同意在代码中跟踪数据是最简单的,但我认为在@Franz 答案中与 xlsxwriter 的创建者的回复与此一起值得。
    猜你喜欢
    • 1970-01-01
    • 2015-02-23
    • 1970-01-01
    • 1970-01-01
    • 2013-01-10
    • 1970-01-01
    • 2023-03-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多