Socket
Socket
Sign inDemoInstall

libxl

Package Overview
Dependencies
1
Maintainers
1
Versions
51
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 0.0.12 to 0.1.0

7

demo.js

@@ -33,2 +33,7 @@ var xl = require('./lib/libxl');

sheet.insertRow(row, row+1);
row += 2;
sheet.insertCol(1, 2);
sheet

@@ -53,2 +58,4 @@ .writeStr(row, 0, 'True')

row++;
sheet.split(2, 5);
}

@@ -55,0 +62,0 @@

4

package.json

@@ -5,4 +5,4 @@ {

"license": "MIT",
"version": "0.0.12",
"description": "Libxl bindings for node - read and write excel files using the libxl library.",
"version": "0.1.0",
"description": "Node bindings for the libxl library for reading and writing excel (XLS and XLSX) spreadsheets.",
"keywords": [

@@ -9,0 +9,0 @@ "excel",

@@ -6,6 +6,4 @@ # What it is

# How to use it
# Compilation and Installation
## Installation
Pull the library into your project with `npm install libxl`

@@ -16,6 +14,51 @@ and require the module via

## API
## LibXL installation
### Usage
As this packages contains only bindings for the libxl library, the library
itself is required for building and running the bindings.
### Compilation Phase
Before the bindings are compiled, the `install-libxl.js` script pulls the latest
version of the library from the libxl website and unpacks it in `deps/libxl`.
Therefore, **no separate installation of libxl is necessary for building the
bindings**.
However, if you want to compile and run against a particular version of libxl,
you can do so by manually unpacking the library archive into `deps/libxl` before
building the bindings. This will bypass the `install-libxl.js` script and build
the bindings against that specific version of the library.
### Runtime
In order to load and use the bindings, the libxl library must be available in
your dynamic library search path. This is achieved by either
**Copying the library into your system library search path**, e.g. `/usr/lib` on
Linux.
**Copying the library into the working directory** where you run the scrip which
uses the bindings. The name of the library file is `libxl.so` on Linux,
`libxl.dylib` on Mac and `libxl.dll` on Windows.
**Properly setting the `LD_LIBRARY_PATH` (Linux) or `DYLD_LIBRARY_PATH` (Mac)**
environment variable. For example, the following command will execute the
`demo.js` script in the package directory without requiring libxl to be
installed separately
LD_LIBRARY_PATH="`pwd`/deps/libxl/lib:`pwd`/deps/libxl/lib64:$LD_LIBRARY_PATH" node demo.js
### Overriding the location of the compiled bindings
You can override the location where the Javascript wrapper looks for the
`libxl.node` file by setting the `NODE_LIBXL_PATH` environment variable. This
allows to distribute / deploy an application that uses the bindings to a system
which runs on a different platform / architecture without recompiling the
bindings there.
# API
## Usage
A new excel document is created via

@@ -61,6 +104,4 @@

In C++, the cell value getters on Sheet (e.g. Sheet::readStr) can store the cell
format in an optional second argument. In Javascript, this is implemented by
allowing for an optional JS object as second parameter which will receive the
format in its 'format' property.
See 'Differences...' below for a more detailed description of the methods whose
behavior differs from their C++ counterpart.

@@ -72,12 +113,51 @@ **IMPORTANT:** The Javascript API enforces the types defined in its C++

### Coverage
## Coverage
API coverage is a work in progress. At the moment, the Font, Format and Book
(except methods dealing with embedded pictures) classes are fully implemented,
and Sheet is about 50% covered (reading, writing, formatting and splitting cells
works fine). Please see the jasmine specs and the class initializers
(Book::Initialize, Sheet::Initialize, Format::Initialize, Font::Initialize) for
a more detailed overview of what is currently supported
:).
The bindings cover the libxl API almost completely. The only functions still
missing are the methods for managing pictures embedded in spreadsheets and
`book.loadRaw` / `book.saveRaw`.
## Differences w.r.t. the C++ API
### Not implemented yet
* `book.loadRaw`
* `book.saveRaw`
* `book.pictureSize`
* `book.getPicture`
* `book.addPicture`
* `book.addPicture2`
* `sheet.pictureSize`
* `sheet.getPicture`
* `sheet.addPicture`
* `sheet.addPicture2`
### Interface differences
* `book.dateUnpack`: Returns an object with `year`, `month`,
`date`, `hour`, `minute`, `seconds` and `mseconds` properties.
* `book.colorUnpack`: Returns an object with `red`, `green` and `blue`
properties.
* `book.defaultFont`: Returns an object with `name` and `size` properties.
* `sheet.readStr` & friends: If `sheet.readXXX` is provided with an object as
optional second argument, the cell format is returned in the objects `format`
property.
* `sheet.getMerge`: Returns an object with the `rowFirst`, `rowLast`,
`colFirst`, `colLast` properties.
* `sheet.getPrintFit`: Returns either `false` or an object with the `wPages` and
`hPages` properties.
* `sheet.getNamedRange`: Returns an object with `rowFirst`, `rowLast`,
`colFirst`, `colLast` and `hidden` properties.
* `sheet.namedRange`: Returns an object with `rowFirst`, `rowLast`,
`colFirst`, `colLast`, `name`, `scopeId`, and `hidden` properties.
* `sheet.getTopLeftView`: Returns an object with `row` and `col` properties.
* `sheet.addrToRowCol`: Returns an object with `row`, `col`, `rowRelative`,
`colRelative` properties.
### Other differences
* Book object creation: Books are **not** created via `xlCreateBook` and
`xlCreateXMLBook`. Instead, object instances are directly constructed from the
`xl.Book` constructor via either `new xl.Book(xl.BOOK_TYPE_XLS)` or `new xl.Book(xl.BOOK_TYPE_XLSX)`
## Unlocking the API

@@ -91,12 +171,23 @@

## Platform support
# Platform support
The package currently supports Linux, Windows and Mac.
# How to contribute
# Tests
I'll be happy to merge in all sensible pull requests. If you
implement a new API method, please add a short test to the
jasmine specs and a call to demo.js (if applicable).
The bindings are fully covered with jasmine tests. If you have jasmine-node
installed (via NPM), you can run the suite via
jasmine-node specs/
# Reporting bugs
Please report any bugs on the github issue tracker.
# Roadmap
Version 0.1 is the first release which covers nearly the full API. For 0.2 (and
possibly 0.3), I anticipate adding asynchroneous calls for reading and writing
and implementing the remaining functions.
# Credits

@@ -103,0 +194,0 @@

@@ -14,4 +14,9 @@ var xl = require('../lib/libxl'),

wrongFormat = wrongBook.addFormat(),
sheetNameIdx = 0,
row = 1;
function newSheet() {
return book.addSheet('foo' + (sheetNameIdx++));
}
it('sheet.cellType determines cell type', function() {

@@ -321,2 +326,417 @@ sheet

});
it('sheet.getHorPageBreak, sheet.setHorPageBreak and sheet.horPageBreakSize' +
'manage horizontal page breaks', function()
{
shouldThrow(sheet.getHorPageBreakSize, {});
var n = sheet.getHorPageBreakSize();
shouldThrow(sheet.setHorPageBreak, sheet, 'a');
shouldThrow(sheet.setHorPageBreak, {}, row);
expect(sheet.setHorPageBreak(row)).toBe(sheet);
expect(sheet.getHorPageBreakSize()).toBe(n + 1);
shouldThrow(sheet.getHorPageBreak, sheet, 'a');
shouldThrow(sheet.getHorPageBreak, {}, n + 1);
expect(sheet.getHorPageBreak(n)).toBe(row);
sheet.setHorPageBreak(row, false);
expect(sheet.getHorPageBreakSize()).toBe(n);
});
it('sheet.getVerPageBreak, sheet.setVerPageBreak and sheet.horPageBreakSize' +
'manage vertical page breaks', function()
{
shouldThrow(sheet.getVerPageBreakSize, {});
var n = sheet.getVerPageBreakSize();
shouldThrow(sheet.setVerPageBreak, sheet, 'a');
shouldThrow(sheet.setVerPageBreak, {}, row);
expect(sheet.setVerPageBreak(10)).toBe(sheet);
expect(sheet.getVerPageBreakSize()).toBe(n + 1);
shouldThrow(sheet.getVerPageBreak, sheet, 'a');
shouldThrow(sheet.getVerPageBreak, {}, n + 1);
expect(sheet.getVerPageBreak(n)).toBe(10);
sheet.setVerPageBreak(10, false);
expect(sheet.getVerPageBreakSize()).toBe(n);
});
it('sheet.split splits a sheet', function() {
var book = new xl.Book(xl.BOOK_TYPE_XLS),
sheet = book.addSheet('foo');
shouldThrow(sheet.split, sheet, 'a', 1);
shouldThrow(sheet.split, {}, 2, 2);
expect(sheet.split(2, 2)).toBe(sheet);
});
it('sheet.groupRows groups rows', function() {
var sheet = newSheet();
shouldThrow(sheet.groupRows, sheet, 1, 'a');
shouldThrow(sheet.groupRows, {}, 1, 2);
expect(sheet.groupRows(1, 2)).toBe(sheet);
});
it('sheet.groupCols groups columns', function() {
var sheet = newSheet();
shouldThrow(sheet.groupCols, sheet, 1, 'a');
shouldThrow(sheet.groupCols, {}, 1, 2);
expect(sheet.groupCols(1, 2)).toBe(sheet);
});
it('sheet.setGroupSummaryBelow / sheet.groupSummaryBelow manage vert summary position', function() {
shouldThrow(sheet.setGroupSummaryBelow, sheet, 1);
shouldThrow(sheet.setGroupSummaryBelow, {}, true);
expect(sheet.setGroupSummaryBelow(true)).toBe(sheet);
shouldThrow(sheet.groupSummaryBelow, {});
expect(sheet.groupSummaryBelow()).toBe(true);
expect(sheet.setGroupSummaryBelow(false).groupSummaryBelow()).toBe(false);
});
it('sheet.setGroupSummaryRight / sheet.groupSummaryRight manage hor summary position', function() {
shouldThrow(sheet.setGroupSummaryRight, sheet, 1);
shouldThrow(sheet.setGroupSummaryRight, {}, true);
expect(sheet.setGroupSummaryRight(true)).toBe(sheet);
shouldThrow(sheet.groupSummaryRight, {});
expect(sheet.groupSummaryRight()).toBe(true);
expect(sheet.setGroupSummaryRight(false).groupSummaryRight()).toBe(false);
});
it('sheet.clear clears the sheet', function() {
var sheet = newSheet();
sheet
.writeStr(1, 1, 'foo')
.writeStr(2, 1, 'bar');
shouldThrow(sheet.clear, sheet, 'a');
shouldThrow(sheet.clear, {}, 1, 1, 1, 1);
expect(sheet.clear(1, 1, 1, 1)).toBe(sheet);
expect(function() {sheet.readStr(1, 1);}).toThrow();
expect(sheet.readStr(2, 1)).toBe('bar');
});
it('sheet.insertRow and sheet.insertCol insert rows and cols', function() {
var sheet = newSheet();
sheet
.writeStr(1, 1, '11')
.writeStr(1, 2, '12')
.writeStr(2, 1, '21')
.writeStr(2, 2, '22');
shouldThrow(sheet.insertRow, sheet, 'a', 2);
shouldThrow(sheet.insertRow, {}, 2, 3);
shouldThrow(sheet.insertCol, sheet, 'a', 2);
shouldThrow(sheet.insertCol, {}, 2, 3);
expect(sheet.insertRow(2, 3)).toBe(sheet);
expect(sheet.insertCol(2, 3)).toBe(sheet);
expect(sheet.readStr(1, 1)).toBe('11');
expect(sheet.readStr(1, 4)).toBe('12');
expect(sheet.readStr(4, 1)).toBe('21');
expect(sheet.readStr(4, 4)).toBe('22');
});
it('sheet.removeRow and sheet.removeCol remove rows and cols', function() {
var sheet = newSheet();
sheet
.writeStr(1, 1, '11')
.writeStr(1, 4, '12')
.writeStr(4, 1, '21')
.writeStr(4, 4, '22');
shouldThrow(sheet.removeRow, sheet, 'a', 2);
shouldThrow(sheet.removeRow, {}, 2, 3);
shouldThrow(sheet.removeCol, sheet, 'a', 2);
shouldThrow(sheet.removeCol, {}, 2, 3);
expect(sheet.removeRow(2, 3)).toBe(sheet);
expect(sheet.removeCol(2, 3)).toBe(sheet);
expect(sheet.readStr(1, 1)).toBe('11');
expect(sheet.readStr(1, 2)).toBe('12');
expect(sheet.readStr(2, 1)).toBe('21');
expect(sheet.readStr(2, 2)).toBe('22');
});
it('sheet.copyCell copies a cell', function() {
sheet.writeStr(row, 0, 'baz');
shouldThrow(sheet.copyCell, sheet, row, 0, row, 'a');
shouldThrow(sheet.copyCell, {}, row, 0, row, 1);
expect(sheet.copyCell(row, 0, row, 1)).toBe(sheet);
expect(sheet.readStr(row, 1)).toBe('baz');
row++;
});
it('sheet.firstRow, sheet.firstCol, sheet.lastRow, sheet.lastCol return ' +
'the spreadsheet limits', function()
{
var sheet = newSheet();
sheet
.writeNum(2, 1, 1)
.writeNum(5, 5, 1);
shouldThrow(sheet.firstRow, {});
shouldThrow(sheet.firstCol, {});
shouldThrow(sheet.lastRow, {});
shouldThrow(sheet.lastCol, {});
expect(sheet.firstRow()).toBe(2);
expect(sheet.firstCol()).toBe(1);
expect(sheet.lastRow()).toBe(6);
expect(sheet.lastCol()).toBe(6);
});
it('sheet.displayGridlines and sheet.setDisplayGridlines manage display of gridlines', function() {
shouldThrow(sheet.setDisplayGridlines, sheet, 1);
shouldThrow(sheet.setDisplayGridlines, {});
expect(sheet.setDisplayGridlines()).toBe(sheet);
shouldThrow(sheet.displayGridlines, {});
expect(sheet.displayGridlines()).toBe(true);
expect(sheet.setDisplayGridlines(false).displayGridlines()).toBe(false);
});
it('sheet.printGridlines and sheet.setPrintGridlines manage print of gridlines', function() {
shouldThrow(sheet.setPrintGridlines, sheet, 1);
shouldThrow(sheet.setPrintGridlines, {});
expect(sheet.setPrintGridlines()).toBe(sheet);
shouldThrow(sheet.printGridlines, {});
expect(sheet.printGridlines()).toBe(true);
expect(sheet.setPrintGridlines(false).printGridlines()).toBe(false);
});
it('sheet.zoom and sheet.setZoom control sheet zoom', function() {
shouldThrow(sheet.setZoom, sheet, true);
shouldThrow(sheet.setZoom, {}, 10);
expect(sheet.setZoom(10)).toBe(sheet);
shouldThrow(sheet.zoom, {});
expect(sheet.zoom()).toBe(10);
expect(sheet.setZoom(1).zoom()).toBe(1);
});
it('sheet.setLandscape and sheet.landscape control landscape mode', function() {
shouldThrow(sheet.setLandscape, sheet, 1);
shouldThrow(sheet.setLandscape, {});
expect(sheet.setLandscape()).toBe(sheet);
shouldThrow(sheet.landscape, {});
expect(sheet.landscape()).toBe(true);
expect(sheet.setLandscape(false).landscape()).toBe(false);
});
it('sheet.paper and sheet.setPaper control paper format', function() {
shouldThrow(sheet.setPaper, sheet, true);
shouldThrow(sheet.setPaper, {}, xl.PAPER_NOTE);
expect(sheet.setPaper(xl.PAPER_NOTE)).toBe(sheet);
shouldThrow(sheet.paper, {});
expect(sheet.paper()).toBe(xl.PAPER_NOTE);
expect(sheet.setPaper().paper()).toBe(xl.PAPER_DEFAULT);
});
it('sheet.header, sheet.setHeader and sheet.headerMargin control the header', function() {
shouldThrow(sheet.setHeader, sheet, 1);
shouldThrow(sheet.setHeader, {}, 'fuppe');
expect(sheet.setHeader('fuppe')).toBe(sheet);
shouldThrow(sheet.header, {});
expect(sheet.header()).toBe('fuppe');
shouldThrow(sheet.headerMargin, {});
expect(sheet.headerMargin()).toBe(0.5);
expect(sheet.setHeader('fuppe', 11.11).headerMargin()).toBe(11.11);
});
it('sheet.footer, sheet.setFooter and sheet.footerMargin control the footer', function() {
shouldThrow(sheet.setFooter, sheet, 1);
shouldThrow(sheet.setFooter, {}, 'foppe');
expect(sheet.setFooter('foppe')).toBe(sheet);
shouldThrow(sheet.footer, {});
expect(sheet.footer()).toBe('foppe');
shouldThrow(sheet.footerMargin, {});
expect(sheet.footerMargin()).toBe(0.5);
expect(sheet.setFooter('foppe', 11.11).footerMargin()).toBe(11.11);
});
['Left', 'Right', 'Bottom', 'Top'].forEach(function(side) {
var getter = 'margin' + side,
setter = 'setMargin' + side;
it(util.format('sheet.%s and sheet.%s control %s margin',
getter, setter, side.toLowerCase()), function()
{
shouldThrow(sheet[setter], sheet, true);
shouldThrow(sheet[setter], {}, 11.11);
expect(sheet[setter](11.11)).toBe(sheet);
shouldThrow(sheet[getter], {});
expect(sheet[getter]()).toBe(11.11);
expect(sheet[setter](12.12)[getter]()).toBe(12.12);
});
});
it('sheet.printRowCol and sheet.setPrintRowCol control printing of row / col headers', function() {
shouldThrow(sheet.setPrintRowCol, sheet, 1);
shouldThrow(sheet.setPrintRowCol, {});
expect(sheet.setPrintRowCol()).toBe(sheet);
shouldThrow(sheet.printRowCol, {});
expect(sheet.printRowCol()).toBe(true);
expect(sheet.setPrintRowCol(false).printRowCol()).toBe(false);
});
it('sheet.setPrintRepeatRows, sheet.setPrintRepeatCols, sheet.clearPrintRepeat ' +
' control row / col repeat in print', function()
{
shouldThrow(sheet.setPrintRepeatRows, sheet, true, 1);
shouldThrow(sheet.setPrintRepeatRows, {}, 1, 1);
expect(sheet.setPrintRepeatRows(1, 1)).toBe(sheet);
shouldThrow(sheet.setPrintRepeatCols, sheet, true, 1);
shouldThrow(sheet.setPrintRepeatCols, {}, 1, 1);
expect(sheet.setPrintRepeatCols(1, 1)).toBe(sheet);
shouldThrow(sheet.clearPrintRepeats, {});
expect(sheet.clearPrintRepeats()).toBe(sheet);
});
it('sheet.setPrintArea and sheet.clearPrintArea manage the print area', function() {
shouldThrow(sheet.setPrintArea, sheet, true, 1, 5, 5);
shouldThrow(sheet.setPrintArea, {}, 1, 1, 5, 5);
expect(sheet.setPrintArea(1, 1, 5, 5)).toBe(sheet);
shouldThrow(sheet.clearPrintArea, {});
expect(sheet.clearPrintArea()).toBe(sheet);
});
it('sheet.getNamedRange, sheet.setNamedRange, sheet.delNamedRange, sheet.namedRangeSize and sheet.namedRange ' +
'manage named ranges', function()
{
var sheet2 = newSheet();
function assertRange(range, rowFirst, rowLast, colFirst, colLast, name, scope) {
expect(range.rowFirst).toBe(rowFirst);
expect(range.rowLast).toBe(rowLast);
expect(range.colFirst).toBe(colFirst);
expect(range.colLast).toBe(colLast);
if (typeof(name) !== 'undefined') {
expect(range.name).toBe(name);
}
if (typeof(scope) !== 'undefined') {
expect(range.scopeId).toBe(scope);
}
}
shouldThrow(sheet.setNamedRange, sheet, 'range1', 'a', 1, 5, 5);
shouldThrow(sheet.setNamedRange, {}, 'range1', 1, 1, 5, 5);
expect(sheet.setNamedRange('range1', 1, 1, 5, 5, xl.SCOPE_WORKBOOK)).toBe(sheet);
expect(sheet2.setNamedRange('range2', 2, 2, 6, 6)).toBe(sheet2);
shouldThrow(sheet.namedRangeSize, {});
expect(sheet.namedRangeSize()).toBe(1);
expect(sheet2.namedRangeSize()).toBe(1);
var range1, range2;
shouldThrow(sheet.getNamedRange, sheet, 1);
shouldThrow(sheet.getNamedRange, {}, 'range1');
shouldThrow(sheet2.getNamedRange, sheet, 'range2', xl.SCOPE_WORKBOOK);
assertRange(sheet.getNamedRange('range1'), 1, 1, 5, 5);
assertRange(sheet2.getNamedRange('range2'), 2, 2, 6, 6);
shouldThrow(sheet.namedRange, sheet, true);
shouldThrow(sheet.namedRange, {}, 0);
assertRange(sheet.namedRange(0), 1, 1, 5, 5, 'range1', xl.SCOPE_WORKBOOK);
assertRange(sheet2.namedRange(0), 2, 2, 6, 6, 'range2');
shouldThrow(sheet.delNamedRange, sheet, 1);
shouldThrow(sheet.delNamedRange, {}, 'range1');
expect(sheet.delNamedRange('range1')).toBe(sheet);
expect(sheet.namedRangeSize()).toBe(0);
});
it('sheet.name and sheet.setName manage the sheet name', function() {
var sheet = book.addSheet('bazzaraz');
shouldThrow(sheet.name, {});
expect(sheet.name()).toBe('bazzaraz');
shouldThrow(sheet.setName, sheet, 1);
shouldThrow(sheet.setName, {}, 'fooinator');
expect(sheet.setName('fooinator')).toBe(sheet);
expect(sheet.name()).toBe('fooinator');
});
it('sheet.protect and sheet.setProtect manage the protection flag', function() {
shouldThrow(sheet.setProtect, sheet, 1);
shouldThrow(sheet.setProtect, {});
expect(sheet.setProtect()).toBe(sheet);
shouldThrow(sheet.protect, {});
expect(sheet.protect()).toBe(true);
expect(sheet.setProtect(false).protect()).toBe(false);
});
it('sheet.hidden and sheet.setHidden control wether a sheet is visible', function() {
shouldThrow(sheet.setHidden, sheet, true);
shouldThrow(sheet.setHidden, {});
expect(sheet.setHidden()).toBe(sheet);
shouldThrow(sheet.hidden, {});
expect(sheet.hidden()).toBe(xl.SHEETSTATE_HIDDEN);
expect(sheet.setHidden(xl.SHEETSTATE_VISIBLE).hidden()).toBe(xl.SHEETSTATE_VISIBLE);
});
it('sheet.getTopLeftView and sheet.setTopLeftView manage top left visible edge of the sheet',
function()
{
var sheet = newSheet();
shouldThrow(sheet.setTopLeftView, sheet, 5, true);
shouldThrow(sheet.setTopLeftView, {}, 5, 6);
expect(sheet.setTopLeftView(5, 6)).toBe(sheet);
shouldThrow(sheet.getTopLeftView, {});
var result = sheet.getTopLeftView();
expect(result.row).toBe(5);
expect(result.col).toBe(6);
});
it('sheet.addrToRowCol translates a string address to row / col', function() {
shouldThrow(sheet.addrToRowCol, sheet, 1);
shouldThrow(sheet.addrToRowCol, {}, 'A1');
var result = sheet.addrToRowCol('A1');
expect(result.row).toBe(0);
expect(result.col).toBe(0);
expect(result.rowRelative).toBe(true);
expect(result.colRelative).toBe(true);
});
it('sheet.rowColToAddr builds an address string', function() {
shouldThrow(sheet.rowColToAddr, sheet, 0, 'a');
shouldThrow(sheet.rowColToAddr, {}, 0, 0);
expect(sheet.rowColToAddr(0, 0)).toBe('A1');
expect(sheet.rowColToAddr(0, 0, false, false)).toBe('$A$1');
});
});

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Packages

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc