first commit
This commit is contained in:
1
services/__init__.py
Normal file
1
services/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
# This file is intentionally left blank.
|
||||
59
services/excel_service.py
Normal file
59
services/excel_service.py
Normal file
@@ -0,0 +1,59 @@
|
||||
from openpyxl import load_workbook, Workbook
|
||||
from typing import List
|
||||
from pydantic import BaseModel
|
||||
|
||||
class CellData(BaseModel):
|
||||
value: str
|
||||
font: dict
|
||||
fill: dict
|
||||
border: dict
|
||||
alignment: dict
|
||||
|
||||
class SheetData(BaseModel):
|
||||
name: str
|
||||
cells: List[List[CellData]]
|
||||
|
||||
def read_excel(file_path: str) -> List[SheetData]:
|
||||
workbook = load_workbook(file_path)
|
||||
sheets_data = []
|
||||
|
||||
for sheet in workbook.sheetnames:
|
||||
ws = workbook[sheet]
|
||||
cells_data = []
|
||||
|
||||
for row in ws.iter_rows():
|
||||
row_data = []
|
||||
for cell in row:
|
||||
cell_data = CellData(
|
||||
value=cell.value,
|
||||
font=cell.font.__dict__,
|
||||
fill=cell.fill.__dict__,
|
||||
border=cell.border.__dict__,
|
||||
alignment=cell.alignment.__dict__
|
||||
)
|
||||
row_data.append(cell_data)
|
||||
cells_data.append(row_data)
|
||||
|
||||
sheets_data.append(SheetData(name=sheet, cells=cells_data))
|
||||
|
||||
return sheets_data
|
||||
|
||||
def write_excel(file_path: str, sheets_data: List[SheetData]):
|
||||
workbook = Workbook()
|
||||
|
||||
for sheet_data in sheets_data:
|
||||
ws = workbook.create_sheet(title=sheet_data.name)
|
||||
|
||||
for row_index, row in enumerate(sheet_data.cells):
|
||||
for col_index, cell_data in enumerate(row):
|
||||
cell = ws.cell(row=row_index + 1, column=col_index + 1, value=cell_data.value)
|
||||
cell.font = cell_data.font
|
||||
cell.fill = cell_data.fill
|
||||
cell.border = cell_data.border
|
||||
cell.alignment = cell_data.alignment
|
||||
|
||||
# Remove the default sheet created by Workbook
|
||||
if "Sheet" in workbook.sheetnames:
|
||||
del workbook["Sheet"]
|
||||
|
||||
workbook.save(file_path)
|
||||
49
services/translator.py
Normal file
49
services/translator.py
Normal file
@@ -0,0 +1,49 @@
|
||||
from typing import List
|
||||
import openpyxl
|
||||
from googletrans import Translator
|
||||
from pydantic import BaseModel
|
||||
|
||||
class Cell(BaseModel):
|
||||
value: str
|
||||
row: int
|
||||
column: int
|
||||
|
||||
class Sheet(BaseModel):
|
||||
name: str
|
||||
cells: List[Cell]
|
||||
|
||||
class ExcelTranslator:
|
||||
def __init__(self, src_language: str, dest_language: str):
|
||||
self.translator = Translator()
|
||||
self.src_language = src_language
|
||||
self.dest_language = dest_language
|
||||
|
||||
def translate_text(self, text: str) -> str:
|
||||
translated = self.translator.translate(text, src=self.src_language, dest=self.dest_language)
|
||||
return translated.text
|
||||
|
||||
def translate_sheet(self, sheet: Sheet) -> Sheet:
|
||||
translated_cells = []
|
||||
for cell in sheet.cells:
|
||||
translated_value = self.translate_text(cell.value)
|
||||
translated_cells.append(Cell(value=translated_value, row=cell.row, column=cell.column))
|
||||
return Sheet(name=sheet.name, cells=translated_cells)
|
||||
|
||||
def translate_workbook(self, file_path: str) -> None:
|
||||
workbook = openpyxl.load_workbook(file_path)
|
||||
translated_workbook = openpyxl.Workbook()
|
||||
|
||||
for sheet_name in workbook.sheetnames:
|
||||
sheet = workbook[sheet_name]
|
||||
translated_sheet = translated_workbook.create_sheet(title=sheet_name)
|
||||
|
||||
for row in sheet.iter_rows():
|
||||
for cell in row:
|
||||
translated_value = self.translate_text(cell.value) if cell.value else ''
|
||||
translated_sheet[cell.coordinate].value = translated_value
|
||||
# Preserve cell formatting
|
||||
if cell.has_style:
|
||||
translated_sheet[cell.coordinate]._style = cell._style
|
||||
|
||||
translated_file_path = file_path.replace('.xlsx', '_translated.xlsx')
|
||||
translated_workbook.save(translated_file_path)
|
||||
Reference in New Issue
Block a user