Skip to content

Commit 0d94429

Browse files
authored
Merge pull request #389 from brucejo75/issue-386
Add rowBreaks feature.
2 parents 3623df4 + 8cfbe8f commit 0d94429

File tree

14 files changed

+304
-3
lines changed

14 files changed

+304
-3
lines changed

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -559,6 +559,9 @@ row.values = {
559559
dob: new Date()
560560
};
561561

562+
// Insert a page break prior to the row
563+
row.addPageBreak();
564+
562565
// Iterate over all rows that have values in a worksheet
563566
worksheet.eachRow(function(row, rowNumber) {
564567
console.log('Row ' + rowNumber + ' = ' + JSON.stringify(row.values));

lib/doc/row.js

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,22 @@ Row.prototype = {
136136
}
137137
},
138138

139+
// ===========================================================================
140+
// Page Breaks
141+
addPageBreak: function(lft, rght) {
142+
const ws = this._worksheet;
143+
const left = Math.max(0, lft - 1) || 0;
144+
const right = Math.max(0, rght - 1) || 16838;
145+
const pb = {
146+
id: this._number,
147+
max: right,
148+
man: 1
149+
};
150+
if (left) pb.min = left;
151+
152+
ws.rowBreaks.push(pb);
153+
},
154+
139155
// return a sparse array of cell values
140156
get values() {
141157
var values = [];

lib/doc/worksheet.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,9 @@ var Worksheet = module.exports = function(options) {
4343
// keep record of all merges
4444
this._merges = {};
4545

46+
// record of all row and column pageBreaks
47+
this.rowBreaks = [];
48+
4649
this._workbook = options.workbook;
4750

4851
// for tabColor, default row height, outline levels, etc
@@ -557,6 +560,7 @@ Worksheet.prototype = {
557560
dataValidations: this.dataValidations.model,
558561
properties: this.properties,
559562
pageSetup: this.pageSetup,
563+
rowBreaks: this.rowBreaks,
560564
views: this.views,
561565
autoFilter: this.autoFilter,
562566
media: this._media,
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
/**
2+
* Copyright (c) 2015 Guyon Roche
3+
* LICENCE: MIT - please refer to LICENCE file included with this module
4+
* or https://github.com/guyonroche/exceljs/blob/master/LICENSE
5+
*/
6+
7+
'use strict';
8+
9+
var utils = require('../../../utils/utils');
10+
var BaseXform = require('../base-xform');
11+
12+
var PageBreaksXform = module.exports = function() {
13+
};
14+
15+
utils.inherits(PageBreaksXform, BaseXform, {
16+
17+
get tag() { return 'brk'; },
18+
19+
render: function(xmlStream, model) {
20+
xmlStream.leafNode('brk', model);
21+
},
22+
23+
parseOpen: function(node) {
24+
if (node.name === 'brk') {
25+
this.model = node.attributes.ref;
26+
return true;
27+
}
28+
return false;
29+
},
30+
parseText: function() {
31+
},
32+
parseClose: function() {
33+
return false;
34+
}
35+
});
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
/**
2+
* Copyright (c) 2015 Guyon Roche
3+
* LICENCE: MIT - please refer to LICENCE file included with this module
4+
* or https://github.com/guyonroche/exceljs/blob/master/LICENSE
5+
*/
6+
7+
'use strict';
8+
9+
var PageBreaksXform = require('./page-breaks-xform');
10+
11+
var utils = require('../../../utils/utils');
12+
var ListXform = require('../list-xform');
13+
14+
var RowBreaksXform = module.exports = function() {
15+
const options = {tag: 'rowBreaks', count: true, childXform: new PageBreaksXform()};
16+
ListXform.call(this, options);
17+
};
18+
19+
utils.inherits(RowBreaksXform, ListXform, {
20+
21+
// get tag() { return 'rowBreaks'; },
22+
23+
render: function(xmlStream, model) {
24+
if (model && model.length) {
25+
xmlStream.openNode(this.tag, this.$);
26+
if (this.count) {
27+
xmlStream.addAttribute(this.$count, model.length);
28+
xmlStream.addAttribute('manualBreakCount', model.length);
29+
}
30+
31+
var childXform = this.childXform;
32+
model.forEach(function(childModel) {
33+
childXform.render(xmlStream, childModel);
34+
});
35+
36+
xmlStream.closeNode();
37+
} else if (this.empty) {
38+
xmlStream.leafNode(this.tag);
39+
}
40+
}
41+
});

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

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ var PrintOptionsXform = require('./print-options-xform');
3232
var AutoFilterXform = require('./auto-filter-xform');
3333
var PictureXform = require('./picture-xform');
3434
var DrawingXform = require('./drawing-xform');
35+
var RowBreaksXform = require('./row-breaks-xform');
3536

3637
var WorkSheetXform = module.exports = function() {
3738
this.map = {
@@ -43,6 +44,7 @@ var WorkSheetXform = module.exports = function() {
4344
sheetData: new ListXform({tag: 'sheetData', count: false, empty: true, childXform: new RowXform()}),
4445
autoFilter: new AutoFilterXform(),
4546
mergeCells: new ListXform({tag: 'mergeCells', count: true, childXform: new MergeCellXform()}),
47+
rowBreaks: new RowBreaksXform(),
4648
hyperlinks: new ListXform({tag: 'hyperlinks', count: false, childXform: new HyperlinkXform()}),
4749
pageMargins: new PageMarginsXform(),
4850
dataValidations: new DataValidationsXform(),
@@ -180,7 +182,8 @@ utils.inherits(WorkSheetXform, BaseXform, {
180182
this.map.pageSetup.render(xmlStream, model.pageSetup);
181183
this.map.drawing.render(xmlStream, model.drawing);
182184
this.map.picture.render(xmlStream, model.background); // Note: must be after drawing
183-
185+
this.map.rowBreaks.render(xmlStream, model.rowBreaks);
186+
184187
xmlStream.closeNode();
185188
},
186189

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
var expect = require('chai').expect;
2+
3+
var Excel = require('../../../excel');
4+
5+
describe('Worksheet', function() {
6+
describe('Page Breaks', function() {
7+
it('adds multiple row breaks', function() {
8+
var wb = new Excel.Workbook();
9+
var ws = wb.addWorksheet('blort');
10+
11+
// initial values
12+
ws.getCell('A1').value = 'A1';
13+
ws.getCell('B1').value = 'B1';
14+
ws.getCell('A2').value = 'A2';
15+
ws.getCell('B2').value = 'B2';
16+
ws.getCell('A3').value = 'A3';
17+
ws.getCell('B3').value = 'B3';
18+
19+
var row = ws.getRow(1);
20+
row.addPageBreak();
21+
row = ws.getRow(2);
22+
row.addPageBreak();
23+
24+
expect(ws.rowBreaks.length).to.equal(2);
25+
});
26+
});
27+
});

spec/unit/xlsx/xform/sheet/data/sheet.1.0.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,5 +60,6 @@
6060
]
6161
}
6262
],
63-
"media": []
63+
"media": [],
64+
"rowBreaks": []
6465
}

spec/unit/xlsx/xform/sheet/data/sheet.1.1.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,5 +75,6 @@
7575
"Type": "http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink"
7676
}
7777
],
78-
"media": []
78+
"media": [],
79+
"rowBreaks": []
7980
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
{
2+
"dimensions": "A1:C7",
3+
"properties": {"defaultRowHeight": 14.4, "dyDescent": 0.55, "outlineLevelRow": 2},
4+
"views": [{"state": "normal", "workbookViewId": 0}],
5+
"pageSetup": {
6+
"margins": {"left": 0.7, "right": 0.7, "top": 0.75, "bottom": 0.75, "header": 0.3, "footer": 0.3 }
7+
},
8+
"rows": [
9+
{
10+
"number": 1, "min": 1, "max": 3,
11+
"cells": [
12+
{"address": "A1", "type": 3, "value": "Name"},
13+
{"address": "C1", "type": 3, "value": "Tom"}
14+
]
15+
},
16+
{
17+
"number": 2, "min": 1, "max": 3, "outlineLevel": 1,
18+
"cells": [
19+
{"address": "C2", "type": 3, "value": "Dick"}
20+
]
21+
},
22+
{
23+
"number": 3, "min": 1, "max": 3, "outlineLevel": 2, "collapsed": true,
24+
"cells": [
25+
{"address": "C3", "type": 3, "value": "Harry"}
26+
]
27+
},
28+
{
29+
"number": 5, "min": 1, "max": 3,
30+
"cells": [
31+
{"address": "A5", "type": 3, "value": "Inline"}
32+
]
33+
},
34+
{
35+
"number": 7, "min": 1, "max": 3,
36+
"cells": [
37+
{"address": "A7", "type": 3, "value": "Between"},
38+
{"address": "B7", "type": 2, "value": 5}
39+
]
40+
}
41+
],
42+
"rowBreaks": [
43+
{"id": 2, "max": 2, "min": 0, "man": 1},
44+
{"id": 5, "max": 2, "min": 0, "man": 1}
45+
],
46+
"media": []
47+
}

0 commit comments

Comments
 (0)