function GabaritPDF(doc,rows,filtres){

        const nbLignes = rows.length;        
        const horodatage = new Date().toLocaleString('fr-FR', {
            dateStyle: 'short',
            timeStyle: 'medium'
        });
        const resumeFiltres = filtres.length
            ? `Filtres : ${filtres.join(' ; ')}`
            : '';

doc.content = [
    {
        image: LogoBase64,
        link: 'https://www.inha.fr',
        width: 70,
        margin: [0, 0, 0, 15]
    },

    {
        table: {
            widths: ['*'],
            body: [[
                {
                    stack: [
                        {
                            text: 'Les itinéraires des voyages des Thierry',
                            style: 'header',
                            color: '#999999',
                            margin: [0, 0, 0, 4]
                        },
                        {
                            text: 'pense.inha.fr',
                            link: 'https://pense.inha.fr/recherches-en-cours/ItinerairesThierry',
                            color: '#d20a11',
                            margin: [0, 0, 0, 8]
                        },
                        {
                            text: `${nbLignes} document${nbLignes > 1 ? 's' : ''} exporté${nbLignes > 1 ? 's' : ''}`,
                            style: 'subheader',
                            color: '#999999',
                            margin: [0, 0, 0, 4]
                        },
                        {
                            text: resumeFiltres,
                            style: 'meta',
                            color: '#999999',
                            margin: [0, 0, 0, resumeFiltres ? 4 : 0]
                        },
                        {
                            text: `export généré le ${horodatage}`,
                            style: 'meta',
                            color: '#999999'
                        }
                    ],
                    margin: [12, 12, 12, 12]
                }
            ]]
        },

        layout: {
            fillColor: function () {
                return '#ffffff';
            },    
            hLineWidth: () => 1,
            vLineWidth: () => 1,
            hLineColor: () => '#000000',
            vLineColor: () => '#000000'
        },

        margin: [0, 0, 0, 20]
    },

    ...rows.map(function(row, index) {

        const lignes = HTMLversTexte(row.texte || '');

        return {
            stack: [
                {
                    canvas: [
                        {
                            type: 'line',
                            x1: 0,
                            y1: 0,
                            x2: 520,
                            y2: 0,
                            lineWidth: 0.5
                        }
                    ],
                    margin: [0, 16, 0, 0]
                },
                {
                    text: row.identifiant,
                    link: 'https://pense.inha.fr/recherches-en-cours/ItinerairesThierry/corpus/' + row.identifiant,
                    color: '#d20a11',
                    bold: true,
                    margin: [0, 10, 4, 6]
                },
                {
                    text: row.titre,
                    bold: true,
                    decoration: 'underline',
                    margin: [0, 0, 0, 8]
                },
                {
                    stack: lignes.map(function(ligne) {
                        return {
                            text: ligne,
                            margin: [0, 0, 0, ligne === '' ? 4 : 0]
                        }; 
                    }),
                    lineHeight: 0.5,
                    margin: [0, 0, 0, 0]
                }
            ]
        };
    })
];
        doc.styles = {
            header: {
                fontSize: 12,
                bold: true
            }
        };

        doc.defaultStyle.fontSize = 8;
        doc.pageMargins = [40, 40, 40, 40];
     
}

function HTMLversTexte(html) {

    const div = document.createElement('div');
    div.innerHTML = html;

    // supprimer les blocs non textuels
    div.querySelectorAll('.info-bloc, .texte-page-id, .region-type-pagination, .infos-region, .position-absolute').forEach(el => {
        el.remove();
    });

    // injecter un saut de ligne après chaque ligne transcrite
    div.querySelectorAll('.ligne-lb').forEach(el => {
        el.after(document.createTextNode('\n'));
    });

    // extraire le texte brut, normaliser et retourner un tableau de lignes
    return div.textContent
        .replace(/\n{3,}/g, '\n\n')
        .trim()
        .split('\n');
}

function getFiltresActifs(Table) {
    const filtres = [];

    // Recherche globale
    const globalSearch = Table.search();
    if (globalSearch) {
        filtres.push(`recherche globale : "${globalSearch}"`);
    }

    // Recherches par colonne
    const settings = Table.settings()[0];

    Table.columns().every(function () {
        const search = this.search();
        const index = this.index();
        const name = settings.aoColumns[index].name || `colonne ${index}`;

        if (search) {
            filtres.push(`${name} : "${search}"`);
        }
    });

    return filtres;
}

function getFiltresActifsCourts(Table) {

    const filtres = [];

    const settings = Table.settings()[0];

    Table.columns().every(function () {

        const search = this.search();

        if (!search) return;

        const index = this.index();

        const nom =
            settings.aoColumns[index].name ||
            `c${index}`;

        // nettoyage très compact
        const valeur = search
            .replace(/[\^\$\(\)\|]/g, '')
            .replace(/[^a-zA-Z0-9àâçéèêëîïôûùüÿñæœ-]/g, '')
            .substring(0, 12);

        filtres.push(
            nom.substring(0, 8) + '-' + valeur
        );
    });

    return filtres.join('_');
}


const LogoBase64 = 'data:image/png;base64,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';