Skip to content

Commit

Permalink
Merge pull request #10 from rdmurphy/include-exclude
Browse files Browse the repository at this point in the history
Add support for includeSheets and excludeSheets
  • Loading branch information
rdmurphy authored Jun 29, 2016
2 parents e681194 + 65e5780 commit 61fa8cb
Show file tree
Hide file tree
Showing 5 changed files with 134 additions and 7 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Changelog

## 2.1.0

- Add support for `includeSheets` and `excludeSheets` options on `copytext.process`

## 2.0.0

- Remove `marked` dependency and Markdown support
Expand Down
34 changes: 29 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,8 @@ _Note: With **key/value** sheets, the processor will only care about content in
**corgis_keyvalue.xlsx**
_Sheet name: CORGIS_

| - | - |
| ----------------------|----------------------------------------|
| - | - |
| --------------------- | -------------------------------------- |
| **name** | Poky |
| **instagram_account** | <https://instagram.com/tibbythecorgi/> |

Expand Down Expand Up @@ -148,7 +148,7 @@ console.log(data);
// }
```

The override works in both directions &mdash; this would have produced the same result:
The override works in both directions this would have produced the same result:

```js
var data = copytext.process('./husky_keyvalue_corgis_table.xlsx', {
Expand All @@ -159,6 +159,26 @@ var data = copytext.process('./husky_keyvalue_corgis_table.xlsx', {
});
```

It's also possible to include or exclude entire sheets. This is useful if you only want one sheet to be converted (for example, the other sheets may be supplying data to the master sheet), or want to exclude certain sheets.

```js
var copytext = require('copytext');

var data = copytext.process('./husky_keyvalue_corgis_table.xlsx', {
'processor': 'table',
'includeSheets': ['CORGI']
});
```

```js
var copytext = require('copytext');

var data = copytext.process('./husky_keyvalue_corgis_table.xlsx', {
'processor': 'table',
'excludeSheets': ['HUSKY']
});
```

## In Practice

This is most useful when working with templates. Here's an example with the excellent [Nunjucks](http://mozilla.github.io/nunjucks/) library.
Expand Down Expand Up @@ -204,9 +224,13 @@ process it.
**Parameters**

- `rawXLSX` **([String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String) \| [Buffer](https://nodejs.org/api/buffer.html))** A Buffer of, or path to, an XLSX file
- `options` **\[[Object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object)]**
- `options` **\[[Object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object)]**
- `options.processor` **\[[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)]** The processor used on all sheets without overrides (optional, default `'keyvalue'`)
- `options.includeSheets` **\[([Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)&lt;[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)> | [String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String))]** Sheets to include (optional, default `undefined`)
- `options.excludeSheets` **\[([Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)&lt;[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)> | [String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String))]** Sheets to exclude (optional, default `undefined`)
- `options.overrides` **\[[Object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object)]** Key value pairs of the sheet name and processor that should be used (optional, default `undefined`)

Returns **[Object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object)**
Returns **[Object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object)**

## License

Expand Down
55 changes: 54 additions & 1 deletion index.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,19 @@ function getProcessor (name) {
*
* @param {String|Buffer} rawXLSX A Buffer of, or path to, an XLSX file
* @param {Object} [options]
* @param {String} [options.processor='keyvalue'] The processor used on all sheets without overrides
* @param {String[]|String} [options.includeSheets=undefined] Sheets to include
* @param {String[]|String} [options.excludeSheets=undefined] Sheets to exclude
* @param {Object} [options.overrides=undefined] Key value pairs of the sheet name and processor that should be used
* @return {Object}
*/
function process (rawXLSX, options) {
// if no options are passed, set an empty Object as default
options = options || {}

// check for errors in the options, and clean up if needed
options = validateOptions(options)

// if no processor is set, assume `keyvalue`
const defaultProcessor = options.processor || 'keyvalue'

Expand All @@ -50,7 +57,15 @@ function process (rawXLSX, options) {
const workbook = rawXLSX instanceof Buffer ? XLSX.read(rawXLSX, {type: 'buffer'}) : XLSX.readFile(rawXLSX)

// get the names of all the sheets in an Array
const sheets = workbook.SheetNames
let sheets = workbook.SheetNames

if (options.includeSheets) {
sheets = sheets.filter((s) => options.includeSheets.indexOf(s) !== -1)
}

if (options.excludeSheets) {
sheets = sheets.filter((s) => options.excludeSheets.indexOf(s) === -1)
}

// the eventual payload returned to the callback
let payload = {}
Expand All @@ -68,6 +83,44 @@ function process (rawXLSX, options) {
return payload
}

/**
* Validates and normalizes the options passed to `process`.
*
* @private
* @param {Object} options
* @return {Object}
*/
function validateOptions (options) {
// doesn't make sense to pass both, so prevent it
if (options.includeSheets && options.excludeSheets) {
throw new Error("Do not pass both `includeSheets` and `excludeSheets`. It's confusing.")
}

// if `includeSheets` exists and isn't an Array, make it so
if (options.includeSheets) {
if (!Array.isArray(options.includeSheets)) options.includeSheets = [options.includeSheets]
}

// if `excludeSheets` exists and isn't an Array, make it so
if (options.excludeSheets) {
if (!Array.isArray(options.excludeSheets)) options.excludeSheets = [options.excludeSheets]
}

// if `excludeSheets` is set and one of them show up in `overrides`, it won't
// break anything, but the user should be aware it won't work
if (options.excludeSheets && options.overrides) {
const overrides = Object.keys(options.overrides)

overrides.forEach((override) => {
if (options.excludeSheets.indexOf(override) !== -1) {
console.warn(`\`${override}\` has an override, but it is also being excluded in \`excludeSheets\`.`)
}
})
}

return options
}

module.exports = {
process
}
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "copytext",
"version": "2.0.0",
"version": "2.1.0",
"description": "A module for accessing a XLSX spreadsheet as a JavaScript object.",
"main": "index.js",
"files": [
Expand Down
46 changes: 46 additions & 0 deletions test/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -149,3 +149,49 @@ describe('reading mixed key value/table sheets', function () {
}), mixedKeyValueTable)
})
})

describe('including/excluding sheets in a file', function () {
it('should throw an error if both `includeSheets` and `excludeSheets` are used', function () {
const input = () => {
copytext.process('./test/files/multi_keyvalue.xlsx', {
includeSheets: ['CORGI'],
excludeSheets: ['SHIBA']
}, basicKeyValue)
}

assert.throws(input, (e) => e instanceof Error && /Do not pass both `includeSheets` and `excludeSheets`/.test(e))
})

it('should only include sheets listed in `includeSheets` when passed', function () {
assert.deepEqual(copytext.process('./test/files/multi_keyvalue.xlsx', {
includeSheets: ['CORGI']
}), basicKeyValue)
})

it('should only include sheet listed in `includeSheets` when passed as single value', function () {
assert.deepEqual(copytext.process('./test/files/multi_keyvalue.xlsx', {
includeSheets: 'CORGI'
}), basicKeyValue)
})

it('should only exclude sheets listed in `excludeSheets` when passed', function () {
assert.deepEqual(copytext.process('./test/files/multi_keyvalue.xlsx', {
excludeSheets: ['SHIBA']
}), basicKeyValue)
})

it('should only exclude sheet listed in `excludeSheets` when passed as single value', function () {
assert.deepEqual(copytext.process('./test/files/multi_keyvalue.xlsx', {
excludeSheets: 'SHIBA'
}), basicKeyValue)
})

it('should still exclude sheets listed in `excludeSheets` when passed, even if an override is also passed', function () {
assert.deepEqual(copytext.process('./test/files/multi_keyvalue.xlsx', {
excludeSheets: ['SHIBA'],
overrides: {
'SHIBA': 'table'
}
}), basicKeyValue)
})
})

0 comments on commit 61fa8cb

Please sign in to comment.