[]
        
(Showing Draft Content)

테이블 시트 뷰

테이블 시트 뷰는 테이블 시트의 중심이며, 가져온 데이터 소스의 필드들로 구성됩니다. 이는 데이터 열을 풍부하게 하고 더 많은 기능을 부여하는 데 사용됩니다.



위의 흐름도 이미지에서 볼 수 있듯이, 테이블 시트 뷰는 다음과 같은 방식으로 표시될 수 있습니다:

  • 테이블 열(Table columns): 필드에서 직접 생성되는 기본 열로, 필드 이름 속성만 가지며 기본 보기로 사용됩니다.

  • 뷰 열(View columns): 스타일, 포맷 등 다양한 속성으로 사용자 정의할 수 있는 고급 열로, caption, style, width, headerStyle 등의 속성을 통해 테이블 시트 뷰에 렌더링됩니다.

테이블 시트 뷰는 다양한 IColumn 속성을 설정하여 사용자 지정할 수 있습니다. 예를 들어, 헤더 스타일, 헤더 핏 모드, 조건부 서식, 데이터 유효성 검사, 그리고 셀 타입 및 드롭다운과 같은 열 스타일을 설정할 수 있습니다.


열 표시 값

기존 열 데이터를 대신하여 사용자 정의 값을 표시하려면, 열의 style 속성에 포함된 formatter 수식을 사용할 수 있습니다. 이 수식은 [@] 연산자를 이용해 현재 행의 전체 데이터를 참조할 수 있습니다.

테이블 시트 열에서 사용자 지정 값을 표시하는 방법은 다음 두 가지가 있습니다:

  • formatter 안에 수식 사용

    =[@contactTitle] & ":" & [@employee.FirstName] & " " & [@employee.LastName]

  • formatter 안에 템플릿 수식 사용

    {{[@contactTitle]}} : {{=[@employee.FirstName] & " " & [@employee.LastName]}}

column-display-value.png

다음 코드 샘플은 formatter 안의 수식을 사용하여 사용자 정의 열 값을 표시하는 방법을 보여줍니다:

//세일즈 테이블과 고객 테이블 사이 관계 추가
dataManager.addRelationship(salesTable, "customerKey", "myCustomer", customerTable, "customerKey", "mySales");

//사용자 정의 뷰 추가 
customerTable.fetch().then(function () {

var myView = salesTable.addView("myView", [
       { value: "saleKey", width: 100, caption: "Sale Key" },
       { value: "salesPerson", width: 150, caption: "Sales Person" },
       { value: "myCustomer", width: 350, caption: "Customer Information", style: { formatter: '=[@myCustomer.primaryContact] & " " & [@myCustomer.postalCode]' } },
       { value: "address", width: 350, caption: "Address" },
       { value: "stockItem", width: 350, caption: "Stock Item" },
       { value: "quantity", width: 100, caption: "Quantity" }
          ]);


열 헤더 스타일

열 헤더 스타일은 뷰의 headerStyle 속성에 HeaderStyleOptions 를 정의하여 사용자 지정할 수 있습니다. HeaderStyleOptions는 배경색, 테마 글꼴, 자동 줄 바꿈 등과 같은 옵션을 포함합니다.



다음 코드 샘플은 테이블 시트 뷰에서 열 헤더 스타일을 설정하는 방법을 보여줍니다:

// a열 헤더에 대한 스타일 정의 및 addView() 메서드를 사용하여 뷰에 추가하는 동안 할당
var headerStyle = {
    font: "italic bold 13pt Calibri",
    borderTop: {
        color: "red",
        style: "thick"
    },
    borderLeft: {
        color: "red",
        style: "thin"
    },
    borderRight: {
        color: "red",
        style: "thin"
    },
    borderBottom: {
        color: "red",
        style: "thin"
    }
};


//테이블 시트에 뷰 바인딩
customerTable.fetch().then(function () {
    var view = customerTable.addView("myView", [
        { value: "customerKey", width: 130, headerStyle: headerStyle, caption: "Customer Key" },// set the style of column header using headerStyle property
        { value: "customer", width: 200, headerStyle: headerStyle, caption: "Customer" }, 
        { value: "billToCustomer", width: 200, headerStyle: headerStyle, caption: "Bill To Customer" },
        { value: "category", width: 120, headerStyle: headerStyle, caption: "Category" },
        { value: "buyingGroup", width: 180, headerStyle: headerStyle, caption: "Buying Group" },
        { value: "primaryContact", width: 170, headerStyle: headerStyle, caption: "Primary Contact" },
        { value: "postalCode", width: 120, headerStyle: headerStyle, caption: "Postal Code" },
        { value: "validFrom", width: 150, headerStyle: headerStyle, caption: "Valid From" },
        { value: "validTo", width: 180, headerStyle: headerStyle, caption: "Valid To" }

    ]);
    //테이블의 모든 기본 열을 가진 뷰
    sheet.setDataView(view);
});


열 헤더 맞춤 모드

테이블 시트 뷰에서 지정된 열의 헤더 레이아웃을 적절히 표시할 수 있도록 열 헤더 맞춤 모드를 설정할 수 있습니다.

열 데이터의 내용 길이는 짧지만 헤더 캡션이 길거나 일부 열이 관계를 가질 때 유용합니다.


headerFit 뷰 옵션 속성을 사용하여 다음과 같이 세 가지 유형의 헤더 맞춤 모드를 설정할 수 있습니다.

  • Normal: 열 헤더 텍스트 방향이 수평이며 왼쪽에서 오른쪽으로 표시됩니다. 기본 헤더 맞춤 모드입니다.



  • Vertical: 열 헤더 텍스트 방향이 수직이며 위에서 아래로 표시됩니다.




  • Stack: 열 너비가 열 헤더 텍스트를 표시하기에 충분하지 않을 때 헤더가 위에서 아래로 쌓여 표시됩니다.



    Stack 헤더 맞춤 모드는 인접한 열과 함께 표시될 경우 Vertical 모드와 교차하여 함께 표시됩니다.




테이블 시트 뷰에서 defaultStackRowHeight 옵션을 사용하여 Stack 행 높이를 설정할 수 있습니다. 값이 null일 경우 평균 행 높이를 계산하며, 유효한 숫자를 지정하면 위에서 아래로 그 값을 기준으로 높이를 계산합니다.


다음 코드 샘플은 열 헤더 맞춤 모드를 설정하고 테이블 시트 뷰에서 행 높이를 조정하는 방법을 보여줍니다.

//tablesheet에 뷰 바인딩
myTable.fetch().then(function () {
    var view = myTable.addView("myView", [
        { value: "saleKey", caption: "Sale Key", headerFit: "stack", headerStyle: headerStyle },// set headerFit를 스택에 설정
        { value: "cityKey", caption: "City Key", headerFit: "stack", headerStyle: headerStyle },
        { value: "stockItemKey", width: 50, caption: "Stock Item Key", headerFit: "stack", headerStyle: headerStyle },
        { value: "invoiceDateKey", width: 120, caption: "Invoice Date Key", headerFit: "vertical", headerStyle: headerStyle },
        { value: "deliveryDateKey", width: 120, caption: "Delivery Date Key", headerFit: "vertical", headerStyle: headerStyle },
        { value: "salesPerson", width: 150, caption: "Sales Person", headerFit: "vertical", headerStyle: headerStyle },
        { value: "address", caption: "Address", width: 300, headerFit: "normal", headerStyle: headerStyle }

    ]);
    sheet.setDataView(view);
    sheet.options.defaultStackRowHeight = 30;
    sheet.setDefaultRowHeight(220, 1);
});

참고: 행 높이로 전체 캡션을 표시할 수 없는 경우, 해당 열의 스택된 헤더는 잘려서 표시될 수 있습니다. 이 경우 setDefaultRowHeight 메서드를 사용하여 조정할 수 있습니다.

셀 유형 및 드롭다운

테이블 시트 뷰에서 다양한 셀 유형과 드롭다운을 설정하여 정보가 표시되는 방식을 지정하고, 데이터를 보다 쉽게 선택할 수 있도록 도와줍니다.


Cell Types and Dropdowns in SpreadJS TableSheet


테이블 시트에서 지원하는 셀 유형과 드롭다운은 다음과 같습니다:

  • 셀 유형 – 체크박스, 콤보박스, 하이퍼링크, 라디오 버튼 리스트, 체크박스 리스트, 범위 템플릿

  • 드롭다운 – 색상 선택기, 날짜 선택기, 시간 선택기, 월 선택기, 리스트, 슬라이더, 계산기, 워크플로우 리스트, 다중 열

다음 코드 샘플은 테이블 시트 뷰에 셀 유형과 드롭다운을 추가하는 방법을 보여줍니다.

//  RadioButtonList
var radioButtonListStyle = new GC.Spread.Sheets.Style();
var cellTypeRadioButtonList = new GC.Spread.Sheets.CellTypes.RadioButtonList();
cellTypeRadioButtonList.items([
    { text: "Tailspin Toys (Head Office)", value: "Tailspin Toys (Head Office)" },
    { text: "Wingtip Toys (Head Office)", value: "Wingtip Toys (Head Office)" },
]);
radioButtonListStyle.cellType = cellTypeRadioButtonList;

//  ButtonList
var buttonListStyle = new GC.Spread.Sheets.Style();
var buttonListCellType = new GC.Spread.Sheets.CellTypes.ButtonList();
buttonListCellType.items([
    { text: "Tailspin Toys", value: "Tailspin Toys" },
    { text: "Wingtip Toys", value: "Wingtip Toys" },
]);
buttonListStyle.cellType = buttonListCellType;

// Date DropDown
var dateStyle = {};
dateStyle.cellButtons = [
    {
        imageType: "dropdown",
        command: "openDateTimePicker",
        useButtonStyle: true,
    }
];
dateStyle.dropDowns = [
    {
        type: "dateTimePicker",
        option: {
            showTime: true
        }
    }
];

//tablesheet에 뷰 바인딩
customerTable.fetch().then(function () {
    var view = customerTable.addView("myView", [
        { value: "customerKey", width: 120, caption: "Customer Key" },
        { value: "billToCustomer", width: 400, caption: "Bill To Customer", style: radioButtonListStyle },
        { value: "buyingGroup", width: 250, caption: "Buying Group", style: buttonListStyle },
        { value: "primaryContact", width: 170, caption: "Primary Contact" },
        { value: "validFrom", width: 190, caption: "Valid From", style: dateStyle }
    ]);
    //테이블의 모든 기본 열을 가진 뷰
    sheet.setDataView(view);
});


열 캡션 다중 헤더

테이블 시트 뷰에서는 여러 열을 공통 헤더 아래로 그룹화할 수 있도록 열 캡션을 설정할 수 있습니다. 이는 관련 정보를 공통 범주로 묶어 보다 체계적으로 표현하는 데 도움이 됩니다.

addView 메서드에 전달되는 columnInfos 매개변수의 "caption" 속성은 문자열 배열을 받아 테이블 시트의 열 헤더를 여러 행으로 설정할 수 있습니다. 동일한 캡션 값을 가진 열들은 행 방향과 열 방향으로 자동 병합됩니다.

다음 예제에서는 Customer Key, Customer Name, Bill To Customer, Primary Contact와 같은 고객 정보를 “Customer Information”이라는 공통 캡션 아래에 그룹화하여 표시하며, 각 열의 기존 캡션은 유지됩니다. 이와 유사하게 제품 유효 기간도 하나의 공통 헤더 아래 표시할 수 있습니다.



다음 코드 샘플은 테이블 시트 뷰에서 여러 열에 동일한 캡션을 설정하는 방법을 보여줍니다.

Ask ChatGPT

//tablesheet 뷰에 바인딩
myTable.fetch().then(function () {
   var view = myTable.addView("myView", [
       { value: "customerKey", width: 130, caption: ["Customer Information", "Customer Key"] }, // Set string array to caption
       { value: "customer", width: 200, caption: ["Customer Information", "Customer"] },
       { value: "billToCustomer", width: 200, caption: ["Customer Information", "Bill To Customer"] },
       { value: "primaryContact", width: 170, caption: ["Customer Information", "Primary Contact"] },
       { value: "validFrom", width: 150, caption: ["Validity", "Valid From"], style: { formatter: "MM/dd/yyyy"} },
       { value: "validTo", width: 180, caption: ["Validity", "Valid To"], style: { formatter: "MM/dd/yyyy"} }
   ]);
   sheet.setDataView(view);
});

SpreadJS 디자이너에서 다중 헤더 열 캡션을 적용하는 방법은 테이블 시트 디자인 모드를 참고하시기 바랍니다.


자유 헤더 영역

테이블 시트 뷰에는 시트를 설명하거나 수식과 스파크라인을 사용하여 집계 데이터를 표시할 수 있는 헤더 영역을 추가할 수 있습니다. 자유 헤더 영역은 테이블 시트 뷰 상단에 할당되며, 아래 이미지와 같이 하나 이상의 행으로 구성될 수 있습니다.


열 헤더의 자유 레이아웃 영역을 구성하려면 applyFreeHeaderArea 메서드를 사용합니다. 이 메서드는 toJSON 메서드를 사용하여 생성한 워크시트 JSON을 인수로 받습니다. 시트 이름이 포함된 수식을 유지하려면 JSON을 생성하기 전에 keepUnknownFormulas 옵션을 true로 설정해야 합니다.


다음 코드 샘플은 템플릿 워크시트를 생성하고 테이블 시트 뷰에 자유 헤더 영역을 적용하는 방법을 보여줍니다.

Ask ChatGPT

//tablesheet에 뷰 바인딩
myTable.fetch().then(function () {
   var view = myTable.addView("myView", [

       { value: "stockItem", width: 300, caption: "Stock Item", headerStyle: headerStyle },
       { value: "unitPrice", width: 120, caption: "Unit Price", headerStyle: headerStyle },
       { value: "taxRate", width: 120, caption: "Tax Rate", headerStyle: headerStyle },
       { value: "recommendedRetailPrice", width: 190, caption: "Recommended Retail Price", style: currencyFormatter, headerStyle: headerStyle, conditionalFormats: [dataBarRule1] },
       { value: "=([@unitPrice] * [@taxRate])/100 + [@unitPrice]", caption: "Actual Retail Price", style: currencyFormatter, width: 190, headerStyle: headerStyle, conditionalFormats: [dataBarRule2] }, // 계산된 열 

   ]);

   // 자유 헤더 영역 json에 대한 템플릿 시트 생성
   var templateSheet = new GC.Spread.Sheets.Worksheet();
   templateSheet.options.keepUnknownFormulas = true;
   var currencyFormatterStyle = new GC.Spread.Sheets.Style();
   currencyFormatterStyle.formatter = formatter;
   currencyFormatterStyle.hAlign = GC.Spread.Sheets.HorizontalAlign.left;
   templateSheet.setRowCount(6);
   var freeHeaderAreaStyle = new GC.Spread.Sheets.Style();
   freeHeaderAreaStyle.backColor = Colors.white;

   templateSheet.setValue(0, 0, "Retail Price Analysis");
   templateSheet.getCell(0, 0).hAlign(GC.Spread.Sheets.HorizontalAlign.left).font("bold 30px \"Calibri\"");
   templateSheet.addSpan(0, 0, 1, 5);
   var titleStyle = new GC.Spread.Sheets.Style();
   titleStyle.backColor = Colors.lightGreen;
   titleStyle.foreColor = Colors.black;
   templateSheet.setStyle(0, -1, titleStyle);
   templateSheet.setRowHeight(0, 80);

   templateSheet.getCell(1, 0)
       .value("Whether a Stock Item's Actual Retail Price is either under or over Recommended Retail Price is automatically calculated.")
       .font("italic 12px \"Calibri\"")
       .foreColor("rgb(120,120,120)")
       .textIndent(2);
   templateSheet.setStyle(1, -1, titleStyle);
   templateSheet.addSpan(1, 0, 1, 5);

   var headerDescriptionStyle = new GC.Spread.Sheets.Style();
   headerDescriptionStyle.backColor = Colors.lightGreen;
   headerDescriptionStyle.borderBottom = new GC.Spread.Sheets.LineBorder(Colors.middleGreen, GC.Spread.Sheets.LineStyle.thick);
   templateSheet.setStyle(2, -1, headerDescriptionStyle);
   templateSheet.addSpan(2, 0, 1, 5);
   templateSheet.setRowHeight(2, 16);

   templateSheet.setValue(3, 0, "Total Recommended Retail Price");
   templateSheet.getCell(3, 0).hAlign(GC.Spread.Sheets.HorizontalAlign.left).font("bold 14px \"Calibri\"").foreColor(Colors.darkGreen);
   templateSheet.addSpan(3, 0, 1, 2);
   templateSheet.setFormula(3, 2, '=SUM(TableSheet1[Recommended Retail Price])');
   templateSheet.getCell(3, 2).hAlign(GC.Spread.Sheets.HorizontalAlign.left).font("bold 14px \"Calibri\"").foreColor(Colors.darkGreen).formatter(formatter);
   templateSheet.setFormula(3, 3, '=HBARSPARKLINE(ROUND(C4/MAX(C4,C5),2),"' + Colors.darkGreen + '",false)');
   templateSheet.addSpan(3, 3, 1, 2);
   templateSheet.setStyle(3, -1, freeHeaderAreaStyle);

   templateSheet.setValue(4, 0, "Total Actual Retail Price");
   templateSheet.getCell(4, 0).hAlign(GC.Spread.Sheets.HorizontalAlign.left).font("bold 14px \"Calibri\"").foreColor(Colors.brown);
   templateSheet.addSpan(4, 0, 1, 2);
   templateSheet.setFormula(4, 2, '=SUM(TableSheet1[Actual Retail Price])');
   templateSheet.getCell(4, 2).hAlign(GC.Spread.Sheets.HorizontalAlign.left).font("bold 14px \"Calibri\"").foreColor(Colors.brown).formatter(formatter);
   var contentBorderStyle = new GC.Spread.Sheets.Style();
   contentBorderStyle.backColor = Colors.white;
   contentBorderStyle.borderBottom = new GC.Spread.Sheets.LineBorder(Colors.brown, GC.Spread.Sheets.LineStyle.thick);
   templateSheet.setStyle(4, -1, contentBorderStyle);
   templateSheet.setFormula(4, 3, '=HBARSPARKLINE(ROUND(C5/MAX(C4,C5),2),"' + Colors.brown + '",false)');
   templateSheet.addSpan(4, 3, 1, 2);

   templateSheet.setFormula(5, 0, '=IF(C4>C5,"Budget is under Total Recommended Retail Price by","Budget is over Total Recommended Retail Price")');
   templateSheet.getCell(5, 0).hAlign(GC.Spread.Sheets.HorizontalAlign.left).font("bold 14px \"Calibri\"").foreColor(Colors.black);
   templateSheet.addSpan(5, 0, 1, 2);
   templateSheet.setFormula(5, 2, '=C4-C5');
   templateSheet.getCell(5, 2).hAlign(GC.Spread.Sheets.HorizontalAlign.left).font("bold 14px \"Calibri\"").formatter(formatter).foreColor(Colors.black);
   templateSheet.setStyle(5, -1, freeHeaderAreaStyle);
   templateSheet.addSpan(5, 2, 1, 3);

   let template = templateSheet.toJSON();
   sheet.applyFreeHeaderArea(template);
   sheet.setDataView(view);
});

자유 헤더는 셀에서 수식을 편집하거나 생성할 때 수식 입력 상자를 지원합니다. 이를 통해 테이블 시트 열, 열 범위, 여러 열, 교차 시트 열에 대한 선택 작업을 수행할 수 있습니다.


SpreadJS 디자이너에서 자유 헤더 영역을 적용하는 방법은 테이블 시트 디자인 모드를 참고하시기 바랍니다.