1

Using pyscript, I am creating an html file that displays a panel Tabulator. Next to this table, there must be two other widgets: a text input, where a user can enter the filename of the file it wants to save, and a button. Such a button, when clicked, should export the table to csv by using pandas to_csv method.

A minimum reproducible example is the following:

<html>
<head>
  <meta charset="utf-8">
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.1/dist/css/bootstrap.min.css">
  <link rel="stylesheet" href="https://unpkg.com/@holoviz/panel@0.14.0/dist/bundled/bootstraptemplate/bootstrap.css">
  <link href="https://unpkg.com/tabulator-tables@5.3.4/dist/css/tabulator.min.css" rel="stylesheet">
  <script type="text/javascript" src="https://unpkg.com/tabulator-tables@5.3.4/dist/js/tabulator.min.js"></script>
  <script type="text/javascript" src="https://cdn.bokeh.org/bokeh/release/bokeh-2.4.2.js"></script>
  <script type="text/javascript" src="https://cdn.bokeh.org/bokeh/release/bokeh-widgets-2.4.2.min.js"></script>
  <script type="text/javascript" src="https://cdn.bokeh.org/bokeh/release/bokeh-tables-2.4.2.min.js"></script>
  <script type="text/javascript" src="https://unpkg.com/@holoviz/panel@0.14.0/dist/panel.min.js"></script>

  <link rel="stylesheet" href="https://pyscript.net/releases/2022.09.1/pyscript.css" />
  <script defer src="https://pyscript.net/releases/2022.09.1/pyscript.js"></script>
</head>

<body>
  <py-config>
    packages = [
      "panel",
      "pandas",
     ]
 </py-config>
  <py-script>
import panel as pn
import pandas as pd
from panel import widgets

pn.extension('tabulator')

pd.options.display.max_columns = 30

table = pn.widgets.Tabulator(pagination='remote', page_size=30)
table.value = pd.DataFrame([[0,0], [1,0]])

inputTableSaveName = pn.widgets.TextInput(name="Filename", margin=10)
button_save_df = pn.widgets.Button(name='Export to csv', button_type='success', width=125, margin=(25, 10, 10, 25))

def save_table_to_file(event):
    if (inputTableSaveName.value == ""): return
    # internally, table.value is a pandas dataframe according to panel docs
    table.value.to_csv(inputTableSaveName.value + ".csv") 

button_save_df.on_click(save_table_to_file)

pn.Row(table, 
      pn.Column(
        pn.Row(inputTableSaveName, button_save_df)
      ))

</body>

</html>

Note as, when I run this code in a Jupyter Notebook it actually works and a file whose name is the one in the input field is generated. However, when opening the html file in my browser and clicking the button, nothing happens and nothing is saved.

EDIT: It seems that the correct approach would be to exploit this trigger. On the other hand, I would like to understand why files cannot be using a more straighforward way, as I would do with vanilla Python.

Andrea Nicolai
  • 349
  • 1
  • 3
  • 12
  • There's definitely other pyscript answers on here about triggering a download. But getting at your questions in the last paragraph of your original post and your 'EDIT', it seems like you are expecting `table.value.to_csv()` to trigger a download when it is meant to save the `.csv` file to the operating system you are running on. It may well be saving to the virtual system running inside your browser. You can check and perhaps still provide a way to download that once it is made. The way you came up with in your 'EDIT' may work, too. – Wayne Mar 17 '23 at 14:39

0 Answers0