假設您有一場體育賽事或比賽。結果很可能會儲存在資料庫中,並且必須在網站上列出。您可以使用 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中文網其他相關文章!