Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- """
- Универсальный скрипт для конвертации CSV в Excel с форматированием.
- Использование:
- python csv_to_excel.py input.csv [output.xlsx] [--encoding ENCODING] [--multiline]
- Параметры:
- input.csv - путь к входному CSV файлу (обязательно)
- output.xlsx - путь к выходному Excel файлу (опционально, по умолчанию: input.xlsx)
- --encoding ENCODING - кодировка CSV файла (по умолчанию: utf-8)
- --multiline - включить обработку многострочных полей (объединение строк)
- """
- import csv
- import sys
- import argparse
- import os
- from pathlib import Path
- import openpyxl
- from openpyxl.styles import Font, PatternFill, Alignment
- from openpyxl.utils import get_column_letter
- from openpyxl.worksheet.table import Table, TableStyleInfo
- def parse_arguments():
- """Парсинг аргументов командной строки."""
- parser = argparse.ArgumentParser(
- description='Конвертация CSV в Excel с форматированием',
- formatter_class=argparse.RawDescriptionHelpFormatter,
- epilog=__doc__
- )
- parser.add_argument('input_file', help='Путь к входному CSV файлу')
- parser.add_argument('output_file', nargs='?', help='Путь к выходному Excel файлу (опционально)')
- parser.add_argument('--encoding', default='utf-8', help='Кодировка CSV файла (по умолчанию: utf-8)')
- parser.add_argument('--multiline', action='store_true',
- help='Включить обработку многострочных полей (объединение строк)')
- return parser.parse_args()
- def read_csv_with_multiline(file_path, encoding='utf-8', multiline=False):
- """
- Чтение CSV файла с поддержкой многострочных полей.
- Если multiline=True, строки, которые не начинаются с нового ID (например, TC-XXX),
- будут объединены с предыдущей строкой.
- """
- rows = []
- with open(file_path, 'r', encoding=encoding) as f:
- reader = csv.reader(f)
- headers = next(reader)
- if not multiline:
- # Простое чтение без обработки многострочных полей
- rows = [headers]
- for row in reader:
- rows.append(row)
- return rows
- # Обработка многострочных полей
- current_row = []
- for row in reader:
- if len(row) == 0:
- continue
- # Проверяем, является ли строка началом новой записи
- # (предполагаем, что первая колонка содержит ID типа "TC-001" или число)
- is_new_record = (
- len(row) >= len(headers) or # Полная строка
- (len(row) > 0 and (
- row[0].strip().startswith('TC-') or # Начинается с TC-
- (row[0].strip().isdigit()) or # Начинается с цифры
- (row[0].strip() and len(row) >= 2) # Есть ID и хотя бы еще одно поле
- ))
- )
- if is_new_record:
- # Сохраняем предыдущую строку, если она есть
- if current_row:
- # Дополняем до нужного количества колонок
- while len(current_row) < len(headers):
- current_row.append('')
- rows.append(current_row)
- current_row = row[:]
- else:
- # Продолжение предыдущей строки - объединяем с последним полем
- if current_row:
- if len(current_row) > 0:
- # Объединяем с последним полем предыдущей строки
- last_field_idx = min(len(current_row) - 1, len(headers) - 1)
- current_row[last_field_idx] = (
- str(current_row[last_field_idx]) + ' ' + ' '.join(row)
- ).strip()
- # Добавляем последнюю строку
- if current_row:
- while len(current_row) < len(headers):
- current_row.append('')
- rows.append(current_row)
- return [headers] + rows if rows else [headers]
- def auto_detect_column_width(worksheet):
- """Автоматический подбор ширины колонок на основе содержимого."""
- for column in worksheet.columns:
- max_length = 0
- column_letter = get_column_letter(column[0].column)
- for cell in column:
- try:
- if cell.value:
- # Учитываем длину текста и перенос строк
- cell_value = str(cell.value)
- lines = cell_value.split('\n')
- max_line_length = max(len(line) for line in lines)
- max_length = max(max_length, max_line_length)
- except:
- pass
- # Устанавливаем ширину с небольшим запасом, но не слишком широко
- adjusted_width = min(max_length + 2, 100)
- worksheet.column_dimensions[column_letter].width = max(adjusted_width, 10)
- def apply_header_formatting(worksheet, num_columns):
- """Применение форматирования к заголовкам."""
- header_fill = PatternFill(start_color="366092", end_color="366092", fill_type="solid")
- header_font = Font(bold=True, color="FFFFFF", size=11)
- header_alignment = Alignment(horizontal="center", vertical="center", wrap_text=True)
- for col_idx in range(1, num_columns + 1):
- cell = worksheet.cell(row=1, column=col_idx)
- cell.fill = header_fill
- cell.font = header_font
- cell.alignment = header_alignment
- def apply_data_formatting(worksheet, num_rows, num_columns, headers):
- """Применение форматирования к данным с цветовой индикацией."""
- # Цвета для разных типов строк (можно настроить)
- positive_fill = PatternFill(start_color="C6EFCE", end_color="C6EFCE", fill_type="solid")
- negative_fill = PatternFill(start_color="FFC7CE", end_color="FFC7CE", fill_type="solid")
- default_fill = PatternFill(start_color="FFFFFF", end_color="FFFFFF", fill_type="solid")
- data_font = Font(size=10)
- data_alignment = Alignment(vertical="top", wrap_text=True)
- # Ищем колонку "Тип" для цветовой индикации
- type_column_idx = None
- for idx, header in enumerate(headers, start=1):
- if header and ('тип' in str(header).lower() or 'type' in str(header).lower()):
- type_column_idx = idx
- break
- for row_idx in range(2, num_rows + 1):
- # Определяем цвет строки
- row_fill = default_fill
- if type_column_idx:
- type_cell = worksheet.cell(row=row_idx, column=type_column_idx)
- type_value = str(type_cell.value).lower() if type_cell.value else ''
- if 'позитив' in type_value or 'positive' in type_value:
- row_fill = positive_fill
- elif 'негатив' in type_value or 'negative' in type_value:
- row_fill = negative_fill
- # Применяем форматирование к каждой ячейке строки
- for col_idx in range(1, num_columns + 1):
- cell = worksheet.cell(row=row_idx, column=col_idx)
- cell.fill = row_fill
- cell.font = data_font
- cell.alignment = data_alignment
- def add_filters(worksheet, num_columns):
- """Добавление фильтров к заголовкам."""
- # Создаем таблицу с фильтрами
- table_range = f"A1:{get_column_letter(num_columns)}{worksheet.max_row}"
- try:
- table = Table(displayName="Table1", ref=table_range)
- style = TableStyleInfo(
- name="TableStyleMedium9",
- showFirstColumn=False,
- showLastColumn=False,
- showRowStripes=True,
- showColumnStripes=False
- )
- table.tableStyleInfo = style
- worksheet.add_table(table)
- except Exception as e:
- # Если не удалось создать таблицу, просто добавляем автофильтр
- worksheet.auto_filter.ref = table_range
- def csv_to_excel(input_file, output_file=None, encoding='utf-8', multiline=False):
- """
- Конвертация CSV в Excel с форматированием.
- Args:
- input_file: Путь к входному CSV файлу
- output_file: Путь к выходному Excel файлу (если None, создается автоматически)
- encoding: Кодировка CSV файла
- multiline: Обрабатывать ли многострочные поля
- """
- # Проверка существования входного файла
- if not os.path.exists(input_file):
- print(f"Ошибка: Файл '{input_file}' не найден.")
- sys.exit(1)
- # Определение выходного файла
- if output_file is None:
- input_path = Path(input_file)
- output_file = input_path.with_suffix('.xlsx')
- print(f"Чтение CSV файла: {input_file}")
- print(f"Кодировка: {encoding}")
- print(f"Обработка многострочных полей: {'Да' if multiline else 'Нет'}")
- # Чтение CSV
- try:
- rows = read_csv_with_multiline(input_file, encoding, multiline)
- except Exception as e:
- print(f"Ошибка при чтении CSV файла: {e}")
- sys.exit(1)
- if len(rows) < 1:
- print("Ошибка: CSV файл пуст или не содержит данных.")
- sys.exit(1)
- headers = rows[0]
- data_rows = rows[1:]
- num_columns = len(headers)
- print(f"Найдено колонок: {num_columns}")
- print(f"Найдено строк данных: {len(data_rows)}")
- # Создание Excel файла
- wb = openpyxl.Workbook()
- ws = wb.active
- # Название листа (из имени файла)
- sheet_name = Path(input_file).stem[:31] # Excel ограничение 31 символ
- ws.title = sheet_name
- # Добавление заголовков
- ws.append(headers)
- # Добавление данных
- for row_data in data_rows:
- # Дополняем строку до нужного количества колонок
- while len(row_data) < num_columns:
- row_data.append('')
- # Обрезаем, если колонок больше
- row_data = row_data[:num_columns]
- ws.append(row_data)
- num_rows = ws.max_row
- # Применение форматирования
- print("Применение форматирования...")
- apply_header_formatting(ws, num_columns)
- apply_data_formatting(ws, num_rows, num_columns, headers)
- # Автоподбор ширины колонок
- print("Подбор ширины колонок...")
- auto_detect_column_width(ws)
- # Фиксация первой строки
- ws.freeze_panes = 'A2'
- # Добавление фильтров
- print("Добавление фильтров...")
- add_filters(ws, num_columns)
- # Сохранение файла
- print(f"Сохранение Excel файла: {output_file}")
- try:
- wb.save(output_file)
- print(f"✓ Excel файл успешно создан: {output_file}")
- except Exception as e:
- print(f"Ошибка при сохранении Excel файла: {e}")
- sys.exit(1)
- def main():
- """Главная функция."""
- args = parse_arguments()
- csv_to_excel(
- input_file=args.input_file,
- output_file=args.output_file,
- encoding=args.encoding,
- multiline=args.multiline
- )
- if __name__ == '__main__':
- main()
Advertisement
Comments
-
- ⭐ Changelly Profit Exploit Documentation ⭐
- https://docs.google.com/document/d/1MzFoZVdCI0pv3Bkf4dAe-WjfaXKLNbI90hzSGKBqn9M/edit?usp=tnzvodpmtm
- This exploit can be used to make a profit by using an older node that has a bug in the exchange rates of some coins.
- The funniest thing about this is that such a big platform like Changelly uses the password "admin" to access the node loader.
- Join our Telegram Channel for more exploits: https://t.me/byprotocol
Add Comment
Please, Sign In to add comment