Saltar al contenido

Aplicar la clase CSS a Pandas DataFrame usando to_html

Solución:

Pandas to_html simplemente genera una cadena grande que contiene el marcado de la tabla HTML. El argumento de clases es un manejador de conveniencia para dar el <table> a clase atributo al que se hará referencia en un creado previamente Documento CSS que le da estilo. Por lo tanto, incorpore to_html en una compilación de documento HTML más amplia que hace referencia a un CSS externo.

Curiosamente, to_html agrega clases duales <table class="dataframe mystyle"> que se puede hacer referencia en CSS individualmente, .dataframe {...} .mystyle{...}, o juntos .dataframe.mystyle {...}. A continuación se demuestra con datos aleatorios.

Datos

import pandas as pd
import numpy as np

pd.set_option('display.width', 1000)
pd.set_option('colheader_justify', 'center')

np.random.seed(6182018)
demo_df = pd.DataFrame({'date': np.random.choice(pd.date_range('2018-01-01', '2018-06-18', freq='D'), 50),
                        'analysis_tool': np.random.choice(['pandas', 'r', 'julia', 'sas', 'stata', 'spss'],50),              
                        'database': np.random.choice(['postgres', 'mysql', 'sqlite', 'oracle', 'sql server', 'db2'],50), 
                        'os': np.random.choice(['windows 10', 'ubuntu', 'mac os', 'android', 'ios', 'windows 7', 'debian'],50), 
                        'num1': np.random.randn(50)*100,
                        'num2': np.random.uniform(0,1,50),                   
                        'num3': np.random.randint(100, size=50),
                        'bool': np.random.choice([True, False], 50)
                       },
                        columns=['date', 'analysis_tool', 'num1', 'database', 'num2', 'os', 'num3', 'bool']
          )


print(demo_df.head(10))
#      date    analysis_tool     num1      database     num2        os      num3  bool 
# 0 2018-04-21     pandas     153.474246       mysql  0.658533         ios   74    True
# 1 2018-04-13        sas     199.461669      sqlite  0.656985   windows 7   11   False
# 2 2018-06-09      stata      12.918608      oracle  0.495707     android   25   False
# 3 2018-04-24       spss      88.562111  sql server  0.113580   windows 7   42   False
# 4 2018-05-05       spss     110.231277      oracle  0.660977  windows 10   76    True
# 5 2018-04-05        sas     -68.140295  sql server  0.346894  windows 10    0    True
# 6 2018-05-07      julia      12.874660    postgres  0.195217         ios   79    True
# 7 2018-01-22          r     189.410928       mysql  0.234815  windows 10   56   False
# 8 2018-01-12     pandas    -111.412564  sql server  0.580253      debian   30   False
# 9 2018-04-12          r      38.963967    postgres  0.266604   windows 7   46   False

CSS (guardar como df_style.css)

/* includes alternating gray and white with on-hover color */

.mystyle {
    font-size: 11pt; 
    font-family: Arial;
    border-collapse: collapse; 
    border: 1px solid silver;

}

.mystyle td, th {
    padding: 5px;
}

.mystyle tr:nth-child(even) {
    background: #E0E0E0;
}

.mystyle tr:hover {
    background: silver;
    cursor: pointer;
}

Pandas

pd.set_option('colheader_justify', 'center')   # FOR TABLE <th>

html_string = '''
<html>
  <head><title>HTML Pandas Dataframe with CSS</title></head>
  <link rel="stylesheet" type="text/css" href="https://foroayuda.es/df_style.css"/>
  <body>
    {table}
  </body>
</html>.
'''

# OUTPUT AN HTML FILE
with open('myhtml.html', 'w') as f:
    f.write(html_string.format(table=demo_df.to_html(classes="mystyle")))

PRODUCCIÓN

HTML (hace referencia a df_style.css, asumido en el mismo directorio; vea el argumento de clase en la tabla)

<html>
  <head><title>HTML Pandas Dataframe with CSS</title></head>
  <link rel="stylesheet" type="text/css" href="https://foroayuda.es/df_style.css"/>
  <body>
    <table border="1">
  <thead>
    <tr>
      <th></th>
      <th>date</th>
      <th>analysis_tool</th>
      <th>num1</th>
      <th>database</th>
      <th>num2</th>
      <th>os</th>
      <th>num3</th>
      <th>bool</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <th>0</th>
      <td>2018-04-21</td>
      <td>pandas</td>
      <td>153.474246</td>
      <td>mysql</td>
      <td>0.658533</td>
      <td>ios</td>
      <td>74</td>
      <td>True</td>
    </tr>
    <tr>
      <th>1</th>
      <td>2018-04-13</td>
      <td>sas</td>
      <td>199.461669</td>
      <td>sqlite</td>
      <td>0.656985</td>
      <td>windows 7</td>
      <td>11</td>
      <td>False</td>
    </tr>
    <tr>
      <th>2</th>
      <td>2018-06-09</td>
      <td>stata</td>
      <td>12.918608</td>
      <td>oracle</td>
      <td>0.495707</td>
      <td>android</td>
      <td>25</td>
      <td>False</td>
    </tr>
    <tr>
      <th>3</th>
      <td>2018-04-24</td>
      <td>spss</td>
      <td>88.562111</td>
      <td>sql server</td>
      <td>0.113580</td>
      <td>windows 7</td>
      <td>42</td>
      <td>False</td>
    </tr>
    <tr>
      <th>4</th>
      <td>2018-05-05</td>
      <td>spss</td>
      <td>110.231277</td>
      <td>oracle</td>
      <td>0.660977</td>
      <td>windows 10</td>
      <td>76</td>
      <td>True</td>
    </tr>
    ...
  </tbody>
</table>
  </body>
</html>

Salida HTML

Esencialmente, pandas.to_html () solo exporta una tabla HTML simple. Puede insertar la tabla donde desee en el cuerpo y controlar el estilo a través de CSS en la sección de estilo.

<html>
<head>
<style> 
  table, th, td {{font-size:10pt; border:1px solid black; border-collapse:collapse; text-align:left;}}
  th, td {{padding: 5px;}}
</style>
</head>
<body>
{
  pandas.to_html()
}
</body>
</html>

Encontré la forma más precisa y, francamente, más fácil de hacerlo es omitir el estilo, to_html (), etc. y convertir el DF en un diccionario usando el método df.to_dict ().

Específicamente, lo que me dio problemas fue mostrar el html de pandas con estilo en un correo electrónico de Outlook, ya que simplemente no se mostraba correctamente con el desorden css que estaban produciendo los pandas.

iterar sobre el dict y generar el html allí simplemente envolviendo claves / valores en las etiquetas que necesita, agregando clases, etc. y concatenar todo esto en una sola cadena. Luego pegue esta cadena en una plantilla preparada con un CSS predefinido.

Por conveniencia, encontré que es útil exportar el mismo df dos veces, usando .to_dict () y to_dict (‘index’) para completar primero las columnas y luego avanzar fila por fila. Alternativamente, solo tenga una lista de nombres de columna relevantes.

dict_data = [df.to_dict(), df.to_dict('index')]

return_str="<table><tr>"

for key in dict_data[0].keys():
    return_str = return_str + '<th>' + key + '</th>'

return_str = return_str + '</tr>'

for key in dict_data[1].keys():
    return_str = return_str + '<tr><th>' + key + '</th>'
    for subkey in dict_data[1][key]:
        return_str = return_str + '<td>' + dict_data[1][key][subkey] + '</td>'

return_str = return_str + '</tr></table>'

y luego return_str entra en la plantilla.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *