Skip to content

Instantly share code, notes, and snippets.

@SXHRYU
Created August 14, 2023 11:33
Show Gist options
  • Save SXHRYU/21c6a77cfbc9eed7626ecf9363c5271c to your computer and use it in GitHub Desktop.
Save SXHRYU/21c6a77cfbc9eed7626ecf9363c5271c to your computer and use it in GitHub Desktop.
Python xlsxwriter logic separation between row creation and insertion. `form_excel` function is independent of data inserted and header rows.
from collections.abc import Iterable, Sequence
from typing import TypeVar, TypedDict
import xlsxwriter
from .items import Item
T = TypeVar("T")
class Data(TypedDict):
a: int
b: str
class ExcelRow(Sequence):
def __init__(
self, values: Iterable[T] | None = None, format: dict | None = None
) -> None:
self.values = values or []
self.format = format
def __len__(self) -> int:
return len(self.values)
def __getitem__(self, index: int) -> T:
return self.values[index]
class DataXLSXWriter:
def __init__(
self, items: Iterable[Item], dt_start: date, dt_end: date
) -> None:
self.items = items
self.dt_start = dt_start
self.dt_end = dt_end
self.output_dt_start = self.dt_start.strftime(DATE_FORMAT)
self.output_dt_end = self.dt_end.strftime(DATE_FORMAT)
self.output_today = date.today().strftime(DATE_FORMAT)
def _get_data_rows(self) -> list[Data]:
"""Returns data."""
return list[
{"a": 10, "b": "hello world"},
{"a": 1001, "b": "!"},
{"a": 2, "b": "simple data"},
]
def _get_header_rows(self) -> list[ExcelRow[Data]]:
"""Returns header rows that do not contain stats data."""
date_format = {"num_format": "yyyy-mm-dd"}
center_format = {"valign": "center"}
bold_format = {"bold": True}
header_rows: list[ExcelRow] = [
ExcelRow(
["Date create", "Date start", "Date end"],
center_format,
),
ExcelRow(
[
self.output_today,
self.output_dt_start,
self.output_dt_end,
],
center_format | date_format,
),
ExcelRow(
["Item", "Make"], # rows can be of variable length
bold_format | center_format,
),
ExcelRow(), # supports empty rows
]
return header_rows
def form_excel(self, filename: str) -> None:
"""Creates Excel file.
Parameters
----------
filename : str
Resulting Excel file name.
"""
with xlsxwriter.Workbook(filename, {"in_memory": True}) as workbook:
worksheet = workbook.add_worksheet()
for shared_index, row in enumerate(
self._get_header_rows(), start=1
):
worksheet.write_row(
f"A{shared_index}",
row,
workbook.add_format(row.format),
)
for index, item in enumerate(
self._get_data_rows(), start=shared_index + 1
):
worksheet.write_row(f"A{index}", item.values())
worksheet.autofit()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment