Skip to main content

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

Project description

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.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

xx2html-0.18.0rc1.tar.gz (139.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

xx2html-0.18.0rc1-py3-none-any.whl (29.8 kB view details)

Uploaded Python 3

File details

Details for the file xx2html-0.18.0rc1.tar.gz.

File metadata

  • Download URL: xx2html-0.18.0rc1.tar.gz
  • Upload date:
  • Size: 139.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for xx2html-0.18.0rc1.tar.gz
Algorithm Hash digest
SHA256 380e835bbe2061529bbf6a881805e84d45304292cab85ade25947b2ea5066ae1
MD5 bb7a1cd2f0b606697fa05f38821d12a7
BLAKE2b-256 a22a8f8ffae78b2d3ef4c21630345e1297387ddde2a4b75c9e4e327d4d6187d9

See more details on using hashes here.

Provenance

The following attestation bundles were made for xx2html-0.18.0rc1.tar.gz:

Publisher: publish.yml on gocova/xx2html

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file xx2html-0.18.0rc1-py3-none-any.whl.

File metadata

  • Download URL: xx2html-0.18.0rc1-py3-none-any.whl
  • Upload date:
  • Size: 29.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for xx2html-0.18.0rc1-py3-none-any.whl
Algorithm Hash digest
SHA256 f529b18ce89458fa48c182ec513795f898bd9317669ce2df539d8c0f8c1554f4
MD5 d13ba48e242ad4d9a2f981ccc8205ace
BLAKE2b-256 7c0b43914d706cfef612d68a4ef45e5d2b6b161ae616470f5dbb236ee7480c57

See more details on using hashes here.

Provenance

The following attestation bundles were made for xx2html-0.18.0rc1-py3-none-any.whl:

Publisher: publish.yml on gocova/xx2html

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page