Código fuente para pydatajson.writers

#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""Módulo 'writers' de pydatajson

Contiene los métodos para escribir
- diccionarios con metadatos de catálogos a formato JSON, así como
- listas de diccionarios ("tablas") en formato CSV o XLSX
"""

from __future__ import unicode_literals
from __future__ import print_function
from __future__ import with_statement

import io
import json
import unicodecsv as csv
import openpyxl as pyxl
from openpyxl.utils import column_index_from_string
import logging
from . import helpers


[documentos]def write_table(table, path, column_styles=None, cell_styles=None): """ Exporta una tabla en el formato deseado (CSV o XLSX). La extensión del archivo debe ser ".csv" o ".xlsx", y en función de ella se decidirá qué método usar para escribirlo. Args: table (list of dicts): Tabla a ser exportada. path (str): Path al archivo CSV o XLSX de exportación. """ assert isinstance(path, (str, unicode)), "`path` debe ser un string" assert isinstance(table, list), "`table` debe ser una lista de dicts" # si la tabla está vacía, no escribe nada if len(table) == 0: logging.warning("Tabla vacia: no se genera ninguna archivo.") return # Sólo sabe escribir listas de diccionarios con información tabular if not helpers.is_list_of_matching_dicts(table): raise ValueError(""" La lista ingresada no esta formada por diccionarios con las mismas claves.""") # Deduzco el formato de archivo de `path` y redirijo según corresponda. suffix = path.split(".")[-1] if suffix == "csv": return _write_csv_table(table, path) elif suffix == "xlsx": return _write_xlsx_table(table, path, column_styles, cell_styles) else: raise ValueError(""" {} no es un sufijo reconocido. Pruebe con .csv o.xlsx""".format(suffix))
def _write_csv_table(table, path): headers = table[0].keys() with open(path, 'w') as target_file: writer = csv.DictWriter(csvfile=target_file, fieldnames=headers, lineterminator="\n", encoding='utf-8') writer.writeheader() for row in table: writer.writerow(row) def _apply_styles_to_ws(ws, column_styles=None, cell_styles=None): # aplica estilos de columnas if column_styles: for col, properties in column_styles.iteritems(): for prop_name, prop_value in properties.iteritems(): setattr(ws.column_dimensions[col], prop_name, prop_value) # aplica estilos de celdas if cell_styles: for i in xrange(1, ws.max_row + 1): for j in xrange(1, ws.max_column + 1): cell = ws.cell(row=i, column=j) for cell_style in cell_styles: match_all = ( "col" not in cell_style and "row" not in cell_style ) match_row = ( "row" in cell_style and cell_style["row"] == i ) match_col = ( "col" in cell_style and column_index_from_string(cell_style["col"]) == j ) if match_all or match_row or match_col: for prop_name, prop_value in cell_style.iteritems(): if prop_name != "col" and prop_name != "row": setattr(cell, prop_name, prop_value) def _write_xlsx_table(table, path, column_styles=None, cell_styles=None): workbook = pyxl.Workbook() worksheet = workbook.active headers = table[0].keys() worksheet.append(headers) for index, row in enumerate(table): worksheet.append(row.values()) _apply_styles_to_ws(worksheet, column_styles, cell_styles) workbook.save(path)
[documentos]def write_json(obj, path): """Escribo un objeto a un archivo JSON con codificación UTF-8.""" obj_str = unicode(json.dumps(obj, indent=4, separators=(",", ": "), ensure_ascii=False)) with io.open(path, "w", encoding='utf-8') as target: target.write(obj_str)
[documentos]def write_json_catalog(catalog, path): """Función de compatibilidad con releases anteriores.""" write_json(catalog, path)