首頁  >  文章  >  web前端  >  使用 javascript 函數建立資料報告

使用 javascript 函數建立資料報告

Patricia Arquette
Patricia Arquette原創
2024-11-05 06:27:02620瀏覽

假設您有一場體育賽事或比賽。結果很可能會儲存在資料庫中,並且必須在網站上列出。您可以使用 Fetch API 從後端取得資料。本文檔中不會對此進行解釋。我假設資料已經被檢索並且是一個記錄數組。此記錄數組必須按正確的順序排列,但來源函數可以在報表引擎中動態過濾和排序該數組。

本文檔描述如何輕鬆定義頁眉頁腳以及如何透過比較函數安排記錄分組。

每個標頭函數都會根據靜態文字和參數currentRecord、objWork和splitPosition傳回html。每個頁腳函數都會根據靜態文字和參數 previousRecord、objWork 和 splitPosition 傳回 html。

非常靈活,但你必須自己做html!不要指望所見即所得的編輯器。

報告的一般結構

  • 報告有報告頁首和頁尾。可以是文字或只是 html,或兩者兼而有之。
  • 報告具有一個或多個部分等級。部分等級 N 從頁首等級 N 開始,以頁腳等級 N 結束。
  • 局部等級 N 包含一次或多次部分等級 N 1,最高部分等級除外。
  • 最高部分層級包含基於陣列中的記錄所建立的資料。 在大多數情況下,最高部分等級只是一個 html 表格或 html 彈性項目。

報告結構範例

Create data reports using javascript function

稱為reportDefinition的報告定義物件的結構

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

objWork 是一個 javascript 對象,作為第二個參數傳遞給 createOutput 函數(可選參數,預設為 {})。它作為淺拷貝傳遞給頁首函數、頁尾函數、比較函數、初始化函數、來源函數和顯示函數。所有這些函數共享這個物件。例如,您可以將其用於配置資訊或顏色主題。 objWork 會自動使用 { rawData: thisData } 進行擴充。例如 createOutput(reportDefinition, { font: 'Arial', font_color: 'blue' }).

範例

下面列出的範例是用荷蘭語寫的。
撞球俱樂部的報道
桌球成績報告
更多關於開立球的報道
滾球報告
還有更多......

以上是使用 javascript 函數建立資料報告的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn