Skip to content

gocova/xx2html

Repository files navigation

xx2html

PyPI Version CI License Buy Me a Coffee

xx2html converts Excel workbooks (.xlsx) into a single HTML file while preserving:

  • Cell formatting and styles
  • Conditional formatting classes (via condif2css)
  • Worksheet link behavior
  • Embedded worksheet images and in-cell rich-value images

Repository: https://github.com/gocova/xx2html
Issues: https://github.com/gocova/xx2html/issues

Installation

pip install xx2html

Usage

from xx2html import apply_openpyxl_patches, create_xlsx_transform

# Explicit entrypoint. Patches are also applied automatically on import.
apply_openpyxl_patches()

transform = create_xlsx_transform(
    sheet_html=(
        '<section id="{enc_sheet_name}" data-sheet-name="{sheet_name}">'
        "{table_generated_html}"
        "</section>"
    ),
    sheetname_html='<a class="sheet-nav" href="#{enc_sheet_name}">{sheet_name}</a>',
    index_html=(
        "<!doctype html><html><head>"
        "{fonts_html}{core_css_html}{user_css_html}{generated_css_html}"
        "{generated_incell_css_html}{conditional_css_html}"
        '</head><body data-source="{source_filename}">{sheets_names_generated_html}{sheets_generated_html}'
        "{safari_js}</body></html>"
    ),
    fonts_html="",
    core_css="",
    user_css="",
    safari_js="",
    apply_cf=True,
    max_sheets=3,   # optional preview limit
    max_rows=200,   # optional preview limit per sheet
    max_cols=20,    # optional preview limit per sheet
    raise_on_error=False,
)

ok, err = transform("input.xlsx", "output.html", "en_US")
if not ok:
    raise RuntimeError(err)

API Map

Public API (xx2html):

  • apply_openpyxl_patches() -> None
    • Applies required openpyxl monkey patches (idempotent).
  • create_xlsx_transform(...) -> Callable[[str, str, str], tuple[bool, str | None]]
    • Returns a transformer callable with signature (source_xlsx, dest_html, locale).
    • Returns (True, None) on success, (False, "<error repr>") on failure.
    • Optional preview controls:
      • max_sheets: convert only the first N visible sheets.
      • max_rows: convert only the first N rows per included sheet.
      • max_cols: convert only the first N columns per included sheet.
    • Optional error mode:
      • raise_on_error=True raises the original exception instead of returning (False, ...).

Core helpers (xx2html.core, useful for advanced integrations):

  • get_worksheet_contents(...) -> WorksheetContents
  • cova_render_table(worksheet_contents) -> str
  • get_incell_images_refs(archive) -> tuple[dict[str, str], Exception | None]
  • get_incell_css(...) -> str
  • apply_cf_styles(html, cf_style_relations) -> str
  • update_links(html, encoded_sheet_names, ...) -> str

Template Placeholders

sheet_html requires:

  • {enc_sheet_name}
  • {sheet_name}
  • {table_generated_html}

sheetname_html requires:

  • {enc_sheet_name}
  • {sheet_name}

index_html requires:

  • {sheets_generated_html}
  • {sheets_names_generated_html}
  • {source_filename}
  • {fonts_html}
  • {core_css_html}
  • {user_css_html}
  • {generated_css_html}
  • {generated_incell_css_html}
  • {conditional_css_html}

index_html optional:

  • {safari_js}
    • If omitted while safari_js is non-empty, xx2html logs a warning and skips injection.

Generated output also includes:

  • <meta name="generator" content="xx2html {version}"> in <head>
  • <!-- Generated by xx2html {version} --> as the first node in <body>

Monkey Patching Behavior

xx2html relies on an openpyxl monkey patch to carry rich-value metadata used for in-cell images.

  • The patch is applied automatically when xx2html.core is imported.
  • The explicit API entrypoint is apply_openpyxl_patches().
  • xx2html validates the openpyxl major/minor version before patching.
    • Set XX2HTML_ALLOW_UNSUPPORTED_OPENPYXL=1 to bypass the guard.

Development

pdm sync --group dev --frozen-lockfile
python3 tests/scripts/generate_fixtures.py
pdm run python -m compileall src tests
ruff check src tests
mypy src/xx2html
pdm run pytest

Release

  • Stable releases are tag-driven and use SemVer tags: vMAJOR.MINOR.PATCH (for example v1.2.3).
  • Push the tag to GitHub; the publish workflow builds from SCM metadata and publishes with PyPI Trusted Publishing.

License

xx2html is dual-licensed under MIT or Apache-2.0.

About

Convert XLSX workbooks to single styled HTML file with support for conditional formatting and in-cell images.

Resources

License

Apache-2.0, MIT licenses found

Licenses found

Apache-2.0
LICENSE_APACHE
MIT
LICENSE_MIT

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages