假设您有一场体育赛事或比赛。结果很可能会存储在数据库中,并且必须在网站上列出。您可以使用 Fetch API 从后端获取数据。本文档中不会对此进行解释。我假设数据已经被检索并且是一个记录数组。该记录数组必须按正确的顺序排列,但源函数可以在报表引擎中动态过滤和排序该数组。
本文档描述了如何轻松定义页眉和页脚以及如何通过比较函数安排记录分组。
每个标头函数都会根据静态文本和参数currentRecord、objWork和splitPosition返回html。每个页脚函数都会根据静态文本和参数 previousRecord、objWork 和 splitPosition 返回 html。
非常灵活,但是你必须自己制作html!不要指望所见即所得的编辑器。
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>`; };
如果您只想在报告开头初始化objWork.runningCounter,您可以通过在reportDefinition.headers[0]中放置正确的代码来实现。我将其称为属性 runningCounter,但您可以给它任何您想要的名称。
您必须增加代码中某处的运行计数器,因为...否则它不会运行;-) 例如:
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>`; };
下面是我创建的源代码以使这一切正常工作。它是所有页眉和页脚的包装函数。请随意复制粘贴它并在您自己的模块中使用它。
reportDefinition.display = (currentRecord, objWork) => { objWork.runningCounter++; // put extra code here return `<div>This is record number ${objWork.runningCounter}: ${currentRecord.team} - ${currentRecord.player}</div>`; };
objWork 是一个 javascript 对象,作为第二个参数传递给 createOutput 函数(可选参数,默认为 {})。它作为浅拷贝传递给页眉函数、页脚函数、比较函数、初始化函数、源函数和显示函数。所有这些函数共享这个对象。例如,您可以将其用于配置信息或颜色主题。 objWork 自动使用 { rawData: thisData } 进行扩展。例如 createOutput(reportDefinition, { font: 'Arial', font_color: 'blue' }).
下面列出的示例是用荷兰语编写的。
台球俱乐部的报道
台球成绩报告
更多关于开伦台球的报道
滚球报告
还有更多......
以上是使用 javascript 函数创建数据报告的详细内容。更多信息请关注PHP中文网其他相关文章!