apb_extra_utils.excel_utils

  1#  coding=utf-8
  2#
  3#  Author: Ernesto Arredondo Martinez (ernestone@gmail.com)
  4#  Created: 31/03/2019
  5#  Copyright (c)
  6import io
  7
  8from .utils_logging import get_file_logger
  9from openpyxl import load_workbook
 10
 11
 12def xls_sheet(file_xls, sheet_name=None, logger=None, **workbook_args):
 13    """
 14    Devuelve una hoja del fichero excel especificado.
 15    Si no se especifica nombre de hora (sheet_name) la primera que encuentre.
 16    Se podran especificar argumentos extras para la función load_workbook() pero
 17    si no, por defecto en modo read_only=True y data_only=True
 18
 19    Args:
 20        logger:
 21        file_xls (str): path fichero excel
 22        sheet_name (str=None): nombre hoja a devolver. Por defecto la primera que encuentre
 23        **workbook_args: Extra arguments para funcion load_workbook()
 24
 25    Returns:
 26        openpyxl.worksheet
 27    """
 28    if not logger:
 29        logger = get_file_logger()
 30
 31    read_only = workbook_args.pop('read_only', True)
 32
 33    if read_only:
 34        with open(file_xls, "rb") as f:
 35            in_mem_file = io.BytesIO(f.read())
 36        a_wb = load_workbook(in_mem_file,
 37                             read_only=read_only,
 38                             data_only=workbook_args.pop('data_only', True))
 39    else:
 40        a_wb = load_workbook(file_xls,
 41                             read_only=read_only,
 42                             data_only=workbook_args.pop('data_only', True))
 43
 44    sh1 = a_wb.sheetnames[0]
 45    if sheet_name and sheet_name not in a_wb.sheetnames:
 46        logger.warning(f"!AVISO! - No existe la hoja '{sheet_name}' en el excel '{file_xls}'. "
 47                       f"Se cogerá la primera hoja '{sh1}'")
 48        sheet_name = sh1
 49
 50    if not sheet_name:
 51        sheet_name = sh1
 52
 53    a_sheet = a_wb[sheet_name]
 54
 55    return a_sheet
 56
 57
 58def header_sheet(a_sheet, col_ini=None, col_fin=None):
 59    """
 60    Retorna lista con los valores de la primera fila que se tomaran como cabecera
 61
 62    Args:
 63        a_sheet (openpyxl.worksheet.woksheet):
 64        col_ini (int=None):
 65        col_fin (int=None):
 66
 67    Returns:
 68        list
 69    """
 70    return [col if col else "" for col in next(a_sheet.iter_rows(1, 1, col_ini, col_fin, values_only=True), [])]
 71
 72
 73def iter_vals_sheet(a_sheet, row_header=False, row_ini=None, row_fin=None, col_ini=None, col_fin=None):
 74    """
 75    Itera las filas de la hoja indicada y devuelve las filas como diccionarios indexados por el nombre de columna.
 76    Si se indica row_header=True entonces se tomaran los valores de la primera fila como nombres de columna
 77
 78    Args:
 79        a_sheet (openpyxl.worksheet.woksheet):
 80        row_header (bool=False):
 81        row_ini (int=None):
 82        row_fin (int=None):
 83        col_ini (int=None):
 84        col_fin (int=None):
 85
 86    Yields:
 87        dict
 88    """
 89    nom_cols_head = None
 90    if row_header:
 91        nom_cols_head = header_sheet(a_sheet, col_ini, col_fin)
 92        if not row_ini or row_ini == 1:
 93            row_ini = 2
 94
 95    for row in a_sheet.iter_rows(row_ini, row_fin, col_ini, col_fin, values_only=row_header):
 96        if row_header:
 97            yield dict(zip(nom_cols_head, row))
 98        else:
 99            yield {cell.column_letter: cell.value for cell in row}
100
101
102def close_file_sheet(a_sheet):
103    """
104    Cierra la conexion al fichero excel del sheet pasado por parametro
105
106    Args:
107        a_sheet:
108    """
109    a_sheet.parent._archive.close()
110
111
112if __name__ == '__main__':
113    from fire import Fire
114    Fire()
def xls_sheet(file_xls, sheet_name=None, logger=None, **workbook_args):
13def xls_sheet(file_xls, sheet_name=None, logger=None, **workbook_args):
14    """
15    Devuelve una hoja del fichero excel especificado.
16    Si no se especifica nombre de hora (sheet_name) la primera que encuentre.
17    Se podran especificar argumentos extras para la función load_workbook() pero
18    si no, por defecto en modo read_only=True y data_only=True
19
20    Args:
21        logger:
22        file_xls (str): path fichero excel
23        sheet_name (str=None): nombre hoja a devolver. Por defecto la primera que encuentre
24        **workbook_args: Extra arguments para funcion load_workbook()
25
26    Returns:
27        openpyxl.worksheet
28    """
29    if not logger:
30        logger = get_file_logger()
31
32    read_only = workbook_args.pop('read_only', True)
33
34    if read_only:
35        with open(file_xls, "rb") as f:
36            in_mem_file = io.BytesIO(f.read())
37        a_wb = load_workbook(in_mem_file,
38                             read_only=read_only,
39                             data_only=workbook_args.pop('data_only', True))
40    else:
41        a_wb = load_workbook(file_xls,
42                             read_only=read_only,
43                             data_only=workbook_args.pop('data_only', True))
44
45    sh1 = a_wb.sheetnames[0]
46    if sheet_name and sheet_name not in a_wb.sheetnames:
47        logger.warning(f"!AVISO! - No existe la hoja '{sheet_name}' en el excel '{file_xls}'. "
48                       f"Se cogerá la primera hoja '{sh1}'")
49        sheet_name = sh1
50
51    if not sheet_name:
52        sheet_name = sh1
53
54    a_sheet = a_wb[sheet_name]
55
56    return a_sheet

Devuelve una hoja del fichero excel especificado. Si no se especifica nombre de hora (sheet_name) la primera que encuentre. Se podran especificar argumentos extras para la función load_workbook() pero si no, por defecto en modo read_only=True y data_only=True

Arguments:
  • logger:
  • file_xls (str): path fichero excel
  • sheet_name (str=None): nombre hoja a devolver. Por defecto la primera que encuentre
  • **workbook_args: Extra arguments para funcion load_workbook()
Returns:

openpyxl.worksheet

def header_sheet(a_sheet, col_ini=None, col_fin=None):
59def header_sheet(a_sheet, col_ini=None, col_fin=None):
60    """
61    Retorna lista con los valores de la primera fila que se tomaran como cabecera
62
63    Args:
64        a_sheet (openpyxl.worksheet.woksheet):
65        col_ini (int=None):
66        col_fin (int=None):
67
68    Returns:
69        list
70    """
71    return [col if col else "" for col in next(a_sheet.iter_rows(1, 1, col_ini, col_fin, values_only=True), [])]

Retorna lista con los valores de la primera fila que se tomaran como cabecera

Arguments:
  • a_sheet (openpyxl.worksheet.woksheet):
  • col_ini (int=None):
  • col_fin (int=None):
Returns:

list

def iter_vals_sheet( a_sheet, row_header=False, row_ini=None, row_fin=None, col_ini=None, col_fin=None):
 74def iter_vals_sheet(a_sheet, row_header=False, row_ini=None, row_fin=None, col_ini=None, col_fin=None):
 75    """
 76    Itera las filas de la hoja indicada y devuelve las filas como diccionarios indexados por el nombre de columna.
 77    Si se indica row_header=True entonces se tomaran los valores de la primera fila como nombres de columna
 78
 79    Args:
 80        a_sheet (openpyxl.worksheet.woksheet):
 81        row_header (bool=False):
 82        row_ini (int=None):
 83        row_fin (int=None):
 84        col_ini (int=None):
 85        col_fin (int=None):
 86
 87    Yields:
 88        dict
 89    """
 90    nom_cols_head = None
 91    if row_header:
 92        nom_cols_head = header_sheet(a_sheet, col_ini, col_fin)
 93        if not row_ini or row_ini == 1:
 94            row_ini = 2
 95
 96    for row in a_sheet.iter_rows(row_ini, row_fin, col_ini, col_fin, values_only=row_header):
 97        if row_header:
 98            yield dict(zip(nom_cols_head, row))
 99        else:
100            yield {cell.column_letter: cell.value for cell in row}

Itera las filas de la hoja indicada y devuelve las filas como diccionarios indexados por el nombre de columna. Si se indica row_header=True entonces se tomaran los valores de la primera fila como nombres de columna

Arguments:
  • a_sheet (openpyxl.worksheet.woksheet):
  • row_header (bool=False):
  • row_ini (int=None):
  • row_fin (int=None):
  • col_ini (int=None):
  • col_fin (int=None):
Yields:

dict

def close_file_sheet(a_sheet):
103def close_file_sheet(a_sheet):
104    """
105    Cierra la conexion al fichero excel del sheet pasado por parametro
106
107    Args:
108        a_sheet:
109    """
110    a_sheet.parent._archive.close()

Cierra la conexion al fichero excel del sheet pasado por parametro

Arguments:
  • a_sheet: