Skip to content

Commit a9cbc12

Browse files
committed
fix the problem when there is a missing field in the first row
1 parent db90c6b commit a9cbc12

File tree

4 files changed

+112
-63
lines changed

4 files changed

+112
-63
lines changed

.travis.yml

Lines changed: 0 additions & 5 deletions
This file was deleted.

lib/json2xls.js

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,13 +39,34 @@ function getByString(object, path) {
3939
return object;
4040
}
4141

42+
function getFields(json) {
43+
const keys = [];
44+
for (let i = 0; i < json.length; i++) {
45+
const row = json[i];
46+
let count = 0;
47+
for (const key in row) {
48+
if (row.hasOwnProperty(key)) {
49+
const foundKey = keys.find(keyToCheck => keyToCheck === key);
50+
if (!foundKey) {
51+
// We need to put the key in the same place we found it
52+
keys.splice(count, 0, key);
53+
}
54+
count++;
55+
}
56+
}
57+
}
58+
59+
return keys;
60+
61+
}
62+
4263

4364
//prepare json to be in the correct format for excel-export
4465
transform.prepareJson = function(json,config) {
4566
var res = {};
4667
var conf = config||{};
4768
var jsonArr = [].concat(json);
48-
var fields = conf.fields || Object.keys(jsonArr[0]||{});
69+
var fields = conf.fields || getFields(jsonArr);
4970
var types = [];
5071
if (!(fields instanceof Array)) {
5172
types = Object.keys(fields).map(function(key) {

package.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,5 +11,8 @@
1111
"license": "BSD-2-Clause",
1212
"dependencies": {
1313
"excel-export": "~0.3.11"
14+
},
15+
"devDependencies": {
16+
"jasmine-node": "^3.0.0"
1417
}
1518
}

spec/prepareSpec.js

Lines changed: 87 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,16 @@ var arrayData = require('./arrayData.json');
44
var objectData = require('./objectData.json');
55
var weirdData = require('./weirdData');
66

7-
describe('prepare',function() {
7+
describe('prepare', function () {
88

9-
beforeEach(function() {
9+
beforeEach(function () {
1010
this.addMatchers({
11-
toEqualFields: function() {
11+
toEqualFields: function () {
1212
return {
13-
compare: function(actual,expected) {
13+
compare: function (actual, expected) {
1414
var res;
15-
var res = expected && expected.all && expected.all(function(item,i) {
16-
return actual[i] && Object.keys(item).all(function(field) {
15+
var res = expected && expected.all && expected.all(function (item, i) {
16+
return actual[i] && Object.keys(item).all(function (field) {
1717
return actual[i][field] === item[field];
1818
});
1919
})
@@ -23,68 +23,68 @@ describe('prepare',function() {
2323
}
2424
}
2525
}
26-
})
27-
})
26+
});
27+
});
2828

29-
describe('handling illegal xml characters', function() {
30-
it('should remove vertical tabs',function() {
29+
describe('handling illegal xml characters', function () {
30+
it('should remove vertical tabs', function () {
3131
var res = prep(weirdData);
3232
expect(res.rows[0][1]).toEqual(' foo bar ');
3333
});
3434
});
3535

36-
describe('when the data is an empty array', function() {
37-
it('should create an empty config', function() {
36+
describe('when the data is an empty array', function () {
37+
it('should create an empty config', function () {
3838
var res = prep([]);
3939
expect(res.cols).toEqual([]);
4040
expect(res.rows).toEqual([]);
4141
});
4242
});
4343

44-
describe('when the data is an empty object', function() {
45-
it('should create a config with one empty row', function() {
44+
describe('when the data is an empty object', function () {
45+
it('should create a config with one empty row', function () {
4646
var res = prep({});
4747
expect(res.cols).toEqual([]);
4848
expect(res.rows).toEqual([[]]);
4949
});
5050
});
5151

52-
describe('when the data is an array', function() {
53-
54-
describe('cols',function() {
55-
it('should create a cols part',function() {
52+
describe('when the data is an array', function () {
53+
54+
describe('cols', function () {
55+
it('should create a cols part', function () {
5656
var res = prep(arrayData);
5757
expect(res.cols).toBeDefined();
5858
});
59-
it('should create the correct cols',function() {
59+
it('should create the correct cols', function () {
6060
var res = prep(arrayData);
6161
expect(res.cols).toEqualFields([{
6262
caption: 'name',
6363
type: 'string'
64-
},{
64+
}, {
6565
caption: 'date',
6666
type: 'string'
67-
},{
67+
}, {
6868
caption: 'number',
6969
type: 'number'
7070
}]);
7171
});
7272

73-
it('should create the correct cols when fields are given as array',function() {
74-
var res = prep(arrayData,{
75-
fields: ['date','name']
73+
it('should create the correct cols when fields are given as array', function () {
74+
var res = prep(arrayData, {
75+
fields: ['date', 'name']
7676
});
7777
expect(res.cols).toEqualFields([{
7878
caption: 'date',
7979
type: 'string'
80-
},{
80+
}, {
8181
caption: 'name',
8282
type: 'string'
8383
}]);
8484
});
8585

86-
it('should create the correct cols when fields are given as object',function() {
87-
var res = prep(arrayData,{
86+
it('should create the correct cols when fields are given as object', function () {
87+
var res = prep(arrayData, {
8888
fields: {
8989
number: 'string',
9090
name: 'string'
@@ -93,36 +93,36 @@ describe('prepare',function() {
9393
expect(res.cols).toEqualFields([{
9494
caption: 'number',
9595
type: 'string'
96-
},{
96+
}, {
9797
caption: 'name',
9898
type: 'string'
9999
}]);
100100
});
101101

102-
it('should create caption and type field',function() {
102+
it('should create caption and type field', function () {
103103
var cols = prep(arrayData).cols;
104104
expect(cols[0].caption).toBeDefined();
105105
expect(cols[0].type).toBeDefined();
106106
});
107107
});
108108

109-
describe('rows',function() {
110-
it('should create a rows part',function() {
109+
describe('rows', function () {
110+
it('should create a rows part', function () {
111111
var res = prep(arrayData);
112112
expect(res.rows).toBeDefined();
113113
});
114-
it('should create rows with data in the correct order',function() {
114+
it('should create rows with data in the correct order', function () {
115115
var res = prep(arrayData);
116-
expect(res.rows[0]).toEqual([ 'Ivy Dickson', '2013-05-27T11:04:15-07:00', 10 ]);
117-
expect(res.rows[1]).toEqual([ 'Walker Lynch','2014-02-07T22:09:58-08:00', 2 ]);
118-
expect(res.rows[2]).toEqual([ 'Maxwell U. Holden', '2013-06-16T05:29:13-07:00', 5]);
116+
expect(res.rows[0]).toEqual(['Ivy Dickson', '2013-05-27T11:04:15-07:00', 10]);
117+
expect(res.rows[1]).toEqual(['Walker Lynch', '2014-02-07T22:09:58-08:00', 2]);
118+
expect(res.rows[2]).toEqual(['Maxwell U. Holden', '2013-06-16T05:29:13-07:00', 5]);
119119
});
120120
});
121121

122-
describe('style',function() {
123-
it('should have the provided style xml file',function() {
122+
describe('style', function () {
123+
it('should have the provided style xml file', function () {
124124
var fn = 'test.xml';
125-
var res = prep(arrayData,{
125+
var res = prep(arrayData, {
126126
style: fn
127127
});
128128
expect(res.stylesXmlFile).toBe(fn);
@@ -131,46 +131,46 @@ describe('prepare',function() {
131131

132132
});
133133

134-
describe('when the data is an object', function() {
135-
describe('cols',function() {
136-
it('should create a cols part',function() {
134+
describe('when the data is an object', function () {
135+
describe('cols', function () {
136+
it('should create a cols part', function () {
137137
var res = prep(objectData);
138138
expect(res.cols).toBeDefined();
139139
});
140-
it('should create caption and type field',function() {
140+
it('should create caption and type field', function () {
141141
var cols = prep(objectData).cols;
142142
expect(cols[0].caption).toBeDefined();
143143
expect(cols[0].type).toBeDefined();
144144
});
145145
});
146146

147-
describe('rows',function() {
148-
it('should create a rows part',function() {
147+
describe('rows', function () {
148+
it('should create a rows part', function () {
149149
var res = prep(objectData);
150150
expect(res.rows).toBeDefined();
151151
});
152152
});
153153

154-
describe('style',function() {
155-
it('should have the provided style xml file',function() {
154+
describe('style', function () {
155+
it('should have the provided style xml file', function () {
156156
var fn = 'test.xml';
157-
var res = prep(objectData,{
157+
var res = prep(objectData, {
158158
style: fn
159159
});
160160
expect(res.stylesXmlFile).toBe(fn);
161161
});
162162
});
163163

164-
describe('display of nested fields',function() {
165-
it('should write nested fields as json',function() {
164+
describe('display of nested fields', function () {
165+
it('should write nested fields as json', function () {
166166
var res = prep(objectData);
167167
expect(res.rows[0][3]).toEqual('{"field":"foo"}');
168168
});
169169
});
170170
});
171171

172-
describe('working with missing fields',function() {
173-
it('should leave missing fields blank',function() {
172+
describe('working with missing fields', function () {
173+
it('should leave missing fields blank', function () {
174174
var res = prep([
175175
{
176176
"firma": "transportabel",
@@ -197,13 +197,43 @@ describe('prepare',function() {
197197
}
198198
]);
199199
expect(res.rows[2][1]).toEqual(null);
200-
})
201-
})
200+
});
201+
});
202+
203+
describe('handling empty value in first row', function () {
204+
it('should leave missing fields blank', function () {
205+
var res = prep([
206+
{
207+
"internet": "http://www.transportabel.de",
208+
"Branche": "Möbel",
209+
"STRASSE": "Messingweg 49",
210+
"ort": "Münster-Sprakel",
211+
"TEL_ZENTRALE": "(0251) 29 79 46"
212+
},
213+
{
214+
"firma": "Soziale Möbelbörse & mehr e.V.",
215+
"internet": "http://www.gersch-ms.de",
216+
"Branche": "Möbel",
217+
"STRASSE": "Nienkamp 80",
218+
"ort": "Münster-Wienburg",
219+
"TEL_ZENTRALE": "(0251) 53 40 76"
220+
},
221+
{
222+
"firma": "Bald Eckhart e.K.",
223+
"Branche": "Möbel",
224+
"STRASSE": "Weseler Str. 628",
225+
"ort": "Münster-Mecklenbeck",
226+
"TEL_ZENTRALE": "(0251) 53 40 76"
227+
}
228+
]);
229+
expect(res.rows[1][0]).toEqual('Soziale Möbelbörse & mehr e.V.');
230+
});
231+
});
202232

203-
describe('prepping with config',function() {
204-
it('should get a nested field',function() {
205-
var res = prep(objectData,{
206-
fields:['nested.field']
233+
describe('prepping with config', function () {
234+
it('should get a nested field', function () {
235+
var res = prep(objectData, {
236+
fields: ['nested.field']
207237
});
208238
expect(res.rows[0]).toEqual(['foo']);
209239
})

0 commit comments

Comments
 (0)