# 빈 데이터 채우기

## Content

**빈 데이터 채우기** 기능은 **리스트** 또는 **그룹** **셀** 내부의 데이터셋이 필요할 경우 **지정된 배수**를 충족할 때까지 **빈 행** 또는 **빈 열**로 채워지도록 보장합니다.

## 사용 시나리오

보고서를 생성할 때 개발자들은 레이아웃이 어긋나는 문제를 자주 겪습니다. 예를 들어, 페이지 나누기된 보고서의 마지막 페이지에 예상보다 적은 행이 표시되거나, 그룹화된 섹션에 길이가 서로 다른 블록이 포함되어 Excel/PDF 내보내기 결과가 고르지 않게 보일 수 있습니다.
고정 채우기 개수를 사용하면 이러한 문제를 자동으로 해결할 수 있습니다.

* **일관된 페이지 나누기 및 그룹화**: 각 페이지 또는 데이터 블록(그룹이나 리스트 등)이 고정된 행 또는 열의 배수로 채워져 보고서 전체에서 균일한 구조를 유지합니다.
* **비침습적인 빈 데이터 채우기**: 필터링, 정렬 또는 데이터셋 자체에 영향을 주지 않고 빈 행이나 열이 자동으로 삽입됩니다.
* **깔끔한 출력**: 내보내기 또는 인쇄된 보고서는 모든 블록에서 정돈되고 전문적인 레이아웃을 유지합니다.

## 관련 API

이 기능은 [GC.Spread.Report.TemplateSheet.setTemplateCell](/spreadjs/api/classes/GC.Spread.Report.TemplateSheet#settemplatecell) 메서드를 통해 설정합니다.
`ListCell` 또는 `GroupCell`에 설정할 때 `fixedFillCount` 속성을 사용합니다.

>type=note
> **참고:**
>
> * 값은 **양의 정수**여야 합니다.
> * 기본값은 **1**이며, 이는 추가 채우기가 적용되지 않음을 의미합니다.

```typescript
export type ListCell = DataCellBase & {
    type: 'List';
    fixedFillCount?: number;
    // 다른 속성은 API 참조를 확인하세요
};

export type GroupCell = DataCellBase & {
    type: 'Group';
    fixedFillCount?: number;
    // 다른 속성은 API 참조를 확인하세요
};
```

## 사용 예제

**1단계: Report Sheet 생성**

```javascript
let spread = new GC.Spread.Sheets.Workbook("spreadjs-host");

// 데이터 소스 생성
var sheet = spread.getActiveSheet();
    sheet.tables.add('table1', 0, 0, 8, 5, GC.Spread.Sheets.Tables.TableThemes.light1);
    sheet.setArray(0, 0, [
            ['orderId', 'name', 'employeeId', 'unitPrice', 'quantity'],
            ['A001', 'Pencil', '1', 1.5, 2],
            ['A002', 'Notebook', '1', 5, 1],
            ['A003', 'Eraser', '2', 1, 2],
            ['A004', 'Eraser', '1', 1, 1],
            ['A005', 'Pencil', '2', 1.5, 1],
            ['A006', 'Pencil', '2', 1.5, 2],
            ['A007', 'Notebook', '2', 5, 1]
    ]);
    // table1을 데이터 관리자 테이블로 변환
    sheet.tables.convertToDataTable('table1');

// Template Sheet 생성
const reportSheet = spread.addSheetTab(1, 'report', GC.Spread.Sheets.SheetType.reportSheet);
reportSheet.renderMode('Design');
const templateSheet = reportSheet.getTemplate();

// 템플릿에 값과 바인딩 설정
const columns = ['name','employeeId', 'orderId', 'unitPrice', 'quantity'];
columns.forEach((columnName, i) => {
    templateSheet.setValue(0, i, `${columnName[0].toUpperCase()}${columnName.substring(1)}`);
    templateSheet.setTemplateCell(1, i, {
      type: 'List',
      binding: `table1[${columnName}]`,
    });
});

// 테이블 끝 설정
templateSheet.setValue(2,0,'현재 페이지:');
templateSheet.setFormula(2,1,'=R.CURRENTPAGE()');
templateSheet.setValue(2,2,'전체 페이지:');
templateSheet.setFormula(2,3,'=R.PAGESCOUNT()');

// 템플릿에 테두리 스타일 설정
const style = new GC.Spread.Sheets.Style();
style.borderTop = new GC.Spread.Sheets.LineBorder("black", GC.Spread.Sheets.LineStyle.thin);
style.borderBottom = new GC.Spread.Sheets.LineBorder("black", GC.Spread.Sheets.LineStyle.thin);
templateSheet.getRange('A:E').setStyle(style);

// 페이지네이션 설정
templateSheet.setPaginationSetting({    
   rowPagination: {       
        paginationDataCell: 'C2',        
        rowCountPerPage: 4,
   },    
   titleRow: {
        start: 0,
        end: 0,
   },
   endRow: {
        start: 2,
        end: 2,
   },
});

// 보고서 새로 고침
reportSheet.refresh();
reportSheet.renderMode('Preview');
```

![image](https://gcdocumentsitekrblob.blob.core.windows.net/document-site-files/images/36b63360-fb01-457c-a448-c3ce32aaf454/image-20251216.152c43.png?width=500)

```javascript
reportSheet.renderMode('PaginatedPreview');
```

![image](https://gcdocumentsitekrblob.blob.core.windows.net/document-site-files/images/36b63360-fb01-457c-a448-c3ce32aaf454/image-20251216.3bf0ef.png?width=500)

보고서에는 총 7개의 레코드가 포함되어 있습니다.
`rowCountPerPage`가 4로 설정되어 있으므로 데이터는 2페이지로 나뉩니다.

* 첫 번째 페이지에는 4개의 행이 표시됩니다.
* 나머지 3개의 행은 두 번째 페이지에 표시됩니다.

**2단계: Fixed Fill Count 설정**

>type=note
> **참고 사항:**
>
> * **세로(행)** 및 **가로(열)** 확장 모두에서 작동합니다.
> * 채우기는 항상 **부모 노드를 기준**으로 처리됩니다.

**시나리오 1**: 리스트 열에 `fixedFillCount` 적용

* **설정**: `Name` 열에 `fixedFillCount = 2` 설정
* **효과**:
    * `Name` 열이 7개 리스트 → 8개 리스트로 확장됩니다.
    * 테이블이 7행 → 8행으로 확장됩니다.

```javascript
reportSheet.renderMode('Design');

templateSheet.setTemplateCell(1, 0, {
    type: 'List',
    binding: 'table1[name]',
    fixedFillCount: 2
});

reportSheet.refresh();
reportSheet.renderMode('Preview');
```

![image](https://gcdocumentsitekrblob.blob.core.windows.net/document-site-files/images/36b63360-fb01-457c-a448-c3ce32aaf454/image-20251216.993f89.png?width=500)

```javascript
reportSheet.renderMode('PaginatedPreview');
```

![image](https://gcdocumentsitekrblob.blob.core.windows.net/document-site-files/images/36b63360-fb01-457c-a448-c3ce32aaf454/image-20251216.0d7966.png?width=500)

**시나리오 2**: 그룹 열에 `fixedFillCount` 적용

* **설정**: `Name` 열을 그룹으로 정의하고 `fixedFillCount = 2` 설정
* **효과**:
    * `Name` 열이 3개 그룹 → 4개 그룹으로 확장됩니다.
    * 테이블이 7행 → 8행으로 확장됩니다.

```javascript
reportSheet.renderMode('Design');

templateSheet.setTemplateCell(1, 0, {
    type: 'Group',
    binding: 'table1[name]',
    fixedFillCount: 2
});

reportSheet.refresh();
reportSheet.renderMode('Preview');
```

![image](https://gcdocumentsitekrblob.blob.core.windows.net/document-site-files/images/36b63360-fb01-457c-a448-c3ce32aaf454/image-20251216.f7d239.png?width=500)

```javascript
reportSheet.renderMode('PaginatedPreview');
```

![image](https://gcdocumentsitekrblob.blob.core.windows.net/document-site-files/images/36b63360-fb01-457c-a448-c3ce32aaf454/image-20251216.4a8bf9.png?width=500)

## 디자이너 사용

SpreadJS 디자이너의 **Report Cell** 속성 패널에 있는 **Fixed Fill Count** 옵션을 사용하여 템플릿 셀의 `fixedFillCount` 속성을 설정할 수도 있습니다.
![image](https://gcdocumentsitekrblob.blob.core.windows.net/document-site-files/images/36b63360-fb01-457c-a448-c3ce32aaf454/image-20251216.2df155.png?width=400)

기본값은 1입니다. 위/아래 화살표를 사용하거나 숫자를 직접 입력하여 값을 변경할 수 있습니다.
![image](https://gcdocumentsitekrblob.blob.core.windows.net/document-site-files/images/36b63360-fb01-457c-a448-c3ce32aaf454/image-20251216.dd86e7.png?width=1000)