Skip to content

Commit

Permalink
Add function to expand tables in xlsx based on content
Browse files Browse the repository at this point in the history
  • Loading branch information
dalito committed Aug 26, 2023
1 parent 978a10e commit 9e5cf77
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 2 deletions.
41 changes: 40 additions & 1 deletion src/voc4cat/utils.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
import glob
import logging
import os
from copy import copy
from pathlib import Path

from openpyxl import load_workbook # as _load_workbook
from openpyxl import load_workbook
from openpyxl.utils.cell import coordinate_from_string
from openpyxl.workbook.workbook import Workbook
from openpyxl.worksheet.table import Table

from voc4cat.checks import Voc4catError

Expand Down Expand Up @@ -80,3 +83,39 @@ def has_file_in_multiple_formats(dir_):
return False
seen = set()
return [x for x in file_names if x in seen or seen.add(x)]


def adjust_length_of_tables(wb_path):
"""Expand length of all tables in workbook to include all filled rows
For all tables in the workbook the table is expanded to include the last
row with content. Note that tables are not shrunk by this method if they
contain empty rows at the end.
"""
wb = load_workbook(wb_path)

for ws in wb.sheetnames:
for t_name in list(wb[ws].tables):
old_range = wb[ws].tables[t_name].ref # "A2:I20"
start, end = old_range.split(":")
end_col, _end_row = coordinate_from_string(end)
adjusted = f"{start}:{end_col}{wb[ws].max_row}"
if adjusted == old_range:
continue
# Expanding the table is not possible with openpyxl. Instead a too
# short table is removed, and a new adjusted table is created.
style = copy(wb[ws].tables[t_name].tableStyleInfo)
del wb[ws].tables[t_name]
newtab = Table(displayName=t_name, ref=adjusted)
newtab.tableStyleInfo = style
wb[ws].add_table(newtab)
logger.debug(
'Adjusted table "%s" in sheet "%s" from {%s} to {%s}.',
t_name,
wb[ws].title,
old_range,
adjusted,
)

wb.save(wb_path)
wb.close()
28 changes: 27 additions & 1 deletion tests/test_utils.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
from voc4cat.utils import split_and_tidy
from openpyxl import Workbook, load_workbook
from openpyxl.worksheet.table import Table
from voc4cat.utils import adjust_length_of_tables, split_and_tidy


def test_default_action():
Expand All @@ -11,3 +13,27 @@ def test_default_action():
def test_trailing_comma():
assert split_and_tidy("a,") == ["a"]
assert split_and_tidy("a,b,") == ["a", "b"]


def test_expand_tables(tmp_path):
test_wb = tmp_path / "table.xlsx"
wb = Workbook()
ws = wb.active
ws.append(["Letter", "value"]) # table header
data = [
["A", 1],
["B", 2],
]
for row in data:
ws.append(row)
tab = Table(displayName="Table1", ref="A1:B3")
ws.add_table(tab)
ws["A5"] = "X"
wb.save(test_wb)

adjust_length_of_tables(test_wb)

wb = load_workbook(test_wb)
name, table_range = wb.active.tables.items()[0]
assert name == "Table1"
assert table_range == "A1:B5"

0 comments on commit 9e5cf77

Please sign in to comment.