node package manager

copytext

A module for accessing a XLSX spreadsheet as a JavaScript object.

node-copytext

A node library for accessing a XLSX spreadsheet as a JavaScript object. Inspired by the NPR visuals team's copytext Python library. Works great coupled with a group-edited Google Spreadsheet exported as a XLSX file.

  • Access an XLSX spreadsheet as a JavaScript object
  • Great for passing into templates, saving to a file, etc.
  • XLSX spreadsheets can be loaded via path or Buffer
  • Can process both key/value sheets and table layouts
npm install --save-dev copytext

If you're looking to do some work on node-copytext itself, clone the repo instead:

git clone https://github.com/rdmurphy/node-copytext.git
cd node-copytext
npm install
npm test # make sure everything already works! 

And you're good to go!

copytext can work with both key/value and table layouts. By default, it assumes you're passing key/value sheets.

Note: With key/value sheets, the processor will only care about content in the first two columns. Anything else will be ignored. (Meaning the other columns are a great place to leave notes!)

corgis_keyvalue.xlsx
Sheet name: CORGIS

- -
name Poky
instagram_account https://instagram.com/tibbythecorgi/
var copytext = require('copytext');
 
var data = copytext.process('./corgis_keyvalue.xlsx');
 
console.log(data);
 
// { 
//   'CORGIS': { 
//     'name': 'Poky', 
//     'instagram_account': 'https://instagram.com/poky_corgi/' 
//   } 
// } 

To tell copytext to use the table parser instead, pass an object as the second argument to copytext with processor set to table.

corgis_table.xlsx
Sheet name: CORGIS

name instagram_account
Poky https://instagram.com/poky_corgi/
Tibby https://instagram.com/tibbythecorgi/
var copytext = require('copytext');
 
var data = copytext.process('./corgis_table.xlsx', {
  'processor': 'table'
});
 
console.log(data);
 
// { 
//   'CORGIS': [{ 
//     'name': 'Poky', 
//     'instagram_account': 'https://instagram.com/poky_corgi/' 
//   },{ 
//     'name': 'Tibby', 
//     'instagram_account': 'https://instagram.com/tibbythecorgi/' 
//   }] 
// } 

Have a spreadsheet that uses both layouts? No problem! Tell copytext which sheets are the exception. Overrides are passed in as a list to the options object on the overrides key. Each override should have the name of the sheet as the key, and the name of the processor as the value.

Assume we have the previous example's CORGIS sheet in a spreadsheet plus this sheet:

Sheet name: SHIBA

var copytext = require('copytext');
 
var data = copytext.process('./husky_keyvalue_corgis_table.xlsx', {
  'processor': 'table',
  'overrides': {
    'SHIBA': 'keyvalue'
  }
});
 
console.log(data);
 
// { 
//   'CORGIS': [{ 
//     'name': 'Poky', 
//     'instagram_account': 'https://instagram.com/poky_corgi/' 
//   }, 
//   { 
//     'name': 'Tibby', 
//     'instagram_account': 'https://instagram.com/tibbythecorgi/' 
//   }], 
//   'SHIBAS': { 
//     'name': 'Maru', 
//     'instagram_account': 'https://instagram.com/marutaro/' 
//   } 
// } 

The override works in both directions — this would have produced the same result:

var data = copytext.process('./husky_keyvalue_corgis_table.xlsx', {
  'processor': 'keyvalue',
  'overrides': {
    'CORGIS': 'table'
  }
});

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.

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

This is most useful when working with templates. Here's an example with the excellent Nunjucks library.

var fs = require('fs');
var copytext = require('copytext');
var nunjucks = require('nunjucks');
 
var data = copytext.process('./data/contacts.xlsx');  // a key/value sheet named CONTACTS 
var res = nunjucks.render('index.html', {DATA: data});

index.html

<ul>
  <li>{{ DATA.CONTACTS.name }}</li>
  <li>{{ DATA.CONTACTS.address }}</li>
  <li>{{ DATA.CONTACTS.phone }}</li>
</ul>

If you pass in a table sheet, you can loop through it! (Assume CONTACTS is a table.)

index.html

<ul>
  {% for contact in DATA.CONTACTS %}
  <li>{{ contact.name }} | {{ contact.address }} | {{ contact.phone }}</li>
  {% endfor %}
</ul>

Accepts a raw XLSX file and options that determine how copytext should process it.

Parameters

  • rawXLSX (String | Buffer) A Buffer of, or path to, an XLSX file
  • options [Object]
    • options.processor [String] The processor used on all sheets without overrides (optional, default 'keyvalue')
    • options.includeSheets [(Array<String> | String)] Sheets to include (optional, default undefined)
    • options.excludeSheets [(Array<String> | String)] Sheets to exclude (optional, default undefined)
    • options.overrides [Object] Key value pairs of the sheet name and processor that should be used (optional, default undefined)

Returns Object

By Ryan Murphy.

Available under the MIT license.