From 9fede83453aa139999ff5bc396bdbe9fecce3ab9 Mon Sep 17 00:00:00 2001 From: charlesdwright Date: Sat, 11 Jun 2022 18:49:55 -0400 Subject: [PATCH 01/13] add to_xlsx function dumps sheets, cells and formula to xlsx todo: handle ranges, ? --- koala/Spreadsheet.py | 72 ++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 69 insertions(+), 3 deletions(-) diff --git a/koala/Spreadsheet.py b/koala/Spreadsheet.py index f4ac5db5..cad70e58 100644 --- a/koala/Spreadsheet.py +++ b/koala/Spreadsheet.py @@ -7,7 +7,10 @@ from koala.reader import read_archive, read_named_ranges, read_cells # This import equivalent functions defined in Excel. from koala.excellib import * + from openpyxl.formula.translate import Translator +from openpyxl import Workbook + from koala.serializer import * from koala.tokenizer import reverse_rpn from koala.utils import * @@ -17,8 +20,8 @@ import networkx from networkx.readwrite import json_graph -from openpyxl.compat import unicode - +#from openpyxl.compat import unicode +unicode = str class Spreadsheet(object): def __init__(self, file=None, ignore_sheets=[], ignore_hidden=False, debug=False): @@ -181,7 +184,7 @@ def gen_graph(self, outputs=[], inputs=[]): sp = Spreadsheet() sp.build_spreadsheet(G, cellmap, self.named_ranges, pointers = self.pointers, outputs = outputs, inputs = inputs, debug = self.debug) return sp - + def build_spreadsheet(self, G, cellmap, named_ranges, pointers = set(), outputs = set(), inputs = set(), debug = False): """ Writes the elements created by gen_graph to the object @@ -663,6 +666,69 @@ def dump_json(self, fname): def dump(self, fname): dump(self, fname) + + def to_xlsx(self, fname=None): + ''' + chaz's thing + ''' + if fname is None: + raise Exception('No file name specified, please provide one') + + #todo + #deal with ranges.... + #test ad-hoc worksheets w/random values + + ''' + isolate sheets, cells, and formulae into a dict: {thisSheet: (thisCell,thisFormula) } + ''' + z={} + for c in list(self.cellmap.values()): + thisSheet = c.address().split('!')[0] + thisCell = c.address().split('!')[1] + thisFormula = c.formula + thisValue = c.value + if thisFormula is None: + thisFormula = thisValue + #print(thisSheet, thisCell, thisFormula) + + if thisSheet not in z: + z[thisSheet]=[(thisCell, thisFormula)] + else: + z[thisSheet].append((thisCell,thisFormula)) + + ''' + create workbook with openpyxl + ''' + wb=Workbook() + + ''' + create sheets + ''' + for sheetName in z.keys(): + wb.create_sheet(sheetName) + + ''' + get rid of wb autocreated sheet + ''' + for sheet in wb.sheetnames: + if sheet not in z.keys(): + rm_sheet = wb[sheet]; + wb.remove_sheet(rm_sheet) + #wb.save("JustOneSheet.xlsx") + + ''' + add formulae to cells by sheet + ''' + for sheetName, values in z.items(): + for cells in values: + thisCell=cells[0] + thisFormula=cells[1] + wb[sheetName][thisCell]=thisFormula + print(sheetName, thisCell, thisFormula) + + wb.save(fname + ".xlsx") + + @staticmethod def load(fname): spreadsheet = Spreadsheet() From eae9d1499f465fcf3f74c037758f538116257808 Mon Sep 17 00:00:00 2001 From: charlesdwright Date: Mon, 27 Jun 2022 17:28:25 -0400 Subject: [PATCH 02/13] move code to dedicated module refact to handle ranges --- koala/ToExcel.py | 133 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 133 insertions(+) create mode 100644 koala/ToExcel.py diff --git a/koala/ToExcel.py b/koala/ToExcel.py new file mode 100644 index 00000000..0b88bed9 --- /dev/null +++ b/koala/ToExcel.py @@ -0,0 +1,133 @@ +import openpyxl + +def to_excel(spreadsheet, fname=None): + '''chaz's thing''' + + if name is None: + raise Exception('No filename specified. Please provide one.') + else: + fname=fname.split('.')[0] + + # TODO: + # sort sheets before creating + # test ad-hoc worksheets + # pivot tables? eek. + + spreadsheet.prune_graph() + #spreadsheet.clean_pointer() + + ''' + isolate sheets, cells, and formulae from graph into a dict: + {thisSheet: [(thisCell, thisFormula), (thisCell_1, thisFormula_1),...]} + do not include range names as keys + ''' + + theDict={} + + #print(spreadsheet.addr_to_name) + #print(spreadsheet.addr_to_range) + #print(spreadsheet.named_ranges) + + print('reading tree contents...') + print('address, formula, value') + + for c in list(spreadsheet.cellmap.values()): + print(c.address(), c.formula, c.value) + + ''' + actual name ranges (as opposed to named cells (single-cell ranges)) should be excluded + from theDict + ''' + if not and(c.address() in val for val in spreadsheet.addr_to_range.values()): + #print(c.address(), c.formula, c. value) + + thisCell = None + + x = c.address().split('!') + thisSheet = x[0] + if len(x) > 1: + thisCell =x[1] + + thisFormula = c.formula + if thisFormula is not None and thisFormula.find('=') != 0: thisFormula = '=' + thisFormula + + thisValue = c.value + + if thisFormula is not None: + thisValue = thisFormula + + print('collecting ' + thisSheet, thisCell, thisValue ) + if thisSheet not in theDict: + theDict[thisSheet] = [(thisCell, thisValue)] + else: + theDict[thisSheet].append((thisCell, thisValue)) + + ''' + clean up dict by removing range names from keys (keys are spreadsheet names) + ''' + for i in spreadsheet.named_ranges: + if i in theDict: + print(' removing name range for special handling') + theDict.pop(i) + + # print('------the dict------') + # print(theDict) + # print('--------------------') + + ''' + create the workbook with openpyxl + ''' + wb = openpyxl.Workbook() + + ''' + create sheets from theDict + ''' + for sheetName in theDict.keys(): + wb.create_sheet(sheetName) + + ''' + get rid of the sheet autocreated by openpyxl + and don't consider range names (if any) as sheet named_ranges + ''' + for sheet in wb.sheetnames: + if sheet not in theDict.keys() or sheet in spreadsheet.named_ranges: + rm_sheet = wb[sheet] + wb.remove(rm_sheet) + + ''' + add formuale to cells by sheets + ''' + for sheetName, values in theDict.items(): + print('adding cell contents...') + for cells in values: + thisCell = cells[0] + thisFormula = cells[1] + print(' adding ' + sheetName + '!' + thisCell, thisFormula) + wb[sheetName][thisCell] = thisFormula + + ''' + add named ranges + ''' + print('adding ranges') + for thisName, thisAddress in spreadsheet.named_ranges.items(): + thisAddress = absolute_addr(thisAddress) + + print(' adding range ', thisName, thisAddress) + theRange = openpyxl.defined_name.DefinedName(thisName, attr_text=thisAddress) + wb.defined_names.append(theRange) + + print('saving wb') + wb.save(fname + '.xlsx') + +def absolute_addr(theAddress): + #make the address absolute + theSheet = theAddress.split('!')[0] + theCells = theAddress.split('!')[1:] + for cell in theCells: + absCell = '' + for i in cell.split(':'): + absCell = absCell + openpyxl.cell.absolute_coordinate(i.strip()) + if len(cell.split(':')) > 1: absCell = absCell + ':' + if absCell[-1] == ':': absCell = absCell[:-1] + absAddress = theSheet + '!' + absCell + return absAddress From 03201f8b18502d34441faef7f8b54d4c6e4284cb Mon Sep 17 00:00:00 2001 From: charlesdwright Date: Mon, 27 Jun 2022 17:29:13 -0400 Subject: [PATCH 03/13] refactor to remove code to dedicated module --- koala/Spreadsheet.py | 124 ++++++++++++++++++++++--------------------- 1 file changed, 64 insertions(+), 60 deletions(-) diff --git a/koala/Spreadsheet.py b/koala/Spreadsheet.py index cad70e58..efde1747 100644 --- a/koala/Spreadsheet.py +++ b/koala/Spreadsheet.py @@ -20,6 +20,7 @@ import networkx from networkx.readwrite import json_graph +import ToExcel #from openpyxl.compat import unicode unicode = str @@ -667,66 +668,69 @@ def dump(self, fname): dump(self, fname) - def to_xlsx(self, fname=None): - ''' - chaz's thing - ''' - if fname is None: - raise Exception('No file name specified, please provide one') - - #todo - #deal with ranges.... - #test ad-hoc worksheets w/random values - - ''' - isolate sheets, cells, and formulae into a dict: {thisSheet: (thisCell,thisFormula) } - ''' - z={} - for c in list(self.cellmap.values()): - thisSheet = c.address().split('!')[0] - thisCell = c.address().split('!')[1] - thisFormula = c.formula - thisValue = c.value - if thisFormula is None: - thisFormula = thisValue - #print(thisSheet, thisCell, thisFormula) - - if thisSheet not in z: - z[thisSheet]=[(thisCell, thisFormula)] - else: - z[thisSheet].append((thisCell,thisFormula)) - - ''' - create workbook with openpyxl - ''' - wb=Workbook() - - ''' - create sheets - ''' - for sheetName in z.keys(): - wb.create_sheet(sheetName) - - ''' - get rid of wb autocreated sheet - ''' - for sheet in wb.sheetnames: - if sheet not in z.keys(): - rm_sheet = wb[sheet]; - wb.remove_sheet(rm_sheet) - #wb.save("JustOneSheet.xlsx") - - ''' - add formulae to cells by sheet - ''' - for sheetName, values in z.items(): - for cells in values: - thisCell=cells[0] - thisFormula=cells[1] - wb[sheetName][thisCell]=thisFormula - print(sheetName, thisCell, thisFormula) - - wb.save(fname + ".xlsx") + def to_excel(self, fname = None): + ToExcel.to_excel(self, fname) + + # def to_xlsx(self, fname=None): + # ''' + # chaz's thing + # ''' + # if fname is None: + # raise Exception('No file name specified, please provide one') + # + # #todo + # #deal with ranges.... + # #test ad-hoc worksheets w/random values + # + # ''' + # isolate sheets, cells, and formulae into a dict: {thisSheet: [(thisCell_1,thisFormula_1),(thisCell_2,thisFormula_2),...] } + # ''' + # z={} + # for c in list(self.cellmap.values()): + # thisSheet = c.address().split('!')[0] + # thisCell = c.address().split('!')[1] + # thisFormula = c.formula + # thisValue = c.value + # if thisFormula is None: + # thisFormula = thisValue + # #print(thisSheet, thisCell, thisFormula) + # + # if thisSheet not in z: + # z[thisSheet]=[(thisCell, thisFormula)] + # else: + # z[thisSheet].append((thisCell,thisFormula)) + # + # ''' + # create workbook with openpyxl + # ''' + # wb=Workbook() + # + # ''' + # create sheets + # ''' + # for sheetName in z.keys(): + # wb.create_sheet(sheetName) + # + # ''' + # get rid of wb autocreated sheet + # ''' + # for sheet in wb.sheetnames: + # if sheet not in z.keys(): + # rm_sheet = wb[sheet]; + # wb.remove_sheet(rm_sheet) + # #wb.save("JustOneSheet.xlsx") + # + # ''' + # add formulae to cells by sheet + # ''' + # for sheetName, values in z.items(): + # for cells in values: + # thisCell=cells[0] + # thisFormula=cells[1] + # wb[sheetName][thisCell]=thisFormula + # print(sheetName, thisCell, thisFormula) + # + # wb.save(fname + ".xlsx") @staticmethod From 8ed178667fd174df2286a308e23114f2d896b88a Mon Sep 17 00:00:00 2001 From: charlesdwright Date: Mon, 27 Jun 2022 17:32:04 -0400 Subject: [PATCH 04/13] remove deprecated code --- koala/Spreadsheet.py | 62 -------------------------------------------- 1 file changed, 62 deletions(-) diff --git a/koala/Spreadsheet.py b/koala/Spreadsheet.py index efde1747..60e96775 100644 --- a/koala/Spreadsheet.py +++ b/koala/Spreadsheet.py @@ -671,68 +671,6 @@ def dump(self, fname): def to_excel(self, fname = None): ToExcel.to_excel(self, fname) - # def to_xlsx(self, fname=None): - # ''' - # chaz's thing - # ''' - # if fname is None: - # raise Exception('No file name specified, please provide one') - # - # #todo - # #deal with ranges.... - # #test ad-hoc worksheets w/random values - # - # ''' - # isolate sheets, cells, and formulae into a dict: {thisSheet: [(thisCell_1,thisFormula_1),(thisCell_2,thisFormula_2),...] } - # ''' - # z={} - # for c in list(self.cellmap.values()): - # thisSheet = c.address().split('!')[0] - # thisCell = c.address().split('!')[1] - # thisFormula = c.formula - # thisValue = c.value - # if thisFormula is None: - # thisFormula = thisValue - # #print(thisSheet, thisCell, thisFormula) - # - # if thisSheet not in z: - # z[thisSheet]=[(thisCell, thisFormula)] - # else: - # z[thisSheet].append((thisCell,thisFormula)) - # - # ''' - # create workbook with openpyxl - # ''' - # wb=Workbook() - # - # ''' - # create sheets - # ''' - # for sheetName in z.keys(): - # wb.create_sheet(sheetName) - # - # ''' - # get rid of wb autocreated sheet - # ''' - # for sheet in wb.sheetnames: - # if sheet not in z.keys(): - # rm_sheet = wb[sheet]; - # wb.remove_sheet(rm_sheet) - # #wb.save("JustOneSheet.xlsx") - # - # ''' - # add formulae to cells by sheet - # ''' - # for sheetName, values in z.items(): - # for cells in values: - # thisCell=cells[0] - # thisFormula=cells[1] - # wb[sheetName][thisCell]=thisFormula - # print(sheetName, thisCell, thisFormula) - # - # wb.save(fname + ".xlsx") - - @staticmethod def load(fname): spreadsheet = Spreadsheet() From 3dd68098e758cee3d736123c96c8ac6eefbed5dd Mon Sep 17 00:00:00 2001 From: charlesdwright Date: Tue, 28 Jun 2022 18:13:38 -0400 Subject: [PATCH 05/13] add .venv --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 2f295e5f..249685e0 100644 --- a/.gitignore +++ b/.gitignore @@ -15,3 +15,4 @@ eval* .pytest_cache .tox docs_api +.venv From 830e4bee9aced33e7ee59bb2f5ba20af95800361 Mon Sep 17 00:00:00 2001 From: charlesdwright Date: Tue, 28 Jun 2022 18:16:17 -0400 Subject: [PATCH 06/13] unicode workaround added --- koala/Cell.py | 4 ++-- koala/Range.py | 4 ++-- koala/ast/__init__.py | 4 +++- koala/ast/astnodes.py | 5 +++-- koala/excellib.py | 3 ++- koala/serializer.py | 16 ++++++++-------- koala/utils.py | 3 ++- 7 files changed, 22 insertions(+), 17 deletions(-) diff --git a/koala/Cell.py b/koala/Cell.py index df893ccd..a7e8cc43 100644 --- a/koala/Cell.py +++ b/koala/Cell.py @@ -6,8 +6,8 @@ from koala.Range import RangeCore from koala.utils import * -from openpyxl.compat import unicode - +#from openpyxl.compat import unicode +unicode = str class Cell(CellBase): ctr = 0 diff --git a/koala/Range.py b/koala/Range.py index f3c2c0cd..7f33dfa1 100644 --- a/koala/Range.py +++ b/koala/Range.py @@ -4,8 +4,8 @@ from koala.ExcelError import ErrorCodes, ExcelError from koala.utils import * -from openpyxl.compat import unicode - +#from openpyxl.compat import unicode +unicode = str # WARNING: Range should never be imported directly. Import Range from excelutils instead. diff --git a/koala/ast/__init__.py b/koala/ast/__init__.py index 6d1f8d21..bd817e33 100644 --- a/koala/ast/__init__.py +++ b/koala/ast/__init__.py @@ -6,7 +6,9 @@ import networkx from networkx.classes.digraph import DiGraph -from openpyxl.compat import unicode + +#from openpyxl.compat import unicode +unicode = str from koala.utils import uniqueify, flatten, max_dimension, col2num, resolve_range from koala.Cell import Cell diff --git a/koala/ast/astnodes.py b/koala/ast/astnodes.py index 03bceb44..3c766f91 100644 --- a/koala/ast/astnodes.py +++ b/koala/ast/astnodes.py @@ -3,7 +3,8 @@ from networkx import NetworkXError -from openpyxl.compat import unicode +#from openpyxl.compat import unicode +unicode = str from koala.excellib import FUNCTION_MAP, IND_FUN from koala.utils import is_range, split_range, split_address, resolve_range @@ -45,7 +46,7 @@ def __getattr__(self, name): def children(self, ast): try: args = ast.predecessors(self) - args = sorted(args, key=lambda x: ast.node[x]['pos']) + args = sorted(args, key=lambda x: ast.nodes[x]['pos']) except NetworkXError: args = '' return args diff --git a/koala/excellib.py b/koala/excellib.py index 46b85008..aef11d16 100644 --- a/koala/excellib.py +++ b/koala/excellib.py @@ -18,7 +18,8 @@ from calendar import monthrange from dateutil.relativedelta import relativedelta -from openpyxl.compat import unicode +#from openpyxl.compat import unicode +unicode = str from koala.utils import * from koala.Range import RangeCore as Range diff --git a/koala/serializer.py b/koala/serializer.py index 27dd2d79..7a20ab91 100644 --- a/koala/serializer.py +++ b/koala/serializer.py @@ -7,8 +7,8 @@ from networkx.classes.digraph import DiGraph from networkx.readwrite import json_graph from networkx.drawing.nx_pydot import write_dot -from openpyxl.compat import unicode - +#from openpyxl.compat import unicode +unicode = str from koala.Cell import Cell from koala.Range import RangeCore, RangeFactory @@ -120,12 +120,12 @@ def to_float(string): inputs = None named_ranges = {} infile = gzip.GzipFile(fname, 'rb') - + for line in infile.read().splitlines(): line= line.decode("utf-8") - if line == "====": + if line == "====": mode = "node0" continue if line == "-----": @@ -133,7 +133,7 @@ def to_float(string): Range = RangeFactory(cellmap_temp) mode = "node0" continue - elif line == "edges": + elif line == "edges": cellmap = {n.address(): n for n in nodes} mode = "edges" continue @@ -148,15 +148,15 @@ def to_float(string): continue if mode == "node0": - [address, formula, python_expression, is_range, is_named_range, is_pointer, should_eval] = line.split(SEP) + [address, formula, python_expression, is_range, is_named_range, is_pointer, should_eval] = line.split(SEP) formula = clean_bool(formula) python_expression = clean_bool(python_expression) is_range = to_bool(is_range) is_named_range = to_bool(is_named_range) is_pointer = to_bool(is_pointer) - should_eval = should_eval + should_eval = should_eval mode = "node1" - elif mode == "node1": + elif mode == "node1": if is_range: reference = json.loads(line) if is_pointer else line # in order to be able to parse dicts vv = Range(reference) diff --git a/koala/utils.py b/koala/utils.py index 626f1980..4d92687a 100644 --- a/koala/utils.py +++ b/koala/utils.py @@ -13,7 +13,8 @@ from six import string_types from copy import deepcopy -from openpyxl.compat import unicode +#from openpyxl.compat import unicode +unicode = str from .ExcelError import ExcelError From 6dff67fb9e9eb15b8af498984f77f781dc0e9ab4 Mon Sep 17 00:00:00 2001 From: charlesdwright Date: Tue, 28 Jun 2022 18:40:48 -0400 Subject: [PATCH 07/13] add #Environments --- .gitignore | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/.gitignore b/.gitignore index 249685e0..fde77957 100644 --- a/.gitignore +++ b/.gitignore @@ -15,4 +15,12 @@ eval* .pytest_cache .tox docs_api + +# Environments +.env .venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ From 7082e18e1578f59faff0129c19553a242931f8a2 Mon Sep 17 00:00:00 2001 From: charlesdwright Date: Tue, 28 Jun 2022 18:45:06 -0400 Subject: [PATCH 08/13] reorder to avoid lxml install fail --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index c676f783..3f0a0f55 100644 --- a/requirements.txt +++ b/requirements.txt @@ -2,8 +2,8 @@ networkx==2.1 openpyxl==2.5.3 numpy>=1.14.2 Cython==0.28.2 -lxml==4.1.1 six==1.11.0 scipy>=1.0.0 python-dateutil==2.8.0 backports.functools_lru_cache==1.5 +lxml==4.1.1 From d2295e9c4267cff0a7e72e28eb543f6ed0e8528e Mon Sep 17 00:00:00 2001 From: charlesdwright Date: Tue, 28 Jun 2022 18:54:17 -0400 Subject: [PATCH 09/13] tweaked to force push again. --- koala/ToExcel.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/koala/ToExcel.py b/koala/ToExcel.py index 0b88bed9..bc7f7f43 100644 --- a/koala/ToExcel.py +++ b/koala/ToExcel.py @@ -21,7 +21,7 @@ def to_excel(spreadsheet, fname=None): {thisSheet: [(thisCell, thisFormula), (thisCell_1, thisFormula_1),...]} do not include range names as keys ''' - + theDict={} #print(spreadsheet.addr_to_name) From c7230252f446fdf7de0d5855c3a47cba7eed6c99 Mon Sep 17 00:00:00 2001 From: charlesdwright Date: Tue, 28 Jun 2022 19:16:12 -0400 Subject: [PATCH 10/13] typo corrected --- koala/ToExcel.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/koala/ToExcel.py b/koala/ToExcel.py index bc7f7f43..124cf55d 100644 --- a/koala/ToExcel.py +++ b/koala/ToExcel.py @@ -21,7 +21,7 @@ def to_excel(spreadsheet, fname=None): {thisSheet: [(thisCell, thisFormula), (thisCell_1, thisFormula_1),...]} do not include range names as keys ''' - + theDict={} #print(spreadsheet.addr_to_name) @@ -38,7 +38,7 @@ def to_excel(spreadsheet, fname=None): actual name ranges (as opposed to named cells (single-cell ranges)) should be excluded from theDict ''' - if not and(c.address() in val for val in spreadsheet.addr_to_range.values()): + if not any(c.address() in val for val in spreadsheet.addr_to_range.values()): #print(c.address(), c.formula, c. value) thisCell = None From 9003d04e2194e16ececba58e191171cbb20810b1 Mon Sep 17 00:00:00 2001 From: charlesdwright Date: Wed, 29 Jun 2022 11:49:58 -0400 Subject: [PATCH 11/13] fully qualify import --- koala/Spreadsheet.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/koala/Spreadsheet.py b/koala/Spreadsheet.py index 60e96775..1ec27da6 100644 --- a/koala/Spreadsheet.py +++ b/koala/Spreadsheet.py @@ -20,7 +20,8 @@ import networkx from networkx.readwrite import json_graph -import ToExcel +import koala.ToExcel + #from openpyxl.compat import unicode unicode = str From 1c865871e2433638f6cb4edc63f08396ff00bcf1 Mon Sep 17 00:00:00 2001 From: charlesdwright Date: Thu, 30 Jun 2022 10:01:37 -0400 Subject: [PATCH 12/13] -- enable graph updating when cells added manually -- fully qualify import of local module --- koala/Spreadsheet.py | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/koala/Spreadsheet.py b/koala/Spreadsheet.py index 1ec27da6..78b91501 100644 --- a/koala/Spreadsheet.py +++ b/koala/Spreadsheet.py @@ -279,8 +279,16 @@ def cell_add(self, address=None, cell=None, value=None, formula=None): cellmap, G = graph_from_seeds([cell], self) - self.cellmap = cellmap - self.G = G + ''' + update this spreadsheet object + ''' + self.build_spreadsheet(G, cellmap, self.named_range, debug=self.debug) + + ''' + superceded by above + ''' + # self.cellmap = cellmap + # self.G = G print("Graph construction updated, %s nodes, %s edges, %s cellmap entries" % (len(G.nodes()),len(G.edges()),len(cellmap))) @@ -670,7 +678,7 @@ def dump(self, fname): def to_excel(self, fname = None): - ToExcel.to_excel(self, fname) + koala.ToExcel.to_excel(self, fname) @staticmethod def load(fname): From d6aacf846ac7b2fd31a520de4aa482e6a1cd94b5 Mon Sep 17 00:00:00 2001 From: charlesdwright Date: Thu, 30 Jun 2022 10:02:47 -0400 Subject: [PATCH 13/13] -- correct typo -- refactoring for economy -- close wb before saving and wrap in 'try' block. --- koala/ToExcel.py | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/koala/ToExcel.py b/koala/ToExcel.py index 124cf55d..4d269ece 100644 --- a/koala/ToExcel.py +++ b/koala/ToExcel.py @@ -3,7 +3,7 @@ def to_excel(spreadsheet, fname=None): '''chaz's thing''' - if name is None: + if fname is None: raise Exception('No filename specified. Please provide one.') else: fname=fname.split('.')[0] @@ -33,7 +33,6 @@ def to_excel(spreadsheet, fname=None): for c in list(spreadsheet.cellmap.values()): print(c.address(), c.formula, c.value) - ''' actual name ranges (as opposed to named cells (single-cell ranges)) should be excluded from theDict @@ -43,10 +42,14 @@ def to_excel(spreadsheet, fname=None): thisCell = None - x = c.address().split('!') - thisSheet = x[0] - if len(x) > 1: - thisCell =x[1] + thisAddress = c.address().split('!') + thisSheet = thisAddress[0] + if len(thisAddress) > 1: + thisCell = thisAddress[1] + + #thisCell=None + # thisSheet = c.address().split('!')[0] + # if len(c.address().) thisFormula = c.formula if thisFormula is not None and thisFormula.find('=') != 0: thisFormula = '=' + thisFormula @@ -83,6 +86,7 @@ def to_excel(spreadsheet, fname=None): create sheets from theDict ''' for sheetName in theDict.keys(): + print(' creating sheet... ', sheetName) wb.create_sheet(sheetName) ''' @@ -117,7 +121,11 @@ def to_excel(spreadsheet, fname=None): wb.defined_names.append(theRange) print('saving wb') - wb.save(fname + '.xlsx') + try: + wb.close() + wb.save(fname + '.xlsx') + except Exception as e: + print('error saving wb: "' + str(e)+'"') def absolute_addr(theAddress): #make the address absolute