Подтвердить что ты не робот

Получить формулу из ячейки Excel с помощью python xlrd

Я должен переносить алгоритм из листа Excel в код python, но мне нужно перепроектировать алгоритм из файла Excel.

Лист Excel довольно сложный, он содержит много ячеек, в которых есть формулы, относящиеся к другим ячейкам (которые также могут содержать формулу или константу).

Моя идея состоит в том, чтобы проанализировать с помощью python script строение таблицы своего рода таблицы зависимостей между ячейками, то есть:

A1 зависит от формулы B4, C5, E7: "= sqrt (B4) + C5 * E7"
A2 зависит от формулы B5, C6: "= sin (B5) * C6"
...

xlrd модуль python позволяет читать книгу XLS, но на данный момент я могу получить доступ к значению ячейки, а не формула.

Например, со следующим кодом я могу просто получить значение ячейки:

import xlrd

#open the .xls file
xlsname="test.xls"
book = xlrd.open_workbook(xlsname)

#build a dictionary of the names->sheets of the book
sd={}
for s in book.sheets():
    sd[s.name]=s

#obtain Sheet "Foglio 1" from sheet names dictionary
sheet=sd["Foglio 1"]

#print value of the cell J141
print sheet.cell(142,9)

В любом случае, похоже, у него нет способа получить формулу из объекта Cell, возвращаемого методом .cell(...). В документации говорится, что можно получить строчную версию формулы (на английском языке, потому что нет никакой информации о переводе имени функции, хранящемся в Excel). Они говорят о формулах (выражениях) в классах Name и Operand, так или иначе я не могу понять, как получить экземпляры этих классов экземпляром класса Cell, который должен содержать их.

Не могли бы вы предложить фрагмент кода, который получает текст формулы из ячейки?

4b9b3361

Ответ 1

[Dis]: Я автор/сопровождающий xlrd.

Ссылки на документацию по тексту формулы описываются формулами "имя"; прочитайте раздел "Именованные ссылки, константы, формулы и макросы" рядом с началом документов. Эти формулы связаны с обложкой или книгой по всему имени; они не связаны с отдельными ячейками. Примеры: PI отображается на =22/7, SALES отображается на =Mktng!$A$2:$Z$99. Декомпилятор формулы имен был написан для поддержки проверки более простых и/или общепринятых способов использования определенных имен.

Формулы в целом имеют несколько типов: cell, shared и array (все связанные с ячеек, прямо или косвенно), имя, валидация данных и условное форматирование.

Декомпиляция общих формул из байт-кода в текст - это "работа в процессе", медленно. Обратите внимание, что, если предположить, что он был доступен, вам нужно будет проанализировать формулу текста, чтобы извлечь ссылки на ячейки. Правильная формулировка формул Excel - непростая задача; как с HTML, использование регулярных выражений выглядит легко, но не работает. Было бы лучше извлечь ссылки непосредственно из байт-кода формулы.

Также обратите внимание, что формулы на основе ячеек могут ссылаться на имена, а формулы имен могут ссылаться как на ячейки, так и на другие имена. Поэтому было бы необходимо извлечь как ссылки на ячейки, так и имена из формул на основе ячеек и имен. Возможно, вам будет полезно иметь информацию о доступных общих формулах; в противном случае проанализировалось следующее:

B2 =A2
B3 =A3+B2
B4 =A4+B3
B5 =A5+B4
...
B60 =A60+B59

вам нужно будет вывести сходство между формулами B3:B60.

В любом случае, ни одно из вышеперечисленных, скорее всего, не будет доступно в ближайшее время - xlrd приоритеты лежат в другом месте.

Ответ 2

Обновление. Я отправил и реализовал небольшую библиотеку, чтобы сделать то, что вы описали: извлечение ячеек и зависимостей из электронной таблицы Excel и преобразование их в код python. Код находится в github, исправления приветствуются:)


Просто добавьте, что вы всегда можете взаимодействовать с excel, используя win32com (не очень быстро, но он работает). Это позволяет вам получить формулу. A учебник можно найти здесь, и подробности можно найти в этой главе [кешированная копия].

По существу вы просто делаете:

app.ActiveWorkbook.ActiveSheet.Cells(r,c).Formula

Что касается построения таблицы зависимостей между ячейками, сложная вещь заключается в анализе выражений excel. Если я правильно помню, код Trace, о котором вы говорили, не всегда делает это правильно. Лучшее, что я видел, это алгоритм Е. У. Бахтала, из которого доступна реализация python, которая хорошо работает.

Ответ 3

Итак, я знаю, что это очень старое сообщение, но я нашел достойный способ получить формулы со всех листов в книге, а также, чтобы вновь созданная книга сохранила все форматирование.

Первый шаг - сохранить копию вашего .xlsx файла как .xls - Используйте .xls в качестве имени файла в коде ниже

Использование Python 2.7

from lxml import etree
from StringIO import StringIO
import xlsxwriter
import subprocess
from xlrd import open_workbook
from xlutils.copy import copy
from xlsxwriter.utility import xl_cell_to_rowcol
import os



file_name = '<YOUR-FILE-HERE>'
dir_path = os.path.dirname(os.path.realpath(file_name))

subprocess.call(["unzip",str(file_name+"x"),"-d","file_xml"])


xml_sheet_names = dict()

with open_workbook(file_name,formatting_info=True) as rb:
    wb = copy(rb)
    workbook_names_list = rb.sheet_names()
    for i,name in enumerate(workbook_names_list):
        xml_sheet_names[name] = "sheet"+str(i+1)

sheet_formulas = dict()
for i, k in enumerate(workbook_names_list):
    xmlFile = os.path.join(dir_path,"file_xml/xl/worksheets/{}.xml".format(xml_sheet_names[k]))
    with open(xmlFile) as f:
        xml = f.read()

    tree = etree.parse(StringIO(xml))
    context = etree.iterparse(StringIO(xml))

    sheet_formulas[k] = dict()
    for _, elem in context:
        if elem.tag.split("}")[1]=='f':
            cell_key = elem.getparent().get(key="r")
            cell_formula = elem.text
            sheet_formulas[k][cell_key] = str("="+cell_formula)

sheet_formulas

Структура словаря "sheet_formulas"

{'Worksheet_Name': {'A1_cell_reference':'cell_formula'}}

Примеры результатов:

{u'CY16': {'A1': '=Data!B5',
  'B1': '=Data!B1',
  'B10': '=IFERROR(Data!B12,"")',
  'B11': '=IFERROR(SUM(B9:B10),"")',

Ответ 4

Кажется, теперь невозможно сделать то, что вы хотите, с xlrd. Вы можете посмотреть этот пост для подробного описания того, почему так сложно реализовать необходимые функции.

Обратите внимание, что команда разработчиков делает отличную работу для поддержки в группе google python-excel.

Ответ 5

Я знаю, что это сообщение немного поздно, но есть одно предложение, которое здесь не было рассмотрено. Вырезать все записи из листа и вставить с помощью специальной пасты (OpenOffice). Это преобразует формулы в числа, поэтому нет необходимости в дополнительном программировании, и это разумное решение для небольших книг.