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

Я должен перенесите алгоритм из листа Excel в код python но я обратный инженер алгоритм из файла Excel.

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

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

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)

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

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

5 ответов


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

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

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

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

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

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

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

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


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


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

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

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

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


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

первый шаг, чтобы сохранить копию .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),"")',

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

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


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