現金流量表(Cash Flow Statement),是指反映企業在一定會計期間現金和現金等價物流入和流出的報表。現金流量表是企業財務報表的三個基本報告之一(另外兩個是資產負債表和損益表)。
為了全面系統地揭示企業一定時期的財務狀況、經營成果和現金流量,財務報表需按財政部會計準則的標準格式設計,因此,財務報表的典型特徵是資料更新頻繁、分析維度多、資料來源複雜,常規的報表工具很難同時滿足上述所有需求
本部落格將帶大家瞭解如何使用類Excel 的 JavaScript 電子試算表在前端建立現金流日曆。此日曆將廣泛使用以下強大功能:
最終效果如圖所示:
要建立我們的現金流日曆,我們需要建立如下所述的三張表:
我們範例的資料來源是交易列表。
我們建立了一個更動態的表格,當我們需要資料而不是單元格範圍時,我們可以參照 Table1。
此表包含有關 TransactionID、交易型別、交易日期、公司名稱、帳戶名稱、存款金額和取款的資訊。
此頁面包含我們將用來呈現現金流日曆中發生的交易的模板範圍。
此處的此單元格範圍將用作包含現金流日曆中所需資訊的單元格的模板。
我們要做的第一件事是排列單元格,然後設定單元格的繫結路徑。
它可以通過 Javascript 使用 SpreadJS setBindingPath 方法來完成。
templateSheet.setBindingPath(0, 1, "month");
templateSheet.setBindingPath(1, 2, "date");
templateSheet.setBindingPath(2, 2, "start");
templateSheet.setBindingPath(3, 2, "withdrawals");
templateSheet.setBindingPath(4, 2, "deposits");
templateSheet.setBindingPath(5, 2, "end");
當然,上邊這步操作也有不用寫程式碼的方法——用SpreadJS設計器,下載SpreadJS安裝包,在下載的安裝包中,從「\SpreadJS.Release.x.x.x\Designer\Designer Runtime」路徑下找到設計器的安裝包,完成安裝後,按照下列步驟操作:
為了使現金短缺(期末餘額為負)的日子可以用紅色著色,期末餘額為正的日子用綠色著色,中性的用黑色著色,我們可以使用條件格式。在設計器上可以這樣操作:
第 1 步:新增 MonthPicker 元素
我們日曆的第一個元素是可變月份元素。要新增它,請使用 MonthPicker,這是 SpreadJS 中的一種下拉單元格樣式。
JavaScript:
var monthPickerStyle = new GC.Spread.Sheets.Style();
monthPickerStyle.dropDowns = [
{
type: GC.Spread.Sheets.DropDownType.monthPicker,
option: {
startYear: 2019,
stopYear: 2021,
height: 300,
}
}
];
sheet.setStyle(2, 5, monthPickerStyle);
設計器:
選擇單元格(在我們的例子中為 B2)
然後,我們在進行計算時為包含月份的單元格指定一個名稱。
使用 SEQUENCE(rows,columns,start,step) 函數來分配我們日曆中的日期。這允許我們稍後在 CellClick 上檢索單元格值。 B4 單元格的公式為:
=SEQUENCE(6,7,currentMonth-WEEKDAY(currentMonth)+1,1)
JavaScript:
cashflowSheet.setFormula(3, 1, '=SEQUENCE(6,7,currentMonth-WEEKDAY(currentMonth)+1,1)');
我們還沒有為這些單元格使用格式化程式。
下一步是使用條件格式來使屬於其他月份的日期成為可能,但所選日期為空白:
下面的步驟包括使用 RANGEBLOCKSPARKLINE,它將 TemplateSheet 中的單元格範圍用作單個單元格型別,並使用 OBJECT 函數將模板應用於代表我們現金流日曆中日期的所有單元格中。
由於我們使用 SEQUENCE 為這些單元格設定值,因此我們將使用 RANGEBLOCKSPARKLINE 作為格式。
=RANGEBLOCKSPARKLINE('Cell Template'!$A$2:$D$7,OBJECT("date",@,"start",IFERROR(SUM(FILTER(Table1[Deposit],Table1[Date]<@))-SUM(FILTER(Table1[Withdrawal],Table1[Date]<@)),0),"withdrawals",IFERROR(SUM(FILTER(Table1[Withdrawal],Table1[Date]=@)),0),"deposits",IFERROR(SUM(FILTER(Table1[Deposit],Table1[Date]=@)),0),"month",MONTH($A$2)))
作為第一個引數,它將單元格範圍作為 TemplateSheet 中的模板。
作為第二個引數,它需要一個 OBJECT,該 OBJECT 從位於資料來源表的 Table1 中獲取資料。
使用公式是繫結並返回一個範圍模板,以便更輕鬆地使用範圍模板。
這是最終輸出:
如上圖所示,包含日曆天數的單元格提供有關開始/結束餘額、存款總額和提款總額的資訊。
第 3 步:獲取每日交易
如果我們想從 DataSource 頁面中提取所有交易的列表,我們可以藉助 SelectionChanged 事件。當這些事件發生時,SpreadJS 中的工作表將其事件繫結到特定操作。
在我們的範例中,當用戶從日曆中選擇日期時,我們使用了這個方便的 SpreadJS 功能來提取所有交易的列表。
我們為包含所選日期、存款和取款的單元格指定一個名稱,因為它更容易進行計算,並且表格將包含有關交易的資訊。為 currentMonth 建立名稱範圍的步驟是:
在我們的範例中:
name:當前選擇;refer to: ='Cash-Flow'!$B$11
name:當前存款;refer to: =FILTER(tblTransactions[Type]:tblTransactions[Withdrawal],(tblTransactions[Date]=CurrentSelection)*(tblTransactions[Deposit]>0))
name:當前取款;refer to: =FILTER(tblTransactions[Type]:tblTransactions[Withdrawal],(tblTransactions[Date]=CurrentSelection)*(tblTransactions[Withdrawal]>0))
設定不同的公式來獲取所有存款列表、所有提款列表、結束和開始餘額。
1. 起始餘額(之前所有存款的總和 - 之前所有取款的總和):=IFERROR((SUM(FILTER(tblTransactions[Deposit],tblTransactions[Date]<$B$11))-SUM(FILTER(tblTransactions[Withdrawal],tblTransactions [日期]<$B$11))),0)
2. 結束餘額(起始餘額 + 當前存款的總和 - 當前提款的總和):=IFERROR(D13+(SUM(FILTER(tblTransactions[Deposit],tblTransactions[Date]=$B$11))-SUM(FILTER(tblTransactions[Withdrawal] ,tblTransactions[日期]=$B$11))),0)```
其中 D13 是起始餘額:
![](https://img2022.cnblogs.com/blog/139239/202210/139239-20221018232814572-876221459.png)
目前手動插入 currentSelection。要根據使用者日期選擇進行更改,請執行下一步。
在 JavaScript 中建立事件處理常式(見下文):
// on day selection, update a cell used in filtering the data to show detailed transaction list
cashflowSheet.bind(GC.Spread.Sheets.Events.SelectionChanged, function (sender, args) {
const sheet = args.sheet;
const row = args.newSelections[0].row;
const col = args.newSelections[0].col;
if ((row < 3 || row >= 3 + 6)
|| (col < 1 || col >= 1 + 7))
return;
// set the current date cell so that FILTER would update.
sheet.setValue(10, 1, sheet.getValue(row, col));
});
一旦使用者單擊單元格,上面的程式碼就會檢查單元格是否在日曆邊界內 (B4:H9)。否則,它會更新 currentSelection,因此,所有用於獲取餘額和有關交易資訊的公式都會在它們指向更改的選定日期時給出正確的結果。
瞭解更多demo範例 :https://demo.grapecity.com.cn/spreadjs/gc-sjs-samples/index.html
行動端範例:http://demo.grapecity.com.cn/spreadjs/mobilesample/