Good looking Table for a Streamlit application... is anyone still using aggrid?

Hi, I am a long time fan of Streamlit.
Recently I have been building my company’s main internal data application using Streamlit, highlighting the benefits of using Python and being able to ship faster.
Still, when I am presenting the application to other stakeholders - like board members - the application is just “not good looking”, especially the tables.

Having a good looking table like “Aggrid” would solve 99% of the “ugliness” of streamlit data_editor / dataframe, but aggrid is simply buggy and not maintained.

Has anyone dealt with such scenario? How did you make the tables “beautiful”?

Note that I know the purpose of Streamlit, which is to make data applications easier to build, but it would make my life 100% better if I could shift the focus of my data application to the actual analysis, and not the “poor” design of dataframes.

Thanks a lot, João

Can you post a sample table that is good-looking?

I tried showing the datatables in streamlit, does this looks good?

1 Like

Hi Ferdy, thanks for the reply!
Yes it does, how did you do it?

I am thinking on using something like tailwind css to create some table component. The data editor seems a little raw in general.
this is a very beautiful example. Having something like this on streamlit would be incredible.

First we need an html template that can take a url that contains a csv.


<!DOCTYPE html>
<html lang="en">
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Beautiful Table with CSV Data</title>

        <!-- Include DataTables CSS and JS -->
        <link rel="stylesheet" type="text/css" href="">
        <script type="text/javascript" charset="utf8" src=""></script>
        <script type="text/javascript" charset="utf8" src=""></script>

        <!-- Table container -->
        <div style="width: 80%; margin: 20px 0 0 0; float: left;">
            <table id="beautifulTable" class="display">
                    <!-- Headers will be loaded dynamically from CSV -->
                    <!-- Data will be loaded dynamically from CSV -->


        <!-- Custom CSS for centering -->
            .center { text-align: center; }
            th.dt-center, td.dt-center { text-align: center; }

        <!-- Initialize DataTable -->
            $(document).ready(function() {
                // Load data from CSV
                    type: "GET",
                    url: "{{ data_source_url }}",
                    dataType: "text",
                    success: function(data) {

                function processData(allText) {
                    var allTextLines = allText.split(/\r\n|\n/);
                    var headers = allTextLines[0].split(',');
                    var lines = [];

                    // Generate table headers
                    var headerHTML = '<tr>';
                    for (var i = 0; i < headers.length; i++) {
                        headerHTML += '<th class="center">' + headers[i] + '</th>';
                    headerHTML += '</tr>';
                    $('#beautifulTable thead').html(headerHTML);

                    for (var i = 1; i < allTextLines.length; i++) {
                        var data = allTextLines[i].split(',');
                        if (data.length == headers.length) {
                            var tarr = [];
                            for (var j = 0; j < headers.length; j++) {

                    // Populate DataTable
                        data: lines,
                        columns: {
                            return { title: header, className: "center" };
                        "lengthMenu": [10, 20, 50, 100],
                        "autoWidth": true // Enable auto column width adjustment

import streamlit as st
from jinja2 import Environment, FileSystemLoader


def render_html_template(url, table_template, width=1200, height=600, scrolling=True):
    # Load Jinja environment
    env = Environment(loader=FileSystemLoader('.'))
    template = env.get_template(table_template)

    # Render the template with the provided URL
    rendered_html = template.render(data_source_url=url)

    # Render the HTML content
    st.components.v1.html(rendered_html, width=width, height=height, scrolling=scrolling)

def main():
    template = 'table_template.html'

    st.title('Miles per Gallon Dataset')
    url = ''
    render_html_template(url, template, width=1300, height=600, scrolling=True)

if __name__ == '__main__':

Input your url here. Be careful on table size.

url = ''

You can customize the table by modifying the html template.


Very nice table, can I use a similar method to display pandas’ dataframe?