一篇带你了解如何使用纯前端类Excel表格构建现金流量表
现金流量表(Cash Flow Statement),是指反映企业在一定会计期间现金和现金等价物流入和流出的报表。现金流量表是企业财务报表的三个基本报告之一(另外两个是资产负债表和损益表)。
为了全面系统地揭示企业一定时期的财务状况、经营成果和现金流量,财务报表需按财政部会计准则的标准格式设计,因此,财务报表的典型特征是数据更新频繁、分析维度多、数据来源复杂,常规的报表工具很难同时满足上述所有需求
本博客将带大家了解如何使用类Excel 的 JavaScript 电子表格在前端创建现金流日历。此日历将广泛使用以下强大功能:
- 动态数组公式 - 根据一个公式将多个结果返回到一系列单元格。此示例使用 SEQUENCE 和 FILTER 函数。
- RANGEBLOCKSPARKLINE(template_range, data_expr) - 此迷你图允许开发人员将单元格范围模板 (template_range) 定义为单个单元格类型,并将该模板应用于单元格以将一组数据 (data_expr) 加载到模板中。该模板可以包括多行和/或多列。
最终效果如图所示:
要创建我们的现金流日历,我们需要创建如下所述的三张表:
- 数据源表
- 模板表
- 现金流日历:渲染表
数据源表
我们示例的数据源是交易列表。
我们创建了一个更动态的表格,当我们需要数据而不是单元格范围时,我们可以引用 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”路径下找到设计器的安装包,完成安装后,按照下列步骤操作:
- 单击数据选项卡上的模板菜单 - 字段列表面板将出现在右侧
- 将鼠标悬停在 Start 分支上并通过单击绿色 + 按钮添加字段 *请注意,你可以使用“x”按钮删除字段并使用位于分支右侧的设置修改这些字段
- 拖动模板范围所需单元格中的字段
为了使现金短缺(期末余额为负)的日子可以用红色着色,期末余额为正的日子用绿色着色,中性的用黑色着色,我们可以使用条件格式。在设计器上可以这样操作:
- 在合并时选择日期单元格“A2:D2”
- 条件格式 → 新规则
- 通常,键入并选择使用公式来确定要格式化的单元格
- 输入你的公式,在我们的例子中 ='Cell Template'!$C$6>0
- 单击格式→填充→选择绿色作为字体颜色
- 重复相同的步骤,但使用公式: ='Cell Template'!$C$6<0 *请注意,对于余额为负的情况,颜色应设置为红色
现金流日历:渲染表
第 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)
- 主页选项卡 → 单元格下拉菜单 → 月份选择器
- 在命令右侧,单击...
- 设置选取器的开始、结束年份和高度
然后,我们在进行计算时为包含月份的单元格指定一个名称。
- 在公式选项卡上,选择名称管理器
- 在弹出窗口中,单击新建按钮
- 设置单元格的名称。在我们的示例中:name: currentMonth
参考:$D$2。你还可以添加评论并更改引用对象
第 2 步:创建现金流日历
使用 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)');
我们还没有为这些单元格使用格式化程序。
下一步是使用条件格式来使属于其他月份的日期成为可能,但所选日期为空白:
- 选择 B4:H9 然后选择日历的日期 → 条件格式
- 从下拉列表中选择新规则,然后选择“使用公式确定要格式化为规则类型的单元格”
- 输入你的公式,在我们的例子中为“=MONTH(B4)<>MONTH(currentMonth)” - 此格式仅适用于月份与下拉列表中选择的月份不同的单元格
- 单击格式
- 编号 → 自定义
- 输入”;;;”作为格式化程序将所有正确的单元格设为空白
下面的步骤包括使用 RANGEBLOCKSPARKLINE,它将 TemplateSheet 中的单元格范围用作单个单元格类型,并使用 OBJECT 函数将模板应用于代表我们现金流日历中日期的所有单元格中。
由于我们使用 SEQUENCE 为这些单元格设置值,因此我们将使用 RANGEBLOCKSPARKLINE 作为格式。
- 选择单元格区域 B4:H9
- 格式→更多数字格式→自定义
- 将格式化程序设置为:
=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 中获取数据。
- [日期]:单元格的当前值
- [开始]:之前所有存款的总和 - 之前所有提款的总和
- [提款]:当前提款的总和
- [存款]:当前存款的总和
- [end]:[start] + 所有当前存款的总和 - 所有当前提款的总和
使用公式是绑定并返回一个范围模板,以便更轻松地使用范围模板。
这是最终输出:
如上图所示,包含日历天数的单元格提供有关开始/结束余额、存款总额和提款总额的信息。
第 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 是起始余额:
- 存款:=IFERROR(FILTER(currentDeposits,{1,0,1,1,0}),"")
- 取款:=IFERROR(FILTER(currentWithdrawals,{1,0,1,0,1}),"")
![](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/
一篇带你了解如何使用纯前端类Excel表格构建现金流量表的更多相关文章
- 基于纯前端类Excel表格控件实现在线损益表应用
财务报表也称对外会计报表,是会计主体对外提供的反映企业或预算单位一定时期资金.利润状况的会计报表,由资产负债表.损益表.现金流量表或财务状况变动表.附表和附注构成.财务报表是财务报告的主要部分,不包括 ...
- H5纯前端生成Excel表格
H5纯前端生成Excel表格方法如下: <!DOCTYPE html> <html> <head> <title></title> < ...
- 纯前端导出Excel表格
<html> <head> <p style="font-size: 20px;color: red;">使用a标签方式将json导出csv文件 ...
- vue 纯前端导出 excel 表格
在开发后台管理系统的时候,很多地方都要用到导出excel 表格,比如将table中的数据导出到本地,那么实现这种需求往往有两种方案: 一.后端开发一个下载链接,前端将这个链接放到 a 标签的 href ...
- 手把手带你实现基于 Vite+Vue3 的在线Excel表格系统
今天,葡萄带你了解如何基于Vite+Vue3实现一套纯前端在线表格系统. 在正式开始项目介绍之前,首先咱们首先来介绍一下Vite和Vue3. Vue3 2020年09月18日Vue.js 3.0发布, ...
- vue后台_纯前端实现excel导出/csv导出
之前的文件下载功能一般是由前后端配合实现,由于项目需要,纯前端实现了一把excel的导出功能: 一.excel导出 1.安装依赖库 xlsx:这是一个功能强大的excel处理库,但是上手难度也很大,还 ...
- 使用javascript纯前端导出excel
前言(感谢技术的分享者) 参考博客地址 github地址 由SheetJS出品的js-xlsx是一款非常方便的只需要纯JS即可读取和导出excel的工具库,功能强大,支持格式众多,支持xls.xlsx ...
- 纯前端表格控件SpreadJS V12.1 隆重登场,专注易用性,提升用户体验
一款优秀的开发工具,在更新迭代中,除了要满足不同场景的业务需求,也需不断优化已有功能,尤其是细节方面,要能为用户带来使用体验和开发效率的提升. 作为一款备受业界专家和开发者认可的纯前端类Excel ...
- Vue 2.x + Webpack 3.x + Nodejs 多页面项目框架(上篇——纯前端多页面)
Vue 2.x + Webpack 3.x + Nodejs 多页面项目框架(上篇--纯前端多页面) @(HTML/JS) 一般来说,使用vue做成单页应用比较好,但特殊情况下,需要使用多页面也有另外 ...
随机推荐
- 在Centos7.3下使用Siege对Django服务进行压力测试
原文转载自「刘悦的技术博客」https://v3u.cn/a_id_87 Siege是linux下的一个web系统的压力测试工具,支持多链接,支持get和post请求,可以对web系统进行多并发下持续 ...
- 海纳百川无所不容,Win10环境下使用Docker容器式部署前后端分离项目Django+Vue.js
原文转载自「刘悦的技术博客」https://v3u.cn/a_id_179 随着现代化产品研发的不断推进,我们会发现,几乎每个产品线都会包含功能各异的服务,而且服务与服务之间存在也会存在着错综复杂的依 ...
- 杀死 Windows 某个端口
进入终端命令行,输入netstat -aon|findstr 3000查找端口号所对应的 PID: 输入指令taskkill /pid 20348 /f:
- 检查一个数值是否为有限的Number.isFinite()
如果参数类型不是数值,Number.isFinite()一律返回false. Number.isFinite(15); // true Number.isFinite(0.8); // true Nu ...
- Spring源码-xml解析
Spring使用SAX解析xml.SAX的全称是Simple APIs for XML,也即XML简单应用程序接口.与DOM不同,SAX提供的访问模式是一种顺序模式,这是一种快速读写XML数据的方式. ...
- ARC120F Wine Thief (组合数学)
题面 有一个长为 N N N 的序列,相邻的两个数中只能选一个,总共选 k k k 个数,一种方案的价值为选的 k k k 个数的和,问所有合法方案的价值总和,答案对 998244353 取模. 1 ...
- Python自学笔记11-函数的定义和调用
函数是组织代码的非常有效的方式,有了函数,我们就可以编写大规模的项目.可以说,函数是组织代码的最小单元. Python函数的定义 函数是代码封装的一种手段,函数中包含一段可以重复执行的代码,在需要用到 ...
- 第五十九篇:关于Vue
好家伙,前面关于vue的学习太散太乱了,我决定重新整理一下知识框架,当作复习了,并且在其中补充一些概念 先提出一个问题:怎么把数据弄到页面上? 若不借助vue,把数据填充到页面上, 我们需要操作dom ...
- Neo4j入门详细教程
Neo4j安装配置 (1)下载安装包 (2)安装jdk (3)环境变量配置 分三步,具体参考 https://www.bilibili.com/video/BV1Nz411q7bG?from=sea ...
- MySQL数据库如何线上修改表结构
一.MDL元数据锁 在修改表结构之前,先来看下可能存在的问题. 1.什么是MDL锁 MySQL有一个把锁,叫做MDL元数据锁,当对表修改的时候,会自动给表加上这把锁,也就是不需要自己显式使用. 当对表 ...