! 제품 버전을 정확하게 입력해 주세요.
제품 버전이 정확하게 기재되어 있지 않은 경우,
최신 버전을 기준으로 안내 드리므로
더욱 빠르고 명확한 안내를 위해
제품 버전을 정확하게 입력해 주세요!

JavaScript 앱에서 재무 보고서 작성하는 방법 > 블로그 & Tips

본문 바로가기

SpreadJS

블로그 & Tips

JavaScript 앱에서 재무 보고서 작성하는 방법

페이지 정보

작성자 GrapeCity 작성일 2019-07-03 00:00 조회 2,624회 댓글 0건

본문

첨부파일

대부분의 재무 관련 애플리케이션에 대한 일반적인 요구 사항은 보고서를 만들어야 한다는 것입니다. 이는 손익 계산서(P&L), 예산 책정, 예측 등 그 이상의 모든 것을 포함할 수 있습니다. 이 모든 것의 공통적인 요인은 데이터이며, 스프레드시트를 사용하여 숫자를 빠르게 처리해야 한다는 것입니다.


이 포스팅에서는 엔터프라이즈 JavaScript 스프레드시트인 SpreadJS 를 사용하여 최종 사용자가 해당 데이터를 쉽게 필터링 할 수있는 방법에 중점을 둔 전형적인 장기 미지급금 보고서를 작성하는 방법을 보여줍니다.


이 보고서에는 미결제 금액이 모두 고객 정보와 함께 표시됩니다. 그런 다음 데이터를 필터링하고 해당 고객의 세부 정보와 함께 과거 지불 기한을 표시합니다. 이 유형의 보고서 사용자는 관리자, 회계사 또는 이사가 될 수 있습니다.



 


재무 보고서 작성


SpreadJS의 내장 및 사용자 정의 기능을 사용하여 이 보고서를 작성할 수 있는 방법에는 아래와 같이 네 가지가 있습니다.


  1. 슬라이서 사용
  2. 맞춤 필터 사용
  3. 배열 수식 사용
  4. 테이블 필터 사용


(참고 : 이 보고서를 작성하기 위해 정적 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에서 사용할 수 있는 다른 옵션에 대해 더 알아보세요.



  • 페이스북으로 공유
  • 트위터로  공유
  • 링크 복사
  • 카카오톡으로 보내기

댓글목록

등록된 댓글이 없습니다.

메시어스 홈페이지를 통해 제품에 대해서 더 자세히 알아 보세요!
홈페이지 바로가기

태그1

인기글

더보기
  • 인기 게시물이 없습니다.
메시어스 홈페이지를 통해 제품에 대해서 더 자세히 알아 보세요!
홈페이지 바로가기
이메일 : sales-kor@mescius.com | 전화 : 1670-0583 | 경기도 과천시 과천대로 7길 33, 디테크타워 B동 1107호 메시어스(주) 대표자 : 허경명 | 사업자등록번호 : 123-84-00981 | 통신판매업신고번호 : 2013-경기안양-00331 ⓒ 2024 MESCIUS inc. All rights reserved.