Внесение данных из файлов приёма в реестр невостребованных документов и заполнение журнала. Дата внесения — текущая; журнал заполняется чисто (без строк-примеров шаблона). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
45 lines
1.4 KiB
Python
45 lines
1.4 KiB
Python
# -*- coding: utf-8 -*-
|
|
"""Читатель .xls (xlrd). Корректно разбирает даты-сериалы Excel."""
|
|
from __future__ import annotations
|
|
|
|
from typing import List
|
|
|
|
import xlrd
|
|
|
|
from ..models import CellValue
|
|
from .base import SourceReader
|
|
|
|
|
|
class XlsReader(SourceReader):
|
|
def _rows(self) -> List[List[CellValue]]:
|
|
book = xlrd.open_workbook(self.path)
|
|
try:
|
|
sheet = book.sheet_by_index(0)
|
|
rows: List[List[CellValue]] = []
|
|
for r in range(sheet.nrows):
|
|
row: List[CellValue] = []
|
|
for c in range(sheet.ncols):
|
|
row.append(self._cell(book, sheet.cell(r, c)))
|
|
rows.append(row)
|
|
return rows
|
|
finally:
|
|
book.release_resources()
|
|
|
|
@staticmethod
|
|
def _cell(book, cell) -> CellValue:
|
|
t = cell.ctype
|
|
if t == xlrd.XL_CELL_EMPTY or t == xlrd.XL_CELL_BLANK:
|
|
return None
|
|
if t == xlrd.XL_CELL_DATE:
|
|
dt = xlrd.xldate_as_datetime(cell.value, book.datemode)
|
|
# дата без времени -> date
|
|
if dt.hour == dt.minute == dt.second == 0:
|
|
return dt.date()
|
|
return dt
|
|
if t == xlrd.XL_CELL_NUMBER:
|
|
return cell.value
|
|
if t == xlrd.XL_CELL_BOOLEAN:
|
|
return bool(cell.value)
|
|
text = str(cell.value).strip()
|
|
return text or None
|