Skip to content

Commit 80da0ad

Browse files
authored
Merge pull request #13 from StefanNedelchev/feature/col-breaks
feat: added col breaks feature
2 parents 3044178 + fd38dfc commit 80da0ad

17 files changed

+149
-9
lines changed

README.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,10 @@ Reverse engineered from Excel spreadsheet files as a project.
1616
npm install @zurmokeeper/exceljs
1717
```
1818

19+
# New Features!
20+
21+
Since V4.4.3, the detailed update of the new version can be accessed from [here](https://github.com/zurmokeeper/excelize/releases).
22+
1923
# V4.4.3 New Features!
2024

2125
Change Log:
@@ -782,6 +786,9 @@ worksheet.getColumn(5).outlineLevel = 1;
782786
expect(worksheet.getColumn(4).collapsed).to.equal(false);
783787
expect(worksheet.getColumn(5).collapsed).to.equal(true);
784788

789+
// Insert a page break below the column
790+
dobCol.addPageBreak();
791+
785792
// iterate over all current cells in this column
786793
dobCol.eachCell(function(cell, rowNumber) {
787794
// ...

README_zh.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@
1414
npm install @zurmokeeper/exceljs
1515
```
1616

17+
# 新的功能!
18+
19+
自V4.4.3以后,新版本详细更新内容在[这里](https://github.com/zurmokeeper/excelize/releases).
20+
1721
# V4.4.3 新的功能!
1822

1923
变更日志:
@@ -730,6 +734,9 @@ worksheet.getColumn(5).outlineLevel = 1;
730734
expect(worksheet.getColumn(4).collapsed).to.equal(false);
731735
expect(worksheet.getColumn(5).collapsed).to.equal(true);
732736

737+
// 在该列右边插入一个分页符
738+
dobCol.addPageBreak();
739+
733740
// 遍历此列中的所有当前单元格
734741
dobCol.eachCell(function(cell, rowNumber) {
735742
// ...

index.d.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -673,6 +673,11 @@ export interface Column {
673673
*/
674674
eachCell(opt: { includeEmpty: boolean }, callback: (cell: Cell, rowNumber: number) => void): void;
675675

676+
/**
677+
* Inserts a page break after the column
678+
*/
679+
addPageBreak(tp?: number, btm?: number): void;
680+
676681
defn: any; //todo
677682
}
678683
export interface PageSetup {
@@ -972,7 +977,7 @@ export interface Range extends Location {
972977
}>): boolean;
973978
}
974979

975-
export interface RowBreak {
980+
export interface PageBreak {
976981
id: number;
977982
max: number;
978983
min: number;
@@ -986,7 +991,8 @@ export interface WorksheetModel {
986991
properties: WorksheetProperties;
987992
pageSetup: Partial<PageSetup>;
988993
headerFooter: Partial<HeaderFooter>;
989-
rowBreaks: RowBreak[];
994+
rowBreaks: PageBreak[];
995+
colBreaks: PageBreak[];
990996
views: WorksheetView[];
991997
autoFilter: AutoFilter;
992998
media: Media[];

lib/doc/column.js

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -122,9 +122,7 @@ class Column {
122122
}
123123

124124
get collapsed() {
125-
return !!(
126-
this._outlineLevel && this._outlineLevel >= this._worksheet.properties.outlineLevelCol
127-
);
125+
return !!(this._outlineLevel && this._outlineLevel >= this._worksheet.properties.outlineLevelCol);
128126
}
129127

130128
toString() {
@@ -201,6 +199,21 @@ class Column {
201199
});
202200
}
203201

202+
// Page Breaks
203+
addPageBreak(tp, btn) {
204+
const ws = this._worksheet;
205+
const top = Math.max(0, tp - 1) || 0;
206+
const bottom = Math.max(0, btn - 1) || 65535;
207+
const pb = {
208+
id: this._number,
209+
max: bottom,
210+
man: 1,
211+
};
212+
if (top) pb.min = top;
213+
214+
ws.colBreaks.push(pb);
215+
}
216+
204217
// =========================================================================
205218
// styles
206219
_applyStyle(name, value) {
@@ -301,7 +314,7 @@ class Column {
301314
* sort cols by min
302315
* If it is not sorted, the subsequent column configuration will be overwritten
303316
* */
304-
cols = cols.sort(function(pre, next) {
317+
cols = cols.sort(function(pre, next) {
305318
return pre.min - next.min;
306319
});
307320
while (index < cols.length) {

lib/doc/worksheet.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ class Worksheet {
4848

4949
// record of all row and column pageBreaks
5050
this.rowBreaks = [];
51+
this.colBreaks = [];
5152

5253
// for tabColor, default row height, outline levels, etc
5354
this.properties = Object.assign(
@@ -850,6 +851,7 @@ class Worksheet {
850851
pageSetup: this.pageSetup,
851852
headerFooter: this.headerFooter,
852853
rowBreaks: this.rowBreaks,
854+
colBreaks: this.colBreaks,
853855
views: this.views,
854856
autoFilter: this.autoFilter,
855857
media: this._media.map(medium => medium.model),

lib/stream/xlsx/worksheet-writer.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ const PictureXform = require('../../xlsx/xform/sheet/picture-xform');
3434
const ConditionalFormattingsXform = require('../../xlsx/xform/sheet/cf/conditional-formattings-xform');
3535
const HeaderFooterXform = require('../../xlsx/xform/sheet/header-footer-xform');
3636
const RowBreaksXform = require('../../xlsx/xform/sheet/row-breaks-xform');
37+
const ColBreaksXform = require('../../xlsx/xform/sheet/col-breaks-xform');
3738

3839
// since prepare and render are functional, we can use singletons
3940
const xform = {
@@ -52,6 +53,7 @@ const xform = {
5253
conditionalFormattings: new ConditionalFormattingsXform(),
5354
headerFooter: new HeaderFooterXform(),
5455
rowBreaks: new RowBreaksXform(),
56+
colBreaks: new ColBreaksXform(),
5557
};
5658

5759
// ============================================================================================
@@ -107,6 +109,7 @@ class WorksheetWriter {
107109

108110
// keep a record of all row and column pageBreaks
109111
this.rowBreaks = [];
112+
this.colBreaks = [];
110113

111114
// for default row height, outline levels, etc
112115
this.properties = Object.assign(
@@ -246,6 +249,7 @@ class WorksheetWriter {
246249
this._writeBackground();
247250
this._writeHeaderFooter();
248251
this._writeRowBreaks();
252+
this._writeColBreaks();
249253

250254
// Legacy Data tag for comments
251255
this._writeLegacyData();
@@ -653,6 +657,10 @@ class WorksheetWriter {
653657
this.stream.write(xform.rowBreaks.toXml(this.rowBreaks));
654658
}
655659

660+
_writeColBreaks() {
661+
this.stream.write(xform.colBreaks.toXml(this.colBreaks));
662+
}
663+
656664
_writeDataValidations() {
657665
this.stream.write(xform.dataValidations.toXml(this.dataValidations.model));
658666
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
'use strict';
2+
3+
const PageBreaksXform = require('./page-breaks-xform');
4+
5+
const ListXform = require('../list-xform');
6+
7+
class ColBreaksXform extends ListXform {
8+
constructor() {
9+
const options = {
10+
tag: 'colBreaks',
11+
count: true,
12+
childXform: new PageBreaksXform(),
13+
};
14+
super(options);
15+
}
16+
17+
// get tag() { return 'colBreaks'; }
18+
19+
render(xmlStream, model) {
20+
if (model && model.length) {
21+
xmlStream.openNode(this.tag, this.$);
22+
if (this.count) {
23+
xmlStream.addAttribute(this.$count, model.length);
24+
xmlStream.addAttribute('manualBreakCount', model.length);
25+
}
26+
27+
const {childXform} = this;
28+
model.forEach(childModel => {
29+
childXform.render(xmlStream, childModel);
30+
});
31+
32+
xmlStream.closeNode();
33+
} else if (this.empty) {
34+
xmlStream.leafNode(this.tag);
35+
}
36+
}
37+
}
38+
39+
module.exports = ColBreaksXform;

lib/xlsx/xform/sheet/worksheet-xform.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ const PictureXform = require('./picture-xform');
2727
const DrawingXform = require('./drawing-xform');
2828
const TablePartXform = require('./table-part-xform');
2929
const RowBreaksXform = require('./row-breaks-xform');
30+
const ColBreaksXform = require('./col-breaks-xform');
3031
const HeaderFooterXform = require('./header-footer-xform');
3132
const ConditionalFormattingsXform = require('./cf/conditional-formattings-xform');
3233
const ExtListXform = require('./ext-lst-xform');
@@ -113,6 +114,7 @@ class WorkSheetXform extends BaseXform {
113114
autoFilter: new AutoFilterXform(),
114115
mergeCells: new ListXform({tag: 'mergeCells', count: true, childXform: new MergeCellXform()}),
115116
rowBreaks: new RowBreaksXform(),
117+
colBreaks: new ColBreaksXform(),
116118
hyperlinks: new ListXform({
117119
tag: 'hyperlinks',
118120
count: false,
@@ -343,6 +345,7 @@ class WorkSheetXform extends BaseXform {
343345
this.map.pageSetup.render(xmlStream, model.pageSetup);
344346
this.map.headerFooter.render(xmlStream, model.headerFooter);
345347
this.map.rowBreaks.render(xmlStream, model.rowBreaks);
348+
this.map.colBreaks.render(xmlStream, model.colBreaks);
346349
this.map.drawing.render(xmlStream, model.drawing); // Note: must be after rowBreaks
347350
this.map.picture.render(xmlStream, model.background); // Note: must be after drawing
348351
this.map.tableParts.render(xmlStream, model.tables);

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@zurmokeeper/exceljs",
3-
"version": "4.4.3",
3+
"version": "4.4.4",
44
"description": "Excel Workbook Manager - Read and Write xlsx and csv Files.",
55
"private": false,
66
"license": "MIT",
@@ -111,7 +111,7 @@
111111
"saxes": "^5.0.1",
112112
"tmp": "^0.2.0",
113113
"unzipper": "^0.10.11",
114-
"uuid": "^8.3.0"
114+
"uuid": "^9.0.0"
115115
},
116116
"devDependencies": {
117117
"@babel/cli": "^7.10.5",

spec/integration/worksheet-xlsx-writer.spec.js

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -534,5 +534,27 @@ describe('WorksheetWriter', () => {
534534
row.addPageBreak();
535535
expect(ws.rowBreaks.length).to.equal(2);
536536
});
537+
538+
it('adds multiple col breaks', () => {
539+
const wb = new ExcelJS.stream.xlsx.WorkbookWriter();
540+
const ws = wb.addWorksheet('blort');
541+
542+
// initial values
543+
ws.getCell('A1').value = 'A1';
544+
ws.getCell('B1').value = 'B1';
545+
ws.getCell('C1').value = 'C1';
546+
ws.getCell('D1').value = 'D1';
547+
ws.getCell('A2').value = 'A2';
548+
ws.getCell('B2').value = 'B2';
549+
ws.getCell('C2').value = 'C2';
550+
ws.getCell('D2').value = 'D2';
551+
552+
let col = ws.getColumn('A');
553+
col.addPageBreak();
554+
col = ws.getColumn('C');
555+
col.addPageBreak();
556+
557+
expect(ws.colBreaks.length).to.equal(2);
558+
});
537559
});
538560
});

0 commit comments

Comments
 (0)