Supposons que vous organisez un événement sportif ou une compétition. Très probablement, les résultats seront stockés dans une base de données et devront être répertoriés sur un site Web. Vous pouvez utiliser l'API Fetch pour récupérer les données du backend. Cela ne sera pas expliqué dans ce document. Je suppose que les données ont déjà été récupérées et constituent un tableau d'enregistrements. Ce tableau d'enregistrements doit être dans le bon ordre, mais la fonction source peut filtrer et trier le tableau à la volée dans le moteur de rapport.
Ce document décrit comment définir des en-têtes et des pieds de page très facilement et comment organiser le regroupement d'enregistrements par fonction de comparaison également.
Chaque fonction d'en-tête renvoie du HTML basé sur le texte statique et les paramètres currentRecord, objWork et splitPosition. Chaque fonction de pied de page renvoie du HTML basé sur le texte statique et les paramètres previousRecord, objWork et splitPosition.
C'est très flexible, mais vous devez créer le code HTML vous-même ! Ne vous attendez pas à un éditeur WYSIWYG.
const reportDefinition = {}; reportDefinition.headers = [report_header, header_level_1, header_level_2, header_level_3, ...]; // default = [] reportDefinition.footers = [report_footer, footer_level_1, footer_level_2, footer_level_3, ...]; // default = [] reportDefinition.compare = (previousRecord, currentRecord, objWork) => { // default = () => -1 // code that returns an integer (report level break number) }; reportDefinition.display = (currentRecord, objWork) => { // code that returns a string, for example return `${currentRecord.team} - ${currentRecord.player}`; }; // source array can be preprocessed, for example filter or sort reportDefinition.source = (arr, objWork) => preProcessFuncCode(arr); // optional function to preprocess data array // example to add extra field for HOME and AWAY and sort afterwards reportDefinition.source = (arr, objWork) => arr.flatMap(val => [{ team: val.team1, ...val }, { team: val.team2, ...val }]) .sort((a, b) => a.team.localeCompare(b.team)); // optional method 'init' which should be a function. It will be called with argument objWork // can be used to initialize some things. reportDefinition.init = objWork => { ... };
reportDefinition.headers = []; // currentRecord=current record, objWork is extra object, // splitPosition=0 if this is the first header shown at this place, otherwise it is 1, 2, 3 ... reportDefinition.headers[0] = (currentRecord, objWork, splitPosition) => { // code that returns a string }; reportDefinition.headers[1] = '<div>Some string</div>'; // string instead of function is allowed; reportDefinition.footers = []; // previousRecord=previous record, objWork is extra object, // splitPosition=0 if this is the last footer shown at this place, otherwise it is 1, 2, 3 ... reportDefinition.footers[0] = (previousRecord, objWork, splitPosition) => { // code that returns a string }; reportDefinition.footers[1] = '<div>Some string</div>'; // string instead of function is allowed;
// previousRecord=previous record, currentRecord=current record, objWork is extra object, reportDefinition.compare = (previousRecord, currentRecord, objWork) => { // please never return 0! headers[0] will be displayed automagically on top of report // group by date return 1 (lowest number first) if (previousRecord.date !== currentRecord.date) return 1; // group by team return 2 if (previousRecord.team !== currentRecord.team) return 2; // assume this function returns X (except -1) then: // footer X upto and include LAST footer will be displayed (in reverse order). In case of footer function the argument is previous record // header X upto and include LAST header will be displayed. In case of header function the argument is current record // current record will be displayed // // if both records belong to same group return -1 return -1; };
Dans le cas où vous souhaitez implémenter un compteur courant, vous devez l'initialiser/réinitialiser au bon endroit. Cela peut être réalisé en mettant du code dans l'en-tête correspondant :
reportDefinition.headers[2] = (currentRecord, objWork, splitPosition) => { // this is a new level 2 group. Reset objWork.runningCounter to 0 objWork.runningCounter = 0; // put extra code here return `<div>This is header number 2: ${currentRecord.team}</div>`; };
Si vous souhaitez uniquement initialiser objWork.runningCounter au début du rapport, vous pouvez y parvenir en mettant le bon code dans reportDefinition.headers[0]. Je l'appelle propriété runningCounter, mais vous pouvez lui donner le nom de votre choix.
Vous devez augmenter le compteur en cours quelque part dans votre code car... sinon il ne fonctionne pas ;-) par exemple :
const reportDefinition = {}; reportDefinition.headers = [report_header, header_level_1, header_level_2, header_level_3, ...]; // default = [] reportDefinition.footers = [report_footer, footer_level_1, footer_level_2, footer_level_3, ...]; // default = [] reportDefinition.compare = (previousRecord, currentRecord, objWork) => { // default = () => -1 // code that returns an integer (report level break number) }; reportDefinition.display = (currentRecord, objWork) => { // code that returns a string, for example return `${currentRecord.team} - ${currentRecord.player}`; }; // source array can be preprocessed, for example filter or sort reportDefinition.source = (arr, objWork) => preProcessFuncCode(arr); // optional function to preprocess data array // example to add extra field for HOME and AWAY and sort afterwards reportDefinition.source = (arr, objWork) => arr.flatMap(val => [{ team: val.team1, ...val }, { team: val.team2, ...val }]) .sort((a, b) => a.team.localeCompare(b.team)); // optional method 'init' which should be a function. It will be called with argument objWork // can be used to initialize some things. reportDefinition.init = objWork => { ... };
reportDefinition.headers = []; // currentRecord=current record, objWork is extra object, // splitPosition=0 if this is the first header shown at this place, otherwise it is 1, 2, 3 ... reportDefinition.headers[0] = (currentRecord, objWork, splitPosition) => { // code that returns a string }; reportDefinition.headers[1] = '<div>Some string</div>'; // string instead of function is allowed; reportDefinition.footers = []; // previousRecord=previous record, objWork is extra object, // splitPosition=0 if this is the last footer shown at this place, otherwise it is 1, 2, 3 ... reportDefinition.footers[0] = (previousRecord, objWork, splitPosition) => { // code that returns a string }; reportDefinition.footers[1] = '<div>Some string</div>'; // string instead of function is allowed;
// previousRecord=previous record, currentRecord=current record, objWork is extra object, reportDefinition.compare = (previousRecord, currentRecord, objWork) => { // please never return 0! headers[0] will be displayed automagically on top of report // group by date return 1 (lowest number first) if (previousRecord.date !== currentRecord.date) return 1; // group by team return 2 if (previousRecord.team !== currentRecord.team) return 2; // assume this function returns X (except -1) then: // footer X upto and include LAST footer will be displayed (in reverse order). In case of footer function the argument is previous record // header X upto and include LAST header will be displayed. In case of header function the argument is current record // current record will be displayed // // if both records belong to same group return -1 return -1; };
reportDefinition.headers[2] = (currentRecord, objWork, splitPosition) => { // this is a new level 2 group. Reset objWork.runningCounter to 0 objWork.runningCounter = 0; // put extra code here return `<div>This is header number 2: ${currentRecord.team}</div>`; };
Ci-dessous le code source que j'ai créé pour que tout cela fonctionne. C'est une sorte de fonction wrapper pour tous les en-têtes et pieds de page. N'hésitez pas à le copier-coller et à l'utiliser dans votre propre module.
reportDefinition.display = (currentRecord, objWork) => { objWork.runningCounter++; // put extra code here return `<div>This is record number ${objWork.runningCounter}: ${currentRecord.team} - ${currentRecord.player}</div>`; };
objWork est un objet javascript qui est passé comme deuxième argument à la fonction createOutput (argument facultatif, {} par défaut). Il est transmis sous forme de copie superficielle aux fonctions d'en-tête, de pied de page, de fonction de comparaison, de fonction d'initialisation, de fonction source et de fonction d'affichage. Toutes ces fonctions partagent cet objet. Vous pouvez l'utiliser par exemple pour des informations de configuration ou un thème de couleur. objWork est automatiquement étendu avec { rawData: thisData }. Par exemple createOutput(reportDefinition, { font: 'Arial', font_color: 'blue' }).
Les exemples listés ci-dessous sont rédigés en néerlandais.
Renseignements sur club de billard
Rapports sur les scores de billard
Plus de rapports sur le billard carambole
Reportages pour la pétanque
et bien d'autres....
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!