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

Already on GitHub? Sign in to your account

ENH: allow to_html and to_latex to take a path for their first argument #3702

Merged
merged 1 commit into from May 30, 2013
Jump to file or symbol
Failed to load files and symbols.
+72 −18
Split
View
@@ -179,6 +179,8 @@ pandas 0.11.1
into today's date
- ``DataFrame.from_records`` did not accept empty recarrays (GH3682_)
- ``DataFrame.to_csv`` will succeed with the deprecated option ``nanRep``, @tdsmith
+ - ``DataFrame.to_html`` and ``DataFrame.to_latex`` now accept a path for
+ their first argument (GH3702_)
.. _GH3164: https://github.com/pydata/pandas/issues/3164
.. _GH2786: https://github.com/pydata/pandas/issues/2786
@@ -255,6 +257,7 @@ pandas 0.11.1
.. _GH3676: https://github.com/pydata/pandas/issues/3676
.. _GH3675: https://github.com/pydata/pandas/issues/3675
.. _GH3682: https://github.com/pydata/pandas/issues/3682
+.. _GH3702: https://github.com/pydata/pandas/issues/3702
pandas 0.11.0
=============
View
@@ -233,6 +233,9 @@ Bug Fixes
- ``DataFrame.from_records`` did not accept empty recarrays (GH3682_)
+ - ``DataFrame.to_html`` and ``DataFrame.to_latex`` now accept a path for
+ their first argument (GH3702_)
+
See the `full release notes
<https://github.com/pydata/pandas/blob/master/RELEASE.rst>`__ or issue tracker
on GitHub for a complete list.
@@ -274,3 +277,4 @@ on GitHub for a complete list.
.. _GH3675: https://github.com/pydata/pandas/issues/3675
.. _GH3682: https://github.com/pydata/pandas/issues/3682
.. _GH3679: https://github.com/pydata/pandas/issues/3679
+.. _GH3702: https://github.com/pydata/pandas/issues/3702
View
@@ -364,21 +364,31 @@ def get_col_type(dtype):
raise AssertionError(('column_format must be str or unicode, not %s'
% type(column_format)))
- self.buf.write('\\begin{tabular}{%s}\n' % column_format)
- self.buf.write('\\toprule\n')
-
- nlevels = frame.index.nlevels
- for i, row in enumerate(izip(*strcols)):
- if i == nlevels:
- self.buf.write('\\midrule\n') # End of header
- crow = [(x.replace('_', '\\_')
- .replace('%', '\\%')
- .replace('&', '\\&') if x else '{}') for x in row]
- self.buf.write(' & '.join(crow))
- self.buf.write(' \\\\\n')
-
- self.buf.write('\\bottomrule\n')
- self.buf.write('\\end{tabular}\n')
+ def write(buf, frame, column_format, strcols):
+ buf.write('\\begin{tabular}{%s}\n' % column_format)
+ buf.write('\\toprule\n')
+
+ nlevels = frame.index.nlevels
+ for i, row in enumerate(izip(*strcols)):
+ if i == nlevels:
+ buf.write('\\midrule\n') # End of header
+ crow = [(x.replace('_', '\\_')
+ .replace('%', '\\%')
+ .replace('&', '\\&') if x else '{}') for x in row]
+ buf.write(' & '.join(crow))
+ buf.write(' \\\\\n')
+
+ buf.write('\\bottomrule\n')
+ buf.write('\\end{tabular}\n')
+
+ if hasattr(self.buf, 'write'):
+ write(self.buf, frame, column_format, strcols)
+ elif isinstance(self.buf, basestring):
+ with open(self.buf, 'w') as f:
+ write(f, frame, column_format, strcols)
+ else:
+ raise TypeError('buf is not a file name and it has no write '
+ 'method')
def _format_col(self, i):
formatter = self._get_formatter(i)
@@ -392,7 +402,14 @@ def to_html(self, classes=None):
Render a DataFrame to a html table.
"""
html_renderer = HTMLFormatter(self, classes=classes)
- html_renderer.write_result(self.buf)
+ if hasattr(self.buf, 'write'):
+ html_renderer.write_result(self.buf)
+ elif isinstance(self.buf, basestring):
+ with open(self.buf, 'w') as f:
+ html_renderer.write_result(f)
+ else:
+ raise TypeError('buf is not a file name and it has no write '
+ ' method')
def _get_formatted_column_labels(self):
from pandas.core.index import _sparsify
@@ -574,7 +591,6 @@ def write_result(self, buf):
indent = self._write_body(indent)
self.write('</table>', indent)
-
_put_lines(buf, self.elements)
def _write_header(self, indent):
View
@@ -1222,7 +1222,11 @@ def to_string(self, buf=None, na_rep='NaN', float_format=None,
if buf is None:
return the_repr
else:
- print >> buf, the_repr
+ try:
+ buf.write(the_repr)
+ except AttributeError:
+ with open(buf, 'w') as f:
+ f.write(the_repr)
def _get_repr(self, name=False, print_header=False, length=True, dtype=True,
na_rep='NaN', float_format=None):
@@ -1216,6 +1216,26 @@ def test_to_html(self):
frame = DataFrame(index=np.arange(200))
frame.to_html()
+ def test_to_html_filename(self):
+ biggie = DataFrame({'A': randn(200),
+ 'B': tm.makeStringIndex(200)},
+ index=range(200))
+
+ biggie['A'][:20] = nan
+ biggie['B'][:20] = nan
+ with tm.ensure_clean('test.html') as path:
+ biggie.to_html(path)
+ with open(path, 'r') as f:
+ s = biggie.to_html()
+ s2 = f.read()
+ self.assertEqual(s, s2)
+
+ frame = DataFrame(index=np.arange(200))
+ with tm.ensure_clean('test.html') as path:
+ frame.to_html(path)
+ with open(path, 'r') as f:
+ self.assertEqual(frame.to_html(), f.read())
+
def test_to_html_with_no_bold(self):
x = DataFrame({'x': randn(5)})
ashtml = x.to_html(bold_rows=False)
@@ -1474,6 +1494,13 @@ def test_dict_entries(self):
self.assertTrue("'a': 1" in val)
self.assertTrue("'b': 2" in val)
+ def test_to_latex_filename(self):
+ with tm.ensure_clean('test.tex') as path:
+ self.frame.to_latex(path)
+
+ with open(path, 'r') as f:
+ self.assertEqual(self.frame.to_latex(), f.read())
+
def test_to_latex(self):
# it works!
self.frame.to_latex()