Veamos el código que ejecuta en python un uvicorn y muestra el fichero que le decimos:
El truco está en utilizar libreoffice para transformar los ficheros de ofimática ( ods,odt, xls,xlsx, doc,docx ..) a html y mostrar el html generado.
Si el fichero es grande puede enlentecer mucho la carga, conversión y muestra
import base64 import mimetypes from fasthtml import common as fh import uvicorn from pathlib import Path import subprocess import shutil app = fh.FastHTML() def convertir_a_html(path: Path) -> Path | None: """Convierte el archivo a HTML usando LibreOffice y devuelve la ruta resultante.""" output_dir = Path("/tmp") result = subprocess.run( ["libreoffice", "--headless", "--convert-to", "html", str(path), "--outdir", str(output_dir)], stdout=subprocess.PIPE, stderr=subprocess.PIPE ) if result.returncode == 0: html_file = output_dir / (path.stem + ".html") if html_file.exists(): return html_file return None def generar_viewer(path: Path): mime_type, _ = mimetypes.guess_type(str(path)) if not mime_type: mime_type = "application/octet-stream" data = path.read_bytes() b64 = base64.b64encode(data).decode("utf-8") # Imágenes if mime_type.startswith("image/"): return fh.Img(src=f"data:{mime_type};base64,{b64}", cls="img-fluid rounded shadow", alt=path.name) # PDF if mime_type == "application/pdf": return fh.Iframe(src=f"data:{mime_type};base64,{b64}", style="width:100%; height:90vh;", cls="border rounded shadow-sm", title=path.name) # Texto if mime_type.startswith("text/"): content = data.decode("utf-8", errors="ignore") return fh.Pre(content, cls="bg-light p-3 border rounded") # ODS / XLSX / DOCX — convertir a HTML convertible_types = { "application/vnd.oasis.opendocument.spreadsheet", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", "application/vnd.openxmlformats-officedocument.wordprocessingml.document", "application/vnd.oasis.opendocument.text", 'application/msword', 'application/vnd.ms-excel', } if mime_type in convertible_types: html_file = convertir_a_html(path) if html_file: html_content = html_file.read_text(encoding="utf-8", errors="ignore") return fh.Div(fh.NotStr(html_content), cls="border p-2 bg-white shadow-sm") # Otros: ofrecer descarga return fh.Div( fh.P("El archivo no puede mostrarse directamente en el navegador.", cls="text-muted"), fh.A("Descargar archivo", href=f"data:{mime_type};base64,{b64}", download=path.name, cls="btn btn-primary mt-3"), cls="text-center" ) @app.get("/mostrarfichero") async def mostrar_fichero(req): path_param = req.query_params.get("pathfichero") if not path_param: return fh.Html(fh.Body(fh.H4("⚠️ Falta el parámetro 'pathfichero'"))) path = Path(path_param) if not path.exists(): return fh.Html(fh.Body(fh.H4(f"❌ Archivo no encontrado: {path_param}"))) viewer = generar_viewer(path) return fh.Html( fh.Head(fh.Link(rel="stylesheet", href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css")), fh.Body( fh.Div( fh.H3(f"Mostrando: {path.name}", cls="text-center my-4"), viewer, cls="container" ) ) ) if __name__ == "__main__": print("🚀 Abre en el navegador: http://localhost:8000/mostrarfichero?pathfichero=/home/edu/kk/ODS01.ods") uvicorn.run(app, host="0.0.0.0", port=8000)
Y para ejecutarlo, tal como se dice en as últimas sentencias, ejecutamos el programa python desde visual studio code y en un navegador apuntamos a esa ruta donde en /home/kk/OSD01.ods está un fichero de hoja de cálculo
http://localhost:8000/mostrarfichero?pathfichero=/home/edu/kk/ODS01.ods
No hay comentarios :
Publicar un comentario