xlkit 1.0.4 → 1.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +96 -9
- package/dist/Sheetflow.d.ts.map +1 -1
- package/dist/Sheetflow.js +134 -23
- package/dist/types.d.ts +8 -2
- package/dist/types.d.ts.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -73,7 +73,22 @@ await createWorkbook().addSheet(userSheet, users).save('users.xlsx');
|
|
|
73
73
|
| `format` | `string` \| `Function` | 数値/日付のフォーマット文字列(例: `'$#,##0'`, `'yyyy-mm-dd'`)または変換関数。 |
|
|
74
74
|
| `style` | `Style` \| `Function` | 列全体のスタイル、または値に応じた条件付きスタイル関数。 |
|
|
75
75
|
|
|
76
|
-
### 2.
|
|
76
|
+
### 2. 自動列幅調整 (`autoWidth`)
|
|
77
|
+
|
|
78
|
+
列幅の自動計算ロジックを微調整できます。
|
|
79
|
+
|
|
80
|
+
```typescript
|
|
81
|
+
const sheet = defineSheet<User>({
|
|
82
|
+
// ...
|
|
83
|
+
autoWidth: {
|
|
84
|
+
padding: 4, // デフォルト: 2
|
|
85
|
+
headerIncluded: true, // ヘッダーの長さも考慮するか
|
|
86
|
+
charWidthConstant: 1.5 // 文字幅の係数(デフォルト: 1.2)
|
|
87
|
+
}
|
|
88
|
+
});
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### 3. 罫線 (`borders`)
|
|
77
92
|
|
|
78
93
|
シート全体の罫線プリセットを `borders` プロパティで指定できます。
|
|
79
94
|
|
|
@@ -91,9 +106,35 @@ const sheet = defineSheet<User>({
|
|
|
91
106
|
|
|
92
107
|
個別のセルに罫線を設定したい場合は、`style` プロパティ内の `border` で詳細に指定可能です。
|
|
93
108
|
|
|
94
|
-
###
|
|
109
|
+
### 4. スタイル (`style`)
|
|
95
110
|
|
|
96
|
-
フォント、背景色、配置などを詳細に設定できます。
|
|
111
|
+
フォント、背景色、配置などを詳細に設定できます。
|
|
112
|
+
|
|
113
|
+
| プロパティ | 説明 | 型・値の例 |
|
|
114
|
+
| :--- | :--- | :--- |
|
|
115
|
+
| **`font`** | | |
|
|
116
|
+
| `font.name` | フォント名 | `'Arial'`, `'MS Pゴシック'` |
|
|
117
|
+
| `font.size` | フォントサイズ | `11`, `12` |
|
|
118
|
+
| `font.bold` | 太字 | `true`, `false` |
|
|
119
|
+
| `font.italic` | 斜体 | `true`, `false` |
|
|
120
|
+
| `font.underline` | 下線 | `true`, `'single'`, `'double'` |
|
|
121
|
+
| `font.strike` | 取り消し線 | `true`, `false` |
|
|
122
|
+
| `font.color` | 文字色 | `'#FF0000'` (Hex), `{ argb: 'FFFF0000' }` |
|
|
123
|
+
| **`fill`** | | |
|
|
124
|
+
| `fill.color` | 背景色 (Solid) | `'#FFFF00'` (Hex) ※xlkit独自ショートカット |
|
|
125
|
+
| `fill.type` | 塗りつぶしタイプ | `'pattern'` |
|
|
126
|
+
| `fill.pattern` | パターン種類 | `'solid'`, `'darkGray'`, `'mediumGray'` |
|
|
127
|
+
| **`alignment`** | | |
|
|
128
|
+
| `alignment.horizontal` | 水平方向の配置 | `'left'`, `'center'`, `'right'`, `'justify'` |
|
|
129
|
+
| `alignment.vertical` | 垂直方向の配置 | `'top'`, `'middle'`, `'bottom'` |
|
|
130
|
+
| `alignment.wrapText` | 折り返し表示 | `true`, `false` |
|
|
131
|
+
| `alignment.indent` | インデント | `1`, `2` |
|
|
132
|
+
| `alignment.textRotation` | 文字の回転 | `45`, `90`, `'vertical'` |
|
|
133
|
+
| **`border`** | | |
|
|
134
|
+
| `border.top` | 上の罫線 | `{ style: 'thin', color: { argb: 'FF000000' } }` |
|
|
135
|
+
| `border.left` | 左の罫線 | (同上) |
|
|
136
|
+
| `border.bottom` | 下の罫線 | (同上) |
|
|
137
|
+
| `border.right` | 右の罫線 | (同上) |
|
|
97
138
|
|
|
98
139
|
```typescript
|
|
99
140
|
style: {
|
|
@@ -112,13 +153,21 @@ style: {
|
|
|
112
153
|
wrapText: true
|
|
113
154
|
},
|
|
114
155
|
border: {
|
|
115
|
-
top: { style: 'thin', color: { argb: 'FF000000' } }
|
|
116
|
-
// ...
|
|
156
|
+
top: { style: 'thin', color: { argb: 'FF000000' } }
|
|
117
157
|
}
|
|
118
158
|
}
|
|
119
159
|
```
|
|
120
160
|
|
|
121
|
-
|
|
161
|
+
#### スタイルの優先順位
|
|
162
|
+
|
|
163
|
+
スタイルは以下の順序で適用(上書き)されます(下が優先):
|
|
164
|
+
|
|
165
|
+
1. **行定義 (`rows.style`)**: シート定義で指定した行全体のスタイル
|
|
166
|
+
2. **データ行スタイル (`row.style`)**: データオブジェクトに含まれる `style` プロパティ
|
|
167
|
+
3. **列定義 (`columns.style`)**: 列ごとのスタイル
|
|
168
|
+
4. **条件付き列スタイル**: `columns.style` が関数の場合
|
|
169
|
+
|
|
170
|
+
### 5. ヘッダー設定 (`header`)
|
|
122
171
|
|
|
123
172
|
ヘッダー行のスタイルや構成をカスタマイズできます。
|
|
124
173
|
|
|
@@ -133,7 +182,7 @@ header: {
|
|
|
133
182
|
}
|
|
134
183
|
```
|
|
135
184
|
|
|
136
|
-
###
|
|
185
|
+
### 6. 行スタイル (`rows`)
|
|
137
186
|
|
|
138
187
|
行ごとのスタイル(縞模様など)を定義できます。
|
|
139
188
|
|
|
@@ -155,7 +204,7 @@ header: {
|
|
|
155
204
|
];
|
|
156
205
|
```
|
|
157
206
|
|
|
158
|
-
###
|
|
207
|
+
### 7. ブラウザ環境でのダウンロード
|
|
159
208
|
|
|
160
209
|
ブラウザ環境では、`download()` メソッドを使って簡単にExcelファイルをダウンロードできます。
|
|
161
210
|
|
|
@@ -169,7 +218,7 @@ await createWorkbook().addSheet(sheet, data).download('output.xlsx');
|
|
|
169
218
|
|
|
170
219
|
内部的には`saveToBuffer()`を呼び出してBlobを作成し、自動的にダウンロードを開始します。
|
|
171
220
|
|
|
172
|
-
###
|
|
221
|
+
### 8. タイムアウト設定
|
|
173
222
|
|
|
174
223
|
大量データ処理時のフリーズを防ぐため、`save()`、`saveToBuffer()`、`download()` にはデフォルトで10秒のタイムアウトが設定されています。
|
|
175
224
|
|
|
@@ -186,6 +235,44 @@ await createWorkbook().addSheet(sheet, data).download('output.xlsx', { timeout:
|
|
|
186
235
|
|
|
187
236
|
> **推奨**: 10万行以下のデータであればデフォルト設定で問題ありません。それ以上の大量データを扱う場合は、ファイル分割やストリーミング処理を検討してください。
|
|
188
237
|
|
|
238
|
+
### 9. 制約事項
|
|
239
|
+
|
|
240
|
+
- **予約語**: 列の `key` に `'style'` は使用できません。これは行ごとのスタイル定義プロパティとして予約されています。
|
|
241
|
+
- **シート名**: Excelの仕様により、シート名は31文字以内で、`\ / ? * [ ] :` の文字は使用できません。
|
|
242
|
+
|
|
243
|
+
## 高度な使い方
|
|
244
|
+
|
|
245
|
+
### 複数シートの作成
|
|
246
|
+
|
|
247
|
+
メソッドチェーンを使用して、1つのワークブックに複数のシートを追加できます。
|
|
248
|
+
|
|
249
|
+
```typescript
|
|
250
|
+
await createWorkbook()
|
|
251
|
+
.addSheet(usersSheet, usersData)
|
|
252
|
+
.addSheet(productsSheet, productsData)
|
|
253
|
+
.save('data.xlsx');
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
### TypeScriptによる型安全性
|
|
257
|
+
|
|
258
|
+
ジェネリクスを使用することで、列定義のキーを型安全に保つことができます。
|
|
259
|
+
|
|
260
|
+
```typescript
|
|
261
|
+
interface User {
|
|
262
|
+
id: number;
|
|
263
|
+
name: string;
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
// keyは 'id' | 'name' に型推論され、誤字を防げます
|
|
267
|
+
const sheet = defineSheet<User>({
|
|
268
|
+
name: 'Users',
|
|
269
|
+
columns: [
|
|
270
|
+
{ key: 'id', ... }, // OK
|
|
271
|
+
{ key: 'nmae', ... } // Error: Type '"nmae"' is not assignable to type 'keyof User'
|
|
272
|
+
]
|
|
273
|
+
});
|
|
274
|
+
```
|
|
275
|
+
|
|
189
276
|
## ライセンス
|
|
190
277
|
|
|
191
278
|
MIT
|
package/dist/Sheetflow.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Sheetflow.d.ts","sourceRoot":"","sources":["../src/Sheetflow.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAsB,MAAM,SAAS,CAAC;AAGvD,qBAAa,KAAK;IAChB,OAAO,CAAC,QAAQ,CAAmB;;IAMnC,QAAQ,CAAC,CAAC,EAAE,GAAG,EAAE,QAAQ,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,GAAG,KAAK;
|
|
1
|
+
{"version":3,"file":"Sheetflow.d.ts","sourceRoot":"","sources":["../src/Sheetflow.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAsB,MAAM,SAAS,CAAC;AAGvD,qBAAa,KAAK;IAChB,OAAO,CAAC,QAAQ,CAAmB;;IAMnC,QAAQ,CAAC,CAAC,EAAE,GAAG,EAAE,QAAQ,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,GAAG,KAAK;IAsTzC,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAmBjE,YAAY,CAAC,OAAO,CAAC,EAAE;QAAE,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,UAAU,CAAC;IAajE,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC;CAiBhF;AAED,wBAAgB,cAAc,IAAI,KAAK,CAEtC;AAED,wBAAgB,WAAW,CAAC,CAAC,EAAE,GAAG,EAAE,QAAQ,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,CAE5D"}
|
package/dist/Sheetflow.js
CHANGED
|
@@ -26,7 +26,7 @@ class XLKit {
|
|
|
26
26
|
throw new Error(`Sheet name "${def.name}" contains invalid characters (\\ / ? * [ ] :).`);
|
|
27
27
|
}
|
|
28
28
|
const sheet = this.workbook.addWorksheet(def.name);
|
|
29
|
-
// 1. Setup Columns
|
|
29
|
+
// 1. Setup Columns
|
|
30
30
|
const columns = def.columns.map((col, colIndex) => {
|
|
31
31
|
let width = col.width;
|
|
32
32
|
// Validate Column Key
|
|
@@ -59,14 +59,59 @@ class XLKit {
|
|
|
59
59
|
};
|
|
60
60
|
});
|
|
61
61
|
sheet.columns = columns;
|
|
62
|
-
// 2.
|
|
63
|
-
|
|
64
|
-
|
|
62
|
+
// 2. Setup Headers (Multi-line support)
|
|
63
|
+
let headerRowCount = 1;
|
|
64
|
+
if (def.header?.rows) {
|
|
65
|
+
headerRowCount = def.header.rows.length;
|
|
66
|
+
// Clear default header row if we are using custom rows
|
|
67
|
+
sheet.spliceRows(1, 1);
|
|
68
|
+
def.header.rows.forEach((row, rowIndex) => {
|
|
69
|
+
const currentSheetRowIndex = rowIndex + 1;
|
|
70
|
+
const sheetRow = sheet.getRow(currentSheetRowIndex);
|
|
71
|
+
let colIndex = 1;
|
|
72
|
+
row.forEach((cellConfig) => {
|
|
73
|
+
// Find next available cell (skip merged cells)
|
|
74
|
+
while (sheet.getCell(currentSheetRowIndex, colIndex).isMerged) {
|
|
75
|
+
colIndex++;
|
|
76
|
+
}
|
|
77
|
+
const cell = sheet.getCell(currentSheetRowIndex, colIndex);
|
|
78
|
+
if (typeof cellConfig === 'string') {
|
|
79
|
+
cell.value = cellConfig;
|
|
80
|
+
colIndex++;
|
|
81
|
+
}
|
|
82
|
+
else {
|
|
83
|
+
cell.value = cellConfig.value;
|
|
84
|
+
if (cellConfig.style) {
|
|
85
|
+
cell.style = { ...cell.style, ...(0, style_1.mapStyle)(cellConfig.style) };
|
|
86
|
+
}
|
|
87
|
+
const rowSpan = cellConfig.rowSpan || 1;
|
|
88
|
+
const colSpan = cellConfig.colSpan || 1;
|
|
89
|
+
if (rowSpan > 1 || colSpan > 1) {
|
|
90
|
+
sheet.mergeCells(currentSheetRowIndex, colIndex, currentSheetRowIndex + rowSpan - 1, colIndex + colSpan - 1);
|
|
91
|
+
}
|
|
92
|
+
colIndex += colSpan;
|
|
93
|
+
}
|
|
94
|
+
});
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
// 3. Add Data & Apply Row Styles
|
|
98
|
+
const dataStartRow = headerRowCount + 1;
|
|
99
|
+
data.forEach((row, index) => {
|
|
100
|
+
const rowIndex = dataStartRow + index;
|
|
101
|
+
// We can't use addRow easily because it appends to the end, but we might have gaps if we messed with rows?
|
|
102
|
+
// Actually addRow is fine as long as we are consistent.
|
|
103
|
+
// But since we might have complex headers, let's be explicit with getRow to be safe or just use addRow if we know we are at the end.
|
|
104
|
+
// For safety with existing header logic, let's use explicit row rendering for data to ensure alignment.
|
|
105
|
+
const sheetRow = sheet.getRow(rowIndex);
|
|
106
|
+
def.columns.forEach((col, colIndex) => {
|
|
107
|
+
const cell = sheetRow.getCell(colIndex + 1);
|
|
108
|
+
cell.value = row[col.key];
|
|
109
|
+
});
|
|
65
110
|
// Apply row-level style from definition
|
|
66
111
|
if (def.rows?.style) {
|
|
67
|
-
const rowStyle = def.rows.style(row,
|
|
112
|
+
const rowStyle = def.rows.style(row, index);
|
|
68
113
|
const mappedStyle = (0, style_1.mapStyle)(rowStyle);
|
|
69
|
-
|
|
114
|
+
sheetRow.eachCell((cell) => {
|
|
70
115
|
cell.style = { ...cell.style, ...mappedStyle };
|
|
71
116
|
});
|
|
72
117
|
}
|
|
@@ -74,19 +119,19 @@ class XLKit {
|
|
|
74
119
|
if (row.style) {
|
|
75
120
|
const dataRowStyle = row.style;
|
|
76
121
|
const mappedStyle = (0, style_1.mapStyle)(dataRowStyle);
|
|
77
|
-
|
|
122
|
+
sheetRow.eachCell((cell) => {
|
|
78
123
|
cell.style = { ...cell.style, ...mappedStyle };
|
|
79
124
|
});
|
|
80
125
|
}
|
|
81
126
|
// Apply column-level conditional styles
|
|
82
127
|
def.columns.forEach((col, colIndex) => {
|
|
83
128
|
if (typeof col.style === 'function') {
|
|
84
|
-
const cell =
|
|
85
|
-
const cellStyle = col.style(row[col.key], row,
|
|
129
|
+
const cell = sheetRow.getCell(colIndex + 1);
|
|
130
|
+
const cellStyle = col.style(row[col.key], row, index);
|
|
86
131
|
cell.style = { ...cell.style, ...(0, style_1.mapStyle)(cellStyle) };
|
|
87
132
|
}
|
|
88
133
|
if (col.format) {
|
|
89
|
-
const cell =
|
|
134
|
+
const cell = sheetRow.getCell(colIndex + 1);
|
|
90
135
|
if (typeof col.format === 'string') {
|
|
91
136
|
cell.numFmt = col.format;
|
|
92
137
|
}
|
|
@@ -95,23 +140,31 @@ class XLKit {
|
|
|
95
140
|
}
|
|
96
141
|
}
|
|
97
142
|
});
|
|
143
|
+
sheetRow.commit();
|
|
98
144
|
});
|
|
99
|
-
//
|
|
145
|
+
// 4. Apply Header Styles (Global)
|
|
100
146
|
if (def.header?.style) {
|
|
101
|
-
const headerRow = sheet.getRow(1);
|
|
102
147
|
const mappedHeaderStyle = (0, style_1.mapStyle)(def.header.style);
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
148
|
+
// Apply to all header rows
|
|
149
|
+
for (let i = 1; i <= headerRowCount; i++) {
|
|
150
|
+
const row = sheet.getRow(i);
|
|
151
|
+
row.eachCell((cell) => {
|
|
152
|
+
// Merge with existing style (cell specific style takes precedence if we did it right, but here we are applying global header style)
|
|
153
|
+
// Usually global header style is base, cell specific is override.
|
|
154
|
+
// But here we apply global AFTER. Let's apply it only if no style?
|
|
155
|
+
// Or just merge.
|
|
156
|
+
cell.style = { ...mappedHeaderStyle, ...cell.style };
|
|
157
|
+
});
|
|
158
|
+
}
|
|
106
159
|
}
|
|
107
|
-
//
|
|
160
|
+
// 5. Apply Vertical Merges
|
|
108
161
|
def.columns.forEach((col, colIndex) => {
|
|
109
162
|
if (col.merge === 'vertical') {
|
|
110
|
-
let startRow =
|
|
163
|
+
let startRow = dataStartRow;
|
|
111
164
|
let previousValue = null;
|
|
112
165
|
// Iterate from first data row to last
|
|
113
166
|
for (let i = 0; i < data.length; i++) {
|
|
114
|
-
const currentRowIndex =
|
|
167
|
+
const currentRowIndex = dataStartRow + i;
|
|
115
168
|
const cell = sheet.getCell(currentRowIndex, colIndex + 1);
|
|
116
169
|
const currentValue = cell.value;
|
|
117
170
|
if (i === 0) {
|
|
@@ -128,13 +181,70 @@ class XLKit {
|
|
|
128
181
|
}
|
|
129
182
|
}
|
|
130
183
|
// Handle the last group
|
|
131
|
-
const lastRowIndex = data.length
|
|
132
|
-
|
|
133
|
-
|
|
184
|
+
const lastRowIndex = dataStartRow + data.length; // This is actually the row AFTER the last data row index if we use <
|
|
185
|
+
// Wait, loop goes 0 to length-1.
|
|
186
|
+
// If i=length-1 (last item), we check logic.
|
|
187
|
+
// We need to handle the merge AFTER the loop for the final group.
|
|
188
|
+
if (data.length > 0) {
|
|
189
|
+
const finalRowIndex = dataStartRow + data.length - 1;
|
|
190
|
+
if (finalRowIndex > startRow) {
|
|
191
|
+
sheet.mergeCells(startRow, colIndex + 1, finalRowIndex, colIndex + 1);
|
|
192
|
+
}
|
|
134
193
|
}
|
|
135
194
|
}
|
|
136
195
|
});
|
|
137
|
-
//
|
|
196
|
+
// 6. Apply Horizontal Merges
|
|
197
|
+
// We iterate row by row
|
|
198
|
+
for (let i = 0; i < data.length; i++) {
|
|
199
|
+
const currentRowIndex = dataStartRow + i;
|
|
200
|
+
const row = sheet.getRow(currentRowIndex);
|
|
201
|
+
let startCol = 1;
|
|
202
|
+
let previousValue = null;
|
|
203
|
+
let merging = false;
|
|
204
|
+
// We need to check which columns are candidates for horizontal merge.
|
|
205
|
+
// A simple approach: iterate columns. If current col has merge='horizontal', try to merge with next.
|
|
206
|
+
// But we need to group them.
|
|
207
|
+
for (let c = 0; c < def.columns.length; c++) {
|
|
208
|
+
const colDef = def.columns[c];
|
|
209
|
+
const currentCell = row.getCell(c + 1);
|
|
210
|
+
const currentValue = currentCell.value;
|
|
211
|
+
if (colDef.merge === 'horizontal') {
|
|
212
|
+
if (!merging) {
|
|
213
|
+
merging = true;
|
|
214
|
+
startCol = c + 1;
|
|
215
|
+
previousValue = currentValue;
|
|
216
|
+
}
|
|
217
|
+
else {
|
|
218
|
+
if (currentValue !== previousValue) {
|
|
219
|
+
// End of a merge group
|
|
220
|
+
if ((c + 1) - 1 > startCol) {
|
|
221
|
+
sheet.mergeCells(currentRowIndex, startCol, currentRowIndex, c);
|
|
222
|
+
}
|
|
223
|
+
// Start new group
|
|
224
|
+
startCol = c + 1;
|
|
225
|
+
previousValue = currentValue;
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
else {
|
|
230
|
+
if (merging) {
|
|
231
|
+
// End of merge group because this column is not mergeable
|
|
232
|
+
if ((c + 1) - 1 > startCol) {
|
|
233
|
+
sheet.mergeCells(currentRowIndex, startCol, currentRowIndex, c);
|
|
234
|
+
}
|
|
235
|
+
merging = false;
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
// Check at end of row
|
|
240
|
+
if (merging) {
|
|
241
|
+
const lastCol = def.columns.length;
|
|
242
|
+
if (lastCol > startCol) {
|
|
243
|
+
sheet.mergeCells(currentRowIndex, startCol, currentRowIndex, lastCol);
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
// 7. Apply Borders
|
|
138
248
|
if (def.borders === 'all') {
|
|
139
249
|
sheet.eachRow((row) => {
|
|
140
250
|
row.eachCell((cell) => {
|
|
@@ -167,8 +277,9 @@ class XLKit {
|
|
|
167
277
|
}
|
|
168
278
|
else if (def.borders === 'header-body') {
|
|
169
279
|
const lastCol = sheet.columnCount;
|
|
280
|
+
// Apply to the last row of the header
|
|
170
281
|
for (let c = 1; c <= lastCol; c++) {
|
|
171
|
-
const headerCell = sheet.getCell(
|
|
282
|
+
const headerCell = sheet.getCell(headerRowCount, c);
|
|
172
283
|
headerCell.border = { ...headerCell.border, bottom: { style: 'medium' } };
|
|
173
284
|
}
|
|
174
285
|
}
|
package/dist/types.d.ts
CHANGED
|
@@ -16,12 +16,18 @@ export interface ColumnDef<T> {
|
|
|
16
16
|
key: keyof T;
|
|
17
17
|
header: string;
|
|
18
18
|
width?: number | 'auto';
|
|
19
|
-
merge?: 'vertical';
|
|
19
|
+
merge?: 'vertical' | 'horizontal';
|
|
20
20
|
style?: XLStyle | ((val: any, row: T, index: number) => XLStyle);
|
|
21
21
|
format?: string | ((val: any) => string);
|
|
22
22
|
}
|
|
23
|
+
export interface HeaderCell {
|
|
24
|
+
value: string;
|
|
25
|
+
colSpan?: number;
|
|
26
|
+
rowSpan?: number;
|
|
27
|
+
style?: XLStyle;
|
|
28
|
+
}
|
|
23
29
|
export interface HeaderConfig {
|
|
24
|
-
rows
|
|
30
|
+
rows?: (string | HeaderCell)[][];
|
|
25
31
|
style?: XLStyle;
|
|
26
32
|
borders?: 'header-body' | 'all' | 'none';
|
|
27
33
|
}
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAS,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AAE/D,MAAM,MAAM,QAAQ,GAAG,MAAM,CAAC;AAE9B,MAAM,WAAW,OAAO;IACtB,IAAI,CAAC,EAAE,OAAO,CAAC,IAAI,CAAC,GAAG;QAAE,KAAK,CAAC,EAAE,QAAQ,GAAG;YAAE,IAAI,EAAE,MAAM,CAAA;SAAE,CAAA;KAAE,CAAC;IAC/D,IAAI,CAAC,EAAE,OAAO,CAAC,IAAI,CAAC,GAAG;QAAE,KAAK,CAAC,EAAE,QAAQ,CAAA;KAAE,CAAC;IAC5C,SAAS,CAAC,EAAE,OAAO,CAAC,SAAS,CAAC,CAAC;IAC/B,MAAM,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,GAAG,KAAK,GAAG,OAAO,GAAG,aAAa,GAAG,MAAM,CAAC;CACrE;AAED,MAAM,WAAW,SAAS,CAAC,CAAC;IAC1B,GAAG,EAAE,MAAM,CAAC,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACxB,KAAK,CAAC,EAAE,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAS,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AAE/D,MAAM,MAAM,QAAQ,GAAG,MAAM,CAAC;AAE9B,MAAM,WAAW,OAAO;IACtB,IAAI,CAAC,EAAE,OAAO,CAAC,IAAI,CAAC,GAAG;QAAE,KAAK,CAAC,EAAE,QAAQ,GAAG;YAAE,IAAI,EAAE,MAAM,CAAA;SAAE,CAAA;KAAE,CAAC;IAC/D,IAAI,CAAC,EAAE,OAAO,CAAC,IAAI,CAAC,GAAG;QAAE,KAAK,CAAC,EAAE,QAAQ,CAAA;KAAE,CAAC;IAC5C,SAAS,CAAC,EAAE,OAAO,CAAC,SAAS,CAAC,CAAC;IAC/B,MAAM,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,GAAG,KAAK,GAAG,OAAO,GAAG,aAAa,GAAG,MAAM,CAAC;CACrE;AAED,MAAM,WAAW,SAAS,CAAC,CAAC;IAC1B,GAAG,EAAE,MAAM,CAAC,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACxB,KAAK,CAAC,EAAE,UAAU,GAAG,YAAY,CAAC;IAClC,KAAK,CAAC,EAAE,OAAO,GAAG,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,CAAC;IACjE,MAAM,CAAC,EAAE,MAAM,GAAG,CAAC,CAAC,GAAG,EAAE,GAAG,KAAK,MAAM,CAAC,CAAC;CAC1C;AAED,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,CAAC,EAAE,CAAC,MAAM,GAAG,UAAU,CAAC,EAAE,EAAE,CAAC;IACjC,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,OAAO,CAAC,EAAE,aAAa,GAAG,KAAK,GAAG,MAAM,CAAC;CAC1C;AAED,MAAM,WAAW,QAAQ,CAAC,CAAC;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC;IACxB,MAAM,CAAC,EAAE,YAAY,CAAC;IACtB,IAAI,CAAC,EAAE;QACL,KAAK,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC;KAC7C,CAAC;IACF,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,OAAO,CAAC,EAAE,KAAK,GAAG,OAAO,GAAG,aAAa,GAAG,MAAM,CAAC;IACnD,SAAS,CAAC,EAAE;QACV,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,cAAc,CAAC,EAAE,OAAO,CAAC;QACzB,iBAAiB,CAAC,EAAE,MAAM,CAAC;KAC5B,CAAC;CACH"}
|