Mostrando entradas con la etiqueta xlsx. Mostrar todas las entradas
Mostrando entradas con la etiqueta xlsx. Mostrar todas las entradas

sábado, 11 de octubre de 2025

WEBPROPv2 (XII). Mostrar ficheros en un control FastHTML

 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