|
| 1 | +import warnings |
| 2 | + |
| 3 | +from openpyxl.cell import MergedCell |
| 4 | +from openpyxl.comments.comment_sheet import CommentSheet |
| 5 | +from openpyxl.drawing.spreadsheet_drawing import SpreadsheetDrawing |
| 6 | +from openpyxl.packaging.relationship import ( |
| 7 | + get_rels_path, |
| 8 | + RelationshipList, |
| 9 | + get_dependents, |
| 10 | +) |
| 11 | +from openpyxl.pivot.table import TableDefinition |
| 12 | +from openpyxl.reader.drawings import find_images |
| 13 | +from openpyxl.worksheet._read_only import ReadOnlyWorksheet |
| 14 | +from openpyxl.worksheet._reader import WorksheetReader |
| 15 | +from openpyxl.xml.constants import COMMENTS_NS |
| 16 | +from openpyxl.xml.functions import fromstring |
| 17 | +from openpyxl.worksheet.table import Table |
| 18 | + |
| 19 | + |
| 20 | +# temporary fix for file not closed issue until openpyxl prepare release |
| 21 | +# https://foss.heptapod.net/openpyxl/openpyxl/-/merge_requests/ |
| 22 | +# 436#7922bd5f66e11e4ca4539f093b2680a25c1f80db |
| 23 | +def read_worksheets(self): |
| 24 | + # pylint: disable=too-many-branches |
| 25 | + comment_warning = ( |
| 26 | + "Cell '{0}':{1} is part of a merged range but has a comment which will " |
| 27 | + "be removed because merged cells cannot contain any data." |
| 28 | + ) |
| 29 | + for sheet, rel in self.parser.find_sheets(): |
| 30 | + if rel.target not in self.valid_files: |
| 31 | + continue |
| 32 | + |
| 33 | + if "chartsheet" in rel.Type: |
| 34 | + self.read_chartsheet(sheet, rel) |
| 35 | + continue |
| 36 | + |
| 37 | + rels_path = get_rels_path(rel.target) |
| 38 | + rels = RelationshipList() |
| 39 | + if rels_path in self.valid_files: |
| 40 | + rels = get_dependents(self.archive, rels_path) |
| 41 | + |
| 42 | + if self.read_only: |
| 43 | + ws = ReadOnlyWorksheet(self.wb, sheet.name, rel.target, self.shared_strings) |
| 44 | + ws.sheet_state = sheet.state |
| 45 | + self.wb._sheets.append(ws) # pylint: disable=protected-access |
| 46 | + continue |
| 47 | + fh = self.archive.open(rel.target) |
| 48 | + ws = self.wb.create_sheet(sheet.name) |
| 49 | + ws._rels = rels # pylint: disable=protected-access |
| 50 | + ws_parser = WorksheetReader( |
| 51 | + ws, fh, self.shared_strings, self.data_only, self.rich_text |
| 52 | + ) |
| 53 | + ws_parser.bind_all() |
| 54 | + fh.close() |
| 55 | + |
| 56 | + # assign any comments to cells |
| 57 | + for r in rels.find(COMMENTS_NS): |
| 58 | + src = self.archive.read(r.target) |
| 59 | + comment_sheet = CommentSheet.from_tree(fromstring(src)) |
| 60 | + for ref, comment in comment_sheet.comments: |
| 61 | + try: |
| 62 | + ws[ref].comment = comment |
| 63 | + except AttributeError: |
| 64 | + c = ws[ref] |
| 65 | + if isinstance(c, MergedCell): |
| 66 | + warnings.warn(comment_warning.format(ws.title, c.coordinate)) |
| 67 | + continue |
| 68 | + |
| 69 | + # preserve link to VML file if VBA |
| 70 | + if self.wb.vba_archive and ws.legacy_drawing: |
| 71 | + ws.legacy_drawing = rels.get(ws.legacy_drawing).target |
| 72 | + else: |
| 73 | + ws.legacy_drawing = None |
| 74 | + |
| 75 | + for t in ws_parser.tables: |
| 76 | + src = self.archive.read(t) |
| 77 | + xml = fromstring(src) |
| 78 | + table = Table.from_tree(xml) |
| 79 | + ws.add_table(table) |
| 80 | + |
| 81 | + #pylint: disable=protected-access |
| 82 | + drawings = rels.find(SpreadsheetDrawing._rel_type) |
| 83 | + for rel in drawings: |
| 84 | + charts, images = find_images(self.archive, rel.target) |
| 85 | + for c in charts: |
| 86 | + ws.add_chart(c, c.anchor) |
| 87 | + for im in images: |
| 88 | + ws.add_image(im, im.anchor) |
| 89 | + |
| 90 | + pivot_rel = rels.find(TableDefinition.rel_type) |
| 91 | + pivot_caches = self.parser.pivot_caches |
| 92 | + for r in pivot_rel: |
| 93 | + pivot_path = r.Target |
| 94 | + src = self.archive.read(pivot_path) |
| 95 | + tree = fromstring(src) |
| 96 | + pivot = TableDefinition.from_tree(tree) |
| 97 | + pivot.cache = pivot_caches[pivot.cacheId] |
| 98 | + ws.add_pivot(pivot) |
| 99 | + |
| 100 | + ws.sheet_state = sheet.state |
0 commit comments