@Matheus, uma opção é você utilizar a lib jQuery Datatable. A própria lib tem uma documentação bem robusta e fica fácil entender como funciona.
Para te auxiliar no começo, vou colocar um trecho onde faço o uso dessa lib com modo Ajax e utilizando a API de /api/public/ecm/dataset/datasets/ do Fluig.
let myTable = $("#tableRiscos_" + WCMRiscos.instanceid).DataTable({
processing: true, //utilizado para atualizar a tabela
destroy: true, //utilizado para atualizar a tabela
order: [2, 'asc'], //coluna que será ordenada inicialmente
pagingType: 'full_numbers', //tipo de paginação
searching: true, //Se será possível filtrar por search
info: true, //Se terá info da tabela
dom: '<"row"<"col-sm-12"Btip>>', //Como ficará o DOM B: botões, t: tabela, i: info, p: paginação
sort: true, //Se será possível ordenar
language: that.languagePT_BR(), //Linguagem que será utilizado na tabela. Tem pt-BR, procurar na documentação que tem um JSON
ajax: { //Ajax. Passar os filtros como se tivesse fazendo um request no DatasetFactory
async: true,
crossDomain: true,
url: '/api/public/ecm/dataset/datasets/',
method: "POST",
data: function () {
const data = {
name: 'dsGerirRisco',
fields: null,
constraints: [{
// Filtro para retornar todos os registros do dataset.
_field: 'documentId',
_initialValue: '___NULL___',
_finalValue: '___NULL___',
_type: 1
}],
order: null
};
return JSON.stringify(data);
},
contentType: 'application/json',
dataType: 'application/json',
dataSrc: function (json) {
return json.content.values;
}
},
columns: [
// Tratamento das colunas. Verificar na documentaçaõ
{
data: null,
className: 'fs-v-align-middle text-center control',
orderable: false,
searchable: false,
defaultContent: ''
},
{
data: null,
className: 'fs-v-align-middle text-center',
orderable: false,
searchable: false,
render: function (data, isType, full, meta) {
return '<input type="radio" name="rdName_' + WCMRiscos.instanceid + '">';
}
},
{
data: 'instrucao',
className: 'fs-v-align-middle fs-cursor-pointer',
width: '28%',
render: function (data, isType, full, meta) {
const arrayDocuments = data.split(/\,/gi);
let html = '';
$.each(arrayDocuments, function (index, docuemtid) {
const documentObj = that.getDescricaoDocumento(docuemtid);
html += documentObj == -1 ?
'<legend class="documentsgq-info"><div><i class="fluigicon fluigicon-sm fluigicon-warning-sign text-danger" data-get-description data-documentid="' + docuemtid + '"></i> Origem não encontrada</div></legend>' :
'<legend class="documentsgq-info"><div><i class="fluigicon fluigicon-sm fluigicon-document-square"></i> ' + documentObj.DESCRICAO + '</div></legend>'
});
return html;
}
},
{
data: 'risco',
className: 'fs-v-align-middle fs-cursor-pointer',
width: '37%',
},
{
data: 'ocorrencia',
className: 'fs-v-align-middle fs-cursor-pointer text-center',
width: '7%',
render: function (data, type, row) {
return that.labelsSeveridadeOcorrencia(data);
}
},
{
data: 'severidade',
className: 'fs-v-align-middle fs-cursor-pointer text-center',
width: '7%',
render: function (data, type, row) {
return that.labelsSeveridadeOcorrencia(data);
}
},
{
type: 'num',
data: 'npr',
className: 'fs-v-align-middle fs-cursor-pointer text-center td-npr',
width: '7%'
},
{
data: 'status',
className: 'fs-v-align-middle fs-cursor-pointer text-center',
width: '12%'
},
{
data: 'codArea',
className: 'none',
},
{
data: 'dateAtualizacao',
className: 'none'
},
{
data: 'respostaRisco',
className: 'none',
},
{
data: 'numAprovacao',
className: 'none',
render: function (value, type, row) {
if (value == '')
return '<i>Solicitação não iniciada</i>';
else
return '<button class="btn btn-primary fs-full-width" data-open-solic>' + value + '</button>';
}
},
{
data: 'numAcao',
className: 'none',
render: function (value, type, row) {
if (value == '')
return '<i>Solicitação não iniciada</i>';
else
return '<button class="btn btn-primary fs-full-width" data-open-solic>' + value + '</button>';
}
},
{
data: null,
className: 'none',
defaultContent: '<button class="btn btn-primary fs-full-width" data-all-solics><i class="fluigicon fluigicon-zoom-in"></i></button>'
}
],
responsive: {
// Responsive é a forma que será mostrada a tabela.
details: {
display: $.fn.dataTable.Responsive.display.childRow,
type: 'column',
renderer: function (api, rowIdx, columns) {
//Callback que será executado quando a linha for mostrada. Verificar na documentação.
}
}
},
buttons: [{
// Botões de exportar em excel, pdf, print. Verificar a documentação para
extend: 'excel',
className: "exportExcel fs-display-none",
filename: function () {
// Callback de geração de nome do arquivo
return "Relatorio_Riscos_";
},
exportOptions: {
stripNewlines: true,
stripHtml: false,
modifier: {
page: 'all'
},
columns: [2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12],
format: {
body: function (data, row, column, node) {
// Callback para formatar as o body do excel. verificar a documentação
}
}
},
}],
fixedHeader: true,
createdRow: function (row, data, index) {
// Callback que será executado a cada criação de linha
},
drawCallback: function (configs) {
// Callback que será executada todas as vezes que a tabela for renderizada.
},
initComplet: function () {
// Executada somente na primeira vez que a tabela for criada. Verificar a documentação
}
});