Thanks again for the awesome plugin. I noticed that, whenever I use the Download Table Databuilt-in function in Tabulator 3.4 with a table having remote pagination, the resulting file (be it CSV, JSON or XLSX) only contains the currently available/visible/fetched rows.
I guess this is the expected and legitimate behaviour when remote paging is enabled, since the previous/next/remaining rows haven't been fetched. However, I think that it would be possible to find a way to download all pages as a whole using the downloadDataMutator function and re-fetching all data using the given AjaxURL, stripping the page & size attributes while keeping all the remaining info (filters, sorting & more).
Am I just trying to reinvent the wheel here? Is there a "standard" way to achieve that already?
EDIT: I implemented an hack to do that and made a post about it on this blog: feel free to use it if you need a "download all data" feature!
Hey @Darkseal
Thanks for getting in touch.
There is no inbuilt way to do this for the reasons you have mentioned above. But your work around could work with a couple of tweaks.
You wouldn't be able to make the ajax call with in the downloadDataMutator function as the ajax call is asynchronous and wouldn't be able to set its value to the return of the function. what you could do is make the ajax call first, send the returned data to a variable and access that variable from within the downloadDataMutator function.
Let me know if you need any other help.
Cheers
Oli :)
I ran into the same issue. My ugly hack involves:
const table2 = $('#newtable'); let flag = false;
table2.tabulator({
columns: columns, height: 10,
renderComplete: () => flag && table2.tabulator('download', 'xlsx', 'table.xlsx', {sheetName:"MyData"})
});
$('#btn17').click(e => {
flag = true;
table2.tabulator('setData', url, { filters: filters });
});
A few wishlist again:
I pursued a different approach, here's my hack:
1) When the "download all data" button is clicked, I fetch all values from the server (using the same WS which I did to populate the table) and store them within a allData global variable:
$("a#download_XLSX_all").click(function (e) {
e.stopPropagation();
e.preventDefault();
$.ajax({
url: '/ws_to_fetch_all_data/',
}).done(function (data) {
// store the whole data into a global variable
allData = data.data;
$("div.tabulator").tabulator("download", "xlsx", "data.xlsx");
});
});
2) Within the Tabulator's downloadDataMutator method, I replace the "current" (paginated) table data with the allData global variable (if present/not null):
downloadDataMutator: function (data) {
// if the allData global variable is present,
// we use it instead of "current" paginated data.
if (allData) {
data = allData;
allData = null;
}
// [TODO: do other column-based trasformations, if required
return data;
}
That's about it.
A great advantage of using such hack is that it also allows me to support a "download this page only" button and a "download all data" button at the same time / within the same page.
@Darkseal Does your approach replace the paginated table view by allData? I was not expecting this when I click 'Download all data' so I see another invisible tabulator the only way.
@mateddy , my "data-swapping" approach does the following:
allData global variable;download method, who also triggers the downloadDataMutatorhook; downloadDataMutatorhook, it uses the data contained within the previously-set allData global variable (checking if it's not null), replacing the "actual" table data; that variable is then set to null because it's not needed anymore.No need to create another tabulator since the data-swap perfectly works.
EDIT: I published this hack here to better explain how it works: feel free to have a look at it!
@Darkseal solution does not work for version 4.2.5. I can download all data when i call setData on the table, but this is not a good approach since i need to load all data inside the DOM.
Is there any other fix to download all data from a remote table without needing to load it into the table first?
I managed to fix the error i got at version 4.2.5 and have @Darkseal solution working with this approach:
The error i got was:
Uncaught TypeError: Cannot read property 'top' of undefined
Then i looked at the downloadDataFormatter _data_ param structure and found it has a _calcs_ object with _top_ and _bottom_ attributes. So, i simply created a calcs object inside the global data Darkseal suggested and now it works.
This is my _downloadDataFormatter_ function:
function onDownloadBtnClick(data) {
if (downloadData) {
downloadData.calcs = {
top: {},
bottom: {}
};
data = downloadData;
downloadData = null;
}
// Tratamento para exibi莽茫o de strings vazias em vez de valores nulos nos arquivos finais
data.data.forEach(row => {
for (key in row)
row[key] = row[key] ? row[key] : '';
});
return data;
}
Thank you very much for your comments, they where very useful.
In addition to what Diegovictor said, in 4.5 instead of what you did I assigned downloadData to data.data instead of data = downloadData, and it was not necessary to create that calcs dictionary.
I found another workaround to get all data, ignoring pagination. It takes advantage to preserve filters if needed. Just save page and page size data, then reset it to first page and full data with setPageSize(true), download, then reset to initial values.
Consider table is your tabulator
function downloadData() {
var page = table.getPage();
var pageSize = table.getPageSize();
table.setPageSize(true);
table.setPage(1);
table.download("csv", "data.csv");
table.setPageSize(pageSize);
table.setPage(page);
}
HerveEmagma works fantastic, thank you
Most helpful comment
I pursued a different approach, here's my hack:
1) When the "download all data" button is clicked, I fetch all values from the server (using the same WS which I did to populate the table) and store them within a
allDataglobal variable:2) Within the Tabulator's
downloadDataMutatormethod, I replace the "current" (paginated) table data with theallDataglobal variable (if present/not null):That's about it.
A great advantage of using such hack is that it also allows me to support a "download this page only" button and a "download all data" button at the same time / within the same page.