Skip to content

API: Add Styler.to_html, for saving output to HTML file #40312

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 42 commits into from
May 26, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
4799d86
json on styler
attack68 Sep 28, 2020
2eb5702
Merge remote-tracking branch 'upstream/master' into json_styler
attack68 Feb 24, 2021
a0bcbd1
meth: to_html
attack68 Feb 25, 2021
5135a91
Merge remote-tracking branch 'upstream/master' into json_styler
attack68 Mar 8, 2021
3e9903d
remove_json
attack68 Mar 8, 2021
766b758
html tests
attack68 Mar 8, 2021
e558a6a
html tests
attack68 Mar 8, 2021
00f8a6e
Merge remote-tracking branch 'upstream/master' into styler_to_html
attack68 Mar 12, 2021
2c440ed
Merge remote-tracking branch 'upstream/master' into styler_to_html
attack68 Mar 21, 2021
dd6785e
to_html parameters
attack68 Mar 22, 2021
e8d0629
Merge remote-tracking branch 'upstream/master' into styler_to_html
attack68 Apr 1, 2021
42cefe6
remove formatting code fro to_html
attack68 Apr 1, 2021
80097cb
Merge remote-tracking branch 'upstream/master' into styler_to_html
attack68 Apr 14, 2021
10f007c
reduce pr scope to simpler initial additions
attack68 Apr 14, 2021
c876bf6
move html tests to html
attack68 Apr 14, 2021
1e5061a
Merge remote-tracking branch 'upstream/master' into styler_to_html
attack68 Apr 15, 2021
130fba4
use dedent
attack68 Apr 15, 2021
5079922
Merge remote-tracking branch 'upstream/master' into styler_to_html
attack68 Apr 18, 2021
339ca37
Merge remote-tracking branch 'upstream/master' into styler_to_html
attack68 Apr 20, 2021
c701d3d
Merge remote-tracking branch 'upstream/master' into styler_to_html
attack68 Apr 21, 2021
3f074aa
Merge remote-tracking branch 'upstream/master' into styler_to_html
attack68 Apr 22, 2021
e1818f2
refactor template inheritance
attack68 Apr 23, 2021
eeeaf54
template inheritance
attack68 Apr 23, 2021
b14e7af
improve tests
attack68 Apr 24, 2021
2a48f4d
Merge remote-tracking branch 'upstream/master' into styler_to_html
attack68 Apr 26, 2021
dda33de
Merge remote-tracking branch 'upstream/master' into styler_to_html
attack68 Apr 26, 2021
b55db71
Merge remote-tracking branch 'upstream/master' into styler_to_html
attack68 Apr 27, 2021
a5c0ec7
Merge remote-tracking branch 'upstream/master' into styler_to_html
attack68 Apr 29, 2021
1d3ba20
Merge remote-tracking branch 'upstream/master' into styler_to_html
attack68 May 1, 2021
4e4c76d
Merge remote-tracking branch 'upstream/master' into styler_to_html
attack68 May 6, 2021
f43961d
Merge remote-tracking branch 'upstream/master' into styler_to_html
attack68 May 7, 2021
a3ce1ef
make keyword only: simialar to Styler.to_latex()
attack68 May 7, 2021
8899fb5
Merge remote-tracking branch 'upstream/master' into styler_to_html
attack68 May 9, 2021
8375f99
Merge remote-tracking branch 'upstream/master' into styler_to_html
attack68 May 14, 2021
f5b84fa
Merge remote-tracking branch 'upstream/master' into styler_to_html
attack68 May 17, 2021
66ba741
Merge remote-tracking branch 'upstream/master' into styler_to_html
attack68 May 18, 2021
d2e2731
Merge remote-tracking branch 'upstream/master' into styler_to_html
attack68 May 20, 2021
792ab44
Merge remote-tracking branch 'upstream/master' into styler_to_html
attack68 May 22, 2021
2575058
doc comments
attack68 May 22, 2021
c0bc29c
change default doctyoe_html from True to False
attack68 May 22, 2021
489030f
Merge remote-tracking branch 'upstream/master' into styler_to_html
attack68 May 24, 2021
2d996ce
whats new
attack68 May 24, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion doc/source/whatsnew/v1.3.0.rst
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ properly format HTML and eliminate some inconsistencies (:issue:`39942` :issue:`
One also has greater control of the display through separate sparsification of the index or columns, using the new 'styler' options context (:issue:`41142`).

We have added an extension to allow LaTeX styling as an alternative to CSS styling and a method :meth:`.Styler.to_latex`
which renders the necessary LaTeX format including built-up styles.
which renders the necessary LaTeX format including built-up styles. An additional file io function :meth:`Styler.to_html` has been added for convenience (:issue:`40312`).

Documentation has also seen major revisions in light of new features (:issue:`39720` :issue:`39317` :issue:`40493`)

Expand Down
68 changes: 68 additions & 0 deletions pandas/io/formats/style.py
Original file line number Diff line number Diff line change
Expand Up @@ -739,6 +739,74 @@ def to_latex(

return save_to_buffer(latex, buf=buf, encoding=encoding)

def to_html(
self,
buf: FilePathOrBuffer[str] | None = None,
*,
table_uuid: str | None = None,
table_attributes: str | None = None,
encoding: str | None = None,
doctype_html: bool = False,
exclude_styles: bool = False,
):
"""
Write Styler to a file, buffer or string in HTML-CSS format.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

add a versionadded 1.3

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done


.. versionadded:: 1.3.0

Parameters
----------
buf : str, Path, or StringIO-like, optional, default None
Buffer to write to. If ``None``, the output is returned as a string.
table_uuid: str, optional
Id attribute assigned to the <table> HTML element in the format:

``<table id="T_<table_uuid>" ..>``

If not given uses Styler's initially assigned value.
table_attributes: str, optional
Attributes to assign within the `<table>` HTML element in the format:

``<table .. <table_attributes> >``

If not given defaults to Styler's preexisting value.
encoding : str, optional
Character encoding setting for file output, and HTML meta tags,
defaults to "utf-8" if None.
doctype_html : bool, default False
Whether to output a fully structured HTML file including all
HTML elements, or just the core ``<style>`` and ``<table>`` elements.
exclude_styles : bool, default False
Whether to include the ``<style>`` element and all associated element
``class`` and ``id`` identifiers, or solely the ``<table>`` element without
styling identifiers.

Returns
-------
str or None
If `buf` is None, returns the result as a string. Otherwise returns `None`.

See Also
--------
DataFrame.to_html: Write a DataFrame to a file, buffer or string in HTML format.
"""
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

add a See Also back to DataFrame.to_html (or are we deprecating this in this PR?)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can't deprecate yet. working towards but needs a gap analysis: there are some things mising.

if table_uuid:
self.set_uuid(table_uuid)

if table_attributes:
self.set_table_attributes(table_attributes)

# Build HTML string..
html = self.render(
exclude_styles=exclude_styles,
encoding=encoding if encoding else "utf-8",
doctype_html=doctype_html,
)

return save_to_buffer(
html, buf=buf, encoding=(encoding if buf is not None else None)
)

def set_td_classes(self, classes: DataFrame) -> Styler:
"""
Set the DataFrame of strings added to the ``class`` attribute of ``<td>``
Expand Down
84 changes: 15 additions & 69 deletions pandas/io/formats/templates/html.tpl
Original file line number Diff line number Diff line change
@@ -1,70 +1,16 @@
{# Update the template_structure.html document too #}
{%- block before_style -%}{%- endblock before_style -%}
{% block style %}
<style type="text/css">
{% block table_styles %}
{% for s in table_styles %}
#T_{{uuid}} {{s.selector}} {
{% for p,val in s.props %}
{{p}}: {{val}};
{% endfor %}
}
{% endfor %}
{% endblock table_styles %}
{% block before_cellstyle %}{% endblock before_cellstyle %}
{% block cellstyle %}
{% for s in cellstyle %}
{% for selector in s.selectors %}{% if not loop.first %}, {% endif %}#T_{{uuid}}{{selector}}{% endfor %} {
{% for p,val in s.props %}
{{p}}: {{val}};
{% endfor %}
}
{% endfor %}
{% endblock cellstyle %}
</style>
{% endblock style %}
{% block before_table %}{% endblock before_table %}
{% block table %}
<table id="T_{{uuid}}"{% if table_attributes %} {{table_attributes}}{% endif %}>
{% block caption %}
{% if caption %}
<caption>{{caption}}</caption>
{# Update the template_structure.html documentation too #}
{% if doctype_html %}
<!DOCTYPE html>
<html>
<head>
<meta charset="{{encoding}}">
{% if not exclude_styles %}{% include "html_style.tpl" %}{% endif %}
</head>
<body>
{% include "html_table.tpl" %}
</body>
</html>
{% elif not doctype_html %}
{% if not exclude_styles %}{% include "html_style.tpl" %}{% endif %}
{% include "html_table.tpl" %}
{% endif %}
{% endblock caption %}
{% block thead %}
<thead>
{% block before_head_rows %}{% endblock %}
{% for r in head %}
{% block head_tr scoped %}
<tr>
{% for c in r %}
{% if c.is_visible != False %}
<{{c.type}} class="{{c.class}}" {{c.attributes}}>{{c.value}}</{{c.type}}>
{% endif %}
{% endfor %}
</tr>
{% endblock head_tr %}
{% endfor %}
{% block after_head_rows %}{% endblock %}
</thead>
{% endblock thead %}
{% block tbody %}
<tbody>
{% block before_rows %}{% endblock before_rows %}
{% for r in body %}
{% block tr scoped %}
<tr>
{% for c in r %}
{% if c.is_visible != False %}
<{{c.type}} {% if c.id is defined -%} id="T_{{uuid}}{{c.id}}" {%- endif %} class="{{c.class}}" {{c.attributes}}>{{c.display_value}}</{{c.type}}>
{% endif %}
{% endfor %}
</tr>
{% endblock tr %}
{% endfor %}
{% block after_rows %}{% endblock after_rows %}
</tbody>
{% endblock tbody %}
</table>
{% endblock table %}
{% block after_table %}{% endblock after_table %}
24 changes: 24 additions & 0 deletions pandas/io/formats/templates/html_style.tpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
{%- block before_style -%}{%- endblock before_style -%}
{% block style %}
<style type="text/css">
{% block table_styles %}
{% for s in table_styles %}
#T_{{uuid}} {{s.selector}} {
{% for p,val in s.props %}
{{p}}: {{val}};
{% endfor %}
}
{% endfor %}
{% endblock table_styles %}
{% block before_cellstyle %}{% endblock before_cellstyle %}
{% block cellstyle %}
{% for s in cellstyle %}
{% for selector in s.selectors %}{% if not loop.first %}, {% endif %}#T_{{uuid}}{{selector}}{% endfor %} {
{% for p,val in s.props %}
{{p}}: {{val}};
{% endfor %}
}
{% endfor %}
{% endblock cellstyle %}
</style>
{% endblock style %}
61 changes: 61 additions & 0 deletions pandas/io/formats/templates/html_table.tpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
{% block before_table %}{% endblock before_table %}
{% block table %}
{% if exclude_styles %}
<table>
{% else %}
<table id="T_{{uuid}}"{% if table_attributes %} {{table_attributes}}{% endif %}>
{% endif %}
{% block caption %}
{% if caption %}
<caption>{{caption}}</caption>
{% endif %}
{% endblock caption %}
{% block thead %}
<thead>
{% block before_head_rows %}{% endblock %}
{% for r in head %}
{% block head_tr scoped %}
<tr>
{% if exclude_styles %}
{% for c in r %}
{% if c.is_visible != False %}
<{{c.type}} {{c.attributes}}>{{c.value}}</{{c.type}}>
{% endif %}
{% endfor %}
{% else %}
{% for c in r %}
{% if c.is_visible != False %}
<{{c.type}} class="{{c.class}}" {{c.attributes}}>{{c.value}}</{{c.type}}>
{% endif %}
{% endfor %}
{% endif %}
</tr>
{% endblock head_tr %}
{% endfor %}
{% block after_head_rows %}{% endblock %}
</thead>
{% endblock thead %}
{% block tbody %}
<tbody>
{% block before_rows %}{% endblock before_rows %}
{% for r in body %}
{% block tr scoped %}
<tr>
{% if exclude_styles %}
{% for c in r %}{% if c.is_visible != False %}
<{{c.type}} {{c.attributes}}>{{c.display_value}}</{{c.type}}>
{% endif %}{% endfor %}
{% else %}
{% for c in r %}{% if c.is_visible != False %}
<{{c.type}} {% if c.id is defined -%} id="T_{{uuid}}{{c.id}}" {%- endif %} class="{{c.class}}" {{c.attributes}}>{{c.display_value}}</{{c.type}}>
{% endif %}{% endfor %}
{% endif %}
</tr>
{% endblock tr %}
{% endfor %}
{% block after_rows %}{% endblock after_rows %}
</tbody>
{% endblock tbody %}
</table>
{% endblock table %}
{% block after_table %}{% endblock after_table %}
Loading