JavaScript 앱에서 재무 보고서 작성하는 방법
페이지 정보
작성자 GrapeCity 작성일 2019-07-03 00:00 조회 2,642회 댓글 0건본문
첨부파일
관련링크
대부분의 재무 관련 애플리케이션에 대한 일반적인 요구 사항은 보고서를 만들어야 한다는 것입니다. 이는 손익 계산서(P&L), 예산 책정, 예측 등 그 이상의 모든 것을 포함할 수 있습니다. 이 모든 것의 공통적인 요인은 데이터이며, 스프레드시트를 사용하여 숫자를 빠르게 처리해야 한다는 것입니다.
이 포스팅에서는 엔터프라이즈 JavaScript 스프레드시트인 SpreadJS 를 사용하여 최종 사용자가 해당 데이터를 쉽게 필터링 할 수있는 방법에 중점을 둔 전형적인 장기 미지급금 보고서를 작성하는 방법을 보여줍니다.
이 보고서에는 미결제 금액이 모두 고객 정보와 함께 표시됩니다. 그런 다음 데이터를 필터링하고 해당 고객의 세부 정보와 함께 과거 지불 기한을 표시합니다. 이 유형의 보고서 사용자는 관리자, 회계사 또는 이사가 될 수 있습니다.
재무 보고서 작성
SpreadJS의 내장 및 사용자 정의 기능을 사용하여 이 보고서를 작성할 수 있는 방법에는 아래와 같이 네 가지가 있습니다.
- 슬라이서 사용
- 맞춤 필터 사용
- 배열 수식 사용
- 테이블 필터 사용
(참고 : 이 보고서를 작성하기 위해 정적 JSON 데이터를 사용했으며 다른 섹션에도 동일한 데이터를 사용했습니다.)
이 네가지 방법을 각각 별도의 포스팅으로 나누었습니다. 이 포스팅에서는 슬라이서로 장기 미지급금 보고서 보고서 작성에 대해 설명합니다.
우리는 ReactJS로 이 보고서를 만들 것입니다. (ReactJS와 함께 SpreadJS를 사용하는 방법)
이 애플리케이션을 위해 Spread.Sheets를 사용하여 React 애플리케이션에서 SpreadJS의 슬라이서를 시연하는 사용자 지정 컴포넌트를 만들었습니다.
슬라이서는 매우 직관적인 방식으로 데이터를 빠르게 필터링하는 데 사용됩니다. 드롭 다운에서 선택해야 하는 기존 필터와 다르게 작동합니다. 슬라이서를 사용하면 슬라이서 항목(필터링 할 조건)을 클릭하자마자 필터 결과가 표시됩니다. 스타일과 데이터를 설정하여 슬라이서를 추가로 사용자 정의할 수 있습니다.
여기에서는 Spread.Sheets를 사용하여 테이블 슬라이서를 사용하여 보고서를 생성할 사용자 정의 React 컴포넌트를 만듭니다.
1.생성자에서 Spread.Sheet 행의 스타일을 설정합니다.
constructor(props) {
super(props);
this.COLS = 12;
this.hostStyle = props.hostStyle;
this.customerRowStyle = new GC.Spread.Sheets.Style();
this.customerRowStyle.backColor = "lightblue";
this.customerRowStyle.font = "bold normal 15px normal";
}
2. 'records'라는 변수에서 컴포넌트 상태의 데이터를 가져옵니다.
state = {
records: this.props.data,
organizaionName: this.props.organizationName,
title: this.props.title,
dateGeneratedOn: new Date(),
asOfDate: new Date(),
dateFormat: "dd/MM/yyyy",
spread: null
};
3. 고객 데이터, lookup 수식 데이터 및 슬라이서 보고서를 표시하려면 3개의 시트가 필요합니다.
initSpread = workBook => {
workBook.suspendPaint();
this.initDataTableSheet(workBook.getSheetFromName("Aging Report
Table"));
this.initLookupTable(workBook.getSheetFromName("LookupTable"));
this.initSlicerSheet(workBook.getSheetFromName("Report with
Slicer"));
workBook.resumePaint();
this.setState({
spread: workBook
});
this.props.onWorkBookInitialized(workBook);
};
4. 이제 각 메소드를 초기화하기 위해 아래와 같이 작성합니다. SpreadJS 시트의 데이터 소스로 기존 JSON 데이터를 사용하려고 합니다. 이 데이터는 고객의 재무 데이터를 보여줍니다.
initDataTableSheet = sheet => {
sheet.setDataSource(this.state.records);
sheet.setColumnWidth(0, 120);
sheet.setColumnWidth(1, 120);
sheet.setColumnWidth(2, 120);
sheet.setColumnWidth(3, 120);
sheet.setColumnWidth(4, 120);
};
결과는 다음과 같습니다.
5. 미리 정의 된 값으로 다른 시트를 만듭니다. 이 시트는 더 나은 사용자 경험을 제공하기 위해 슬라이서를 만드는 데 사용됩니다. vLoopUp 수식을 사용하여 슬라이서의 값을 그룹화합니다.
initLookupTable = sheet => {
let lookUpRowIndex = -1,
lookUpColIndex = 0;
let row = lookUpRowIndex;
sheet.getCell(++row, lookUpColIndex).text("Lookup");
sheet.getCell(row, lookUpColIndex + 1).text("Category");
sheet.getCell(++row, lookUpColIndex).formula("-90");
sheet.getCell(row, lookUpColIndex + 1).text("Current");
sheet.getCell(++row, lookUpColIndex).text("1");
sheet.getCell(row, lookUpColIndex + 1).text("[1-30]");
sheet.getCell(++row, lookUpColIndex).text("31");
sheet.getCell(row, lookUpColIndex + 1).text("[31-60]");
sheet.getCell(++row, lookUpColIndex).text("61");
sheet.getCell(row, lookUpColIndex + 1).text("[61-90]");
sheet.getCell(++row, lookUpColIndex).text("91");
sheet.getCell(row, lookUpColIndex + 1).text("91+");
};
시트는 다음과 같습니다.
6. 통합 문서에 데이터가 있으면, 테이블을 사용하여 슬라이서 시트를 만들어 사용자 선택에 따라 데이터를 필터링하도록 설정합니다.
initSlicerSheet = sheet => {
this.addReportHeader(sheet);
sheet.setRowCount(this.state.records.length + 20);
sheet.setColumnCount(20);
let tableRowIndex = 4;
let table = sheet.tables.addFromDataSource(
"records",
tableRowIndex,
0,
this.state.records
);
sheet.setColumnWidth(0, 180);
sheet.setColumnWidth(1, 120);
sheet.setColumnWidth(2, 120);
sheet.setColumnWidth(3, 120);
sheet.setColumnWidth(4, 150);
sheet.setColumnWidth(5, 80);
sheet.setColumnWidth(6, 120);
sheet.tables.resize(
table.name(),
new GC.Spread.Sheets.Range(tableRowIndex, 0,
this.state.records.length, 7)
);
//#region Add Tables
let spreadNS = GC.Spread.Sheets;
let customerCol = new spreadNS.Tables.TableColumn();
customerCol.name("Customer");
customerCol.dataField("Customer");
let invoiceIDCol = new spreadNS.Tables.TableColumn();
invoiceIDCol.name("Invoice #");
invoiceIDCol.dataField("Invoice Number");
let invoiceDtCol = new spreadNS.Tables.TableColumn();
invoiceDtCol.name("Invoice Date");
invoiceDtCol.dataField("Invoice Date");
let balanceCol = new spreadNS.Tables.TableColumn();
balanceCol.name("Balance");
balanceCol.dataField("Amount");
let dueDateCol = new spreadNS.Tables.TableColumn();
dueDateCol.name("Due Date");
dueDateCol.dataField("Due Date");
let daysLateCol = new spreadNS.Tables.TableColumn();
daysLateCol.name("DaysLate");
let cateogoryCol = new spreadNS.Tables.TableColumn();
cateogoryCol.name("Category");
table.bindColumns([
customerCol,
invoiceIDCol,
invoiceDtCol,
dueDateCol,
balanceCol,
daysLateCol,
cateogoryCol
]);
table.setColumnDataFormula(5, "=Today() - [Due Date] ");
table.highlightLastColumn(false);
table.setColumnDataFormula(
6,
`=VLOOKUP([@DaysLate],LookupTable!$A$1:$B$6,2)`
);
let categorySlicer = sheet.slicers.add(
"categorySlicer",
table.name(),
"Category"
);
categorySlicer.position(new GC.Spread.Sheets.Point(850, 100));
categorySlicer.style(GC.Spread.Sheets.Slicers.SlicerStyles.dark1());
let customerSlicer = sheet.slicers.add(
"customerSlicer",
table.name(),
"Customer"
);
customerSlicer.position(new GC.Spread.Sheets.Point(850, 400));
customerSlicer.style(GC.Spread.Sheets.Slicers.SlicerStyles.dark1());
sheet.setColumnVisible(6, false);
sheet.getRange(-1, 5, -1, 1).formatter(new
NegativeValueFormatter());
sheet.getRange(-1, 4, -1, 1).formatter("$#,#");
sheet.getRange(-1, 2, -1, 6,
GC.Spread.Sheets.SheetArea.viewport).hAlign(GC.Spread.Sheets.Horizontal
Align.right);
sheet.getRange(-1, 0, -1, 1,
GC.Spread.Sheets.SheetArea.viewport).hAlign(GC.Spread.Sheets.Horizontal
Align.left);
sheet.getRange(1, 2, 1, 2,
GC.Spread.Sheets.SheetArea.viewport).vAlign(GC.Spread.Sheets.Horizontal
Align.center);
sheet.getRange(4, 1, 1, 5,
GC.Spread.Sheets.SheetArea.viewport).hAlign(GC.Spread.Sheets.Horizontal
Align.center);
7. 값을 기준으로 빨간색, 녹색 및 주황색으로 일 수를 색칠하는 몇 가지 규칙을 만듭니다.
var cfs = sheet.conditionalFormats;
var style = new GC.Spread.Sheets.Style();
style.foreColor = "green";
cfs.addCellValueRule(
GC.Spread.Sheets.ConditionalFormatting.ComparisonOperators.lessThan,
30,
0,
style,
[new GC.Spread.Sheets.Range(-1, 5, -1, 1)]
);
style = new GC.Spread.Sheets.Style();
style.foreColor = "red";
cfs.addCellValueRule(GC.Spread.Sheets.ConditionalFormatting.ComparisonO
perators.greaterThan,
90,
0,
style,
[new GC.Spread.Sheets.Range(-1, 5, -1, 1)]
);
var lessThanstyle = new GC.Spread.Sheets.Style();
lessThanstyle.foreColor = "orange";
cfs.addCellValueRule(
GC.Spread.Sheets.ConditionalFormatting.ComparisonOperators.between,
31,
90,
lessThanstyle,
[new GC.Spread.Sheets.Range(-1, 5, -1, 1)]
);
cfs.addRule(dataBarRule);
};
8. 위의 시트에서 숨겨진 열 (5열)을 기반으로 슬라이서를 추가하는 코드는 다음과 같습니다.
let categorySlicer = sheet.slicers.add(
"categorySlicer",
table.name(),
"Category"
);
categorySlicer.position(new GC.Spread.Sheets.Point(850, 100));
categorySlicer.style(GC.Spread.Sheets.Slicers.SlicerStyles.dark1());
let customerSlicer = sheet.slicers.add(
"customerSlicer",
table.name(),
"Customer"
);
customerSlicer.position(new GC.Spread.Sheets.Point(850, 400));
customerSlicer.style(GC.Spread.Sheets.Slicers.SlicerStyles.dark1());
전체 슬라이서 워크 시트의 스타일과 서식을 설정하려면 다음과 같이 설정합니다.
addReportHeader = sheet => {
sheet.setColumnCount(this.COLS);
sheet.setRowCount(10000);
sheet
.getCell(1, 0)
.text(this.state.title)
.font("bold normal 20px normal")
.vAlign(GC.Spread.Sheets.VerticalAlign.center);
sheet.addSpan(0, 0, 1, 2);
sheet
.getCell(0, 0)
.text(this.state.organizaionName)
.font("bold normal 20px normal")
.vAlign(GC.Spread.Sheets.VerticalAlign.center);
sheet.addSpan(1, 0, 1, 2);
sheet
.getCell(1, 2)
.text("As of:")
.font("bold normal 15px normal");
sheet
.getCell(1, 3)
.text(this.state.dateGeneratedOn)
.formatter(this.state.dateFormat)
.font("bold normal 15px normal");
sheet.setRowHeight(0, 40);
sheet.setRowHeight(1, 28);
sheet.setColumnWidth(0, 150);
sheet.setColumnWidth(1, 120);
sheet.setColumnWidth(2, 120);
sheet.setColumnWidth(3, 120);
sheet.setColumnWidth(4, 80);
sheet.setColumnWidth(5, 80);
sheet.setColumnWidth(6, 80);
sheet.setColumnWidth(7, 80);
sheet.setColumnWidth(8, 80);
sheet.setColumnWidth(9, 80);
sheet.setColumnWidth(10, 80);
sheet.setColumnWidth(11, 80);
let defaultStyle = new GC.Spread.Sheets.Style();
defaultStyle.foreColor = "Black";
defaultStyle.hAlign = GC.Spread.Sheets.HorizontalAlign.center;
sheet.setDefaultStyle(defaultStyle);
};
9. 데이터 막대 규칙을 'Balance' 열에 적용합니다. 이 열에는 셀의 금액에 대한 데이터 막대가 표시됩니다.
var dataBarRule = new
GC.Spread.Sheets.ConditionalFormatting.DataBarRule(GC.Spread.Sheets.Con
ditionalFormatting.ScaleValueType.Number, 500,
GC.Spread.Sheets.ConditionalFormatting.ScaleValueType.Number, 12000,
"#6891c8", [new GC.Spread.Sheets.Range(-1,4,-1,1)]);
dataBarRule.showBorder(true);
dataBarRule.borderColor("#6891c8");
dataBarRule.dataBarDirection(GC.Spread.Sheets.ConditionalFormatting.Bar
Direction.LeftToRight);
dataBarRule.axisPosition(GC.Spread.Sheets.ConditionalFormatting.DataBar
AxisPosition.Automatic);
cfs.addRule(dataBarRule);
10. 위 코드로 생성된 컴포넌트를 렌더링하는 코드는 다음과 같습니다.
render() {
return (
<div>
<SpreadSheets
hostStyle={this.hostStyle}
workbookInitialized={this.initSpread.bind(this)}
>
<Worksheet name="Report with Slicer" />
<Worksheet name="LookupTable" />
<Worksheet name="Aging Report Table" />
</SpreadSheets>
</div>
);
}
}
export default SlicerComponent;
보고서의 결과는 다음과 같습니다.
이미지에서 알 수 있듯이 Spread.Sheets에는 두 가지 슬라이서가 있습니다. 하나는 '카테고리'용이고 다른 하나는 '고객'용입니다. 사용자는 슬라이서 카테고리 또는 고객을 클릭 할 수 있으며 테이블에는 데이터 시트의 재무 데이터에서 필터링 된 레코드가 표시됩니다.
'DaysLate' 열에는 빨강, 녹색 및 주황색의 다른 색상으로 데이터가 표시됩니다. 빨간색은 90 일보다 오래된 인보이스이고, 주황색은 30일 이상 90일 미만인 인보이스, 녹색은 30일 미만의 인보이스입니다.
툴바에는 상단에 인쇄 및 저장 버튼도 있습니다. 이 버튼을 사용하여 보고서를 인쇄하고 보고서를 Excel 형식으로 내보낼 수 있습니다.
재무 데이터로 작업하면서 Spread.Sheets에서 사용할 수 있는 다른 옵션에 대해 더 알아보세요.
댓글목록
등록된 댓글이 없습니다.