Button in grid to export content of table to CSV file

174 views
Skip to first unread message

Lykke Pedersen

unread,
Dec 17, 2024, 1:15:28 AM12/17/24
to py4web
We need to be able to export data from a table to a CSV file. Would it be possible to add a button in the grid so the content of a table can be exported and saved on a local computer when clicking on the button?

Regards,
Lykke

Massimo DiPierro

unread,
Dec 17, 2024, 1:23:54 AM12/17/24
to Lykke Pedersen, py4web

definitively possible. I will post an example tomorrow.


--
You received this message because you are subscribed to the Google Groups "py4web" group.
To unsubscribe from this group and stop receiving emails from it, send an email to py4web+un...@googlegroups.com.
To view this discussion visit https://groups.google.com/d/msgid/py4web/af51c5af-d992-435f-9bf6-a62e6346d3cdn%40googlegroups.com.

Massimo

unread,
Dec 18, 2024, 2:34:36 AM12/18/24
to py4web
Here is a minimalist example:

from yatl.helpers import A
from py4web import *
from py4web.utils.grid import Grid
from py4web.utils.populate import populate
from .common import auth, db

db.define_table("thing", Field("name"))
if db(db.thing).count() == 0:
populate(db.thing, 100)
db.thing.insert
grid_query = db.thing.id > 0

@action("mygrid/<path:path>")
@action.uses("generic.html", auth)
def _(path):
grid = Grid(path, grid_query)
button = A("download as csv", _role="button", _href=URL("mygrid-csv"))
grid.param.header_elements = [lambda: button]
return dict(grid=grid)

@action("mygrid-csv")
def _():
response.headers["Content-Disposition"] = 'attachment; filename="myfile.csv"'
return str(db(grid_query).select())

It is also possible to have a custom filter in the grid and make the download link dependent on the filter. But I need to think some more about that.

Lykke Pedersen

unread,
Dec 23, 2024, 3:27:46 PM12/23/24
to Massimo DiPierro, py4web
Thank you!


tirsdag den 17. december 2024 skrev Massimo DiPierro <massimo....@gmail.com>:

definitively possible. I will post an example tomorrow.


On Mon, Dec 16, 2024, 22:15 Lykke Pedersen <pederse...@gmail.com> wrote:
We need to be able to export data from a table to a CSV file. Would it be possible to add a button in the grid so the content of a table can be exported and saved on a local computer when clicking on the button?

Regards,
Lykke

--
You received this message because you are subscribed to the Google Groups "py4web" group.
To unsubscribe from this group and stop receiving emails from it, send an email to py4web+unsubscribe@googlegroups.com.

Lykke Pedersen

unread,
Jan 29, 2025, 2:25:42 AM1/29/25
to py4web
It would be useful to have the download button as a standard part of the grid, so all content of a selected table can be downloaded as a csv file.
Could that be possible? If people do not need the button they can set it to False just as you can now where you can set the editable, deletable, details and create buttons to True or False.

Like this with the new export button:
grid = Grid(path.....
........
.........
editable=True, deletable=True, details=True, create=True, export=True,
.....
)


mandag den 23. december 2024 kl. 21.27.46 UTC+1 skrev Lykke Pedersen:
Thank you!

tirsdag den 17. december 2024 skrev Massimo DiPierro <massimo....@gmail.com>:

definitively possible. I will post an example tomorrow.


On Mon, Dec 16, 2024, 22:15 Lykke Pedersen <pederse...@gmail.com> wrote:
We need to be able to export data from a table to a CSV file. Would it be possible to add a button in the grid so the content of a table can be exported and saved on a local computer when clicking on the button?

Regards,
Lykke

--
You received this message because you are subscribed to the Google Groups "py4web" group.
To unsubscribe from this group and stop receiving emails from it, send an email to py4web+un...@googlegroups.com.
Message has been deleted
Message has been deleted

Jacinto Parga

unread,
Feb 4, 2025, 1:55:09 AM2/4/25
to py4web
I had made a bypass to download the selected rows of a grid with javascript:

[[extend 'layout-bulma.html']] [[block page_head]] [[end]]

<div class="section">
<h1 class="title is-1">List of selected rows</h1>
[[if grid.action in ['new','details', 'edit']: ]]
<div class="buttons mb-2">
<button class="button is-light" onclick="window.history.back()">
Back
</button>
</div>
[[=grid.render()]] [[else:]]
<div class="buttons mb-2">
<button id="export-button" class="button is-primary is-light">
Export to Excel
</button>
</div>
[[=grid.render()]] [[pass]]
</div>

[[block page_scripts]]
<script>
document
.getElementById("export-button")
.addEventListener("click", function () {
// Get the data
var table = document.querySelector("table.grid-table");
//console.log(table); // Verify if the table exists

if (!table) {
console.error("No table);
return;
}

var rows = Array.from(table.rows).map((row) => {
var cells = Array.from(row.cells);
// Exclude last column (links)
cells.pop();
return cells.map((cell) => {
// Capture the input or select value
var input = cell.querySelector("input, select");
return input ? input.value : cell.innerText;
});
});
// console.log(rows); // Verify captured data

// Send data
fetch("/myserverurl/export_to_excel", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({data: rows}),
})
.then((response) => response.blob())
.then((blob) => {
// Link to download
var url = window.URL.createObjectURL(blob);
var a = document.createElement("a");
a.href = url;
a.download = "tabla_datos_grid.xlsx";
document.body.appendChild(a);
a.click();
a.remove();
});
});
</script>
[[end]]


Massimo

unread,
Feb 8, 2025, 8:59:02 PM2/8/25
to py4web
this is not perfect but....

from py4web.core import action, utcnow, request, response
from py4web.utils.grid import Grid
from yatl.helpers import A

def download(url):
return url + ("&" if "?" in url else "?") + "download"

@action("books/<path:path>")
@action.uses("generic.html")
def _(path):
grid = Grid(path, db.book)
if "download" in request.GET:
response.headers["Content-Type"] = "text/csv"
return str(db(grid.param.query).select())
grid.param.header_elements = [lambda:A("download",_role="button",_href=download(request.url))]
return dict(grid=grid)


It is not perfect because it will ignore the sorting and optional filtering. It will only return in the CSV the rows in the grid.param.query i.e. the second argument of the Grid constructor.
I am considering modifying the grid to make this better.
Reply all
Reply to author
Forward
0 new messages