Permalink
Browse files

Initial commit.

Does not actually generate the right XLSX file yet, but it does pack one
correctly. Test harnass in place as well.
  • Loading branch information...
0 parents commit 34def2887a63adcd41fc2553c2ec08bf6468dbd3 @rubenv committed Mar 11, 2013
Showing with 418 additions and 0 deletions.
  1. +4 −0 .gitignore
  2. +4 −0 .npmignore
  3. +54 −0 Gruntfile.coffee
  4. +22 −0 LICENSE-MIT
  5. +65 −0 README.md
  6. +52 −0 package.json
  7. +122 −0 src/blobs.coffee
  8. +44 −0 src/index.coffee
  9. +38 −0 test/common.coffee
  10. +13 −0 test/simple_test.coffee
@@ -0,0 +1,4 @@
+.*.swp
+node_modules
+lib
+tmp
@@ -0,0 +1,4 @@
+.npmignore
+Gruntfile.coffee
+src
+test
@@ -0,0 +1,54 @@
+module.exports = (grunt) ->
+ @loadNpmTasks('grunt-contrib-clean')
+ @loadNpmTasks('grunt-contrib-coffee')
+ @loadNpmTasks('grunt-contrib-watch')
+ @loadNpmTasks('grunt-mocha-cli')
+ @loadNpmTasks('grunt-mkdir')
+
+ @initConfig
+ coffee:
+ all:
+ options:
+ bare: true
+ expand: true,
+ cwd: 'src',
+ src: ['*.coffee'],
+ dest: 'lib',
+ ext: '.js'
+
+ clean:
+ all: ['lib', 'tmp']
+
+ mkdir:
+ all:
+ options:
+ create: ['tmp']
+
+ watch:
+ all:
+ files: ['src/**.coffee', 'test/**.coffee']
+ tasks: ['test']
+
+ mochacli:
+ options:
+ files: 'test/*_test.coffee'
+ compilers: ['coffee:coffee-script']
+ spec:
+ options:
+ reporter: 'spec'
+
+ @registerTask 'npmPack', 'Create NPM package.', ->
+ done = @async()
+
+ grunt.util.spawn
+ cmd: 'npm'
+ args: ['pack']
+ , (error, result, code) ->
+ grunt.log.writeln(result.stderr) if result.stderr
+ grunt.log.writeln(result.stdout) if result.stdout
+ done(!error)
+
+ @registerTask 'default', ['test']
+ @registerTask 'build', ['clean', 'coffee']
+ @registerTask 'package', ['build', 'npmPack']
+ @registerTask 'test', ['build', 'mkdir', 'mochacli']
@@ -0,0 +1,22 @@
+Copyright (c) 2013 Ruben Vermeersch
+
+Permission is hereby granted, free of charge, to any person
+obtaining a copy of this software and associated documentation
+files (the "Software"), to deal in the Software without
+restriction, including without limitation the rights to use,
+copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following
+conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,65 @@
+# XLSX writer
+
+ Simple XLSX writer. Reverse-engineered from sample XLSX files.
+
+## Usage
+
+ You can install the latest version via npm:
+
+ $ npm install --save xslx-writer
+
+ Require the module:
+
+ var xlsx = require('xslx-writer');
+
+ Write a spreadsheet:
+
+ var data = [
+ {
+ "Name": "Bob",
+ "Location": "Sweden"
+ },
+ {
+ "Name": "Alice",
+ "Location": "France"
+ }
+ ];
+
+ xlsx.write('mySpreadsheet.xlsx', data, function (err) {
+ // Error handling here
+ });
+
+ This will write a spreadsheet like this:
+
+ Name | Location
+ --------+---------
+ Bob | Sweden
+ Alice | France
+
+ In other words: The key names are used for the first row (headers),
+ The values are used for the columns. All field names should be present
+ in the first row.
+
+## License
+
+ (The MIT License)
+
+ Copyright (C) 2013 by Ruben Vermeersch <ruben@savanne.be>
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
@@ -0,0 +1,52 @@
+{
+ "name": "xlsx-writer",
+ "description": "Simple XLSX writer.",
+ "version": "0.0.1",
+ "homepage": "https://github.com/rubenv/node-xlsx-writer",
+ "author": {
+ "name": "Ruben Vermeersch",
+ "email": "ruben@savanne.be",
+ "url": "http://savanne.be/"
+ },
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/rubenv/node-xlsx-writer.git"
+ },
+ "bugs": {
+ "url": "https://github.com/rubenv/node-xlsx-writer/issues"
+ },
+ "licenses": [
+ {
+ "type": "MIT",
+ "url": "https://github.com/rubenv/node-xlsx-writer/blob/master/LICENSE-MIT"
+ }
+ ],
+ "main": "lib/index.js",
+ "engines": {
+ "node": ">= 0.8.0"
+ },
+ "scripts": {
+ "test": "grunt test"
+ },
+ "devDependencies": {
+ "grunt-contrib-watch": "~0.3.1",
+ "grunt-contrib-coffee": "~0.6.0",
+ "grunt-contrib-clean": "~0.4.0",
+ "grunt": "~0.4.0",
+ "grunt-mocha-cli": "~1.0.1",
+ "coffee-script": "~1.6.1",
+ "grunt-mkdir": "~0.1.0",
+ "excel": "0.0.1",
+ "underscore": "~1.4.4"
+ },
+ "keywords": [
+ "xlsx",
+ "excel",
+ "spreadsheet"
+ ],
+ "dependencies": {
+ "temp": "~0.5.0",
+ "async": "~0.2.6",
+ "zipper": "~0.1.2"
+ }
+}
@@ -0,0 +1,122 @@
+module.exports =
+ contentTypes: """
+ <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+ <Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types">
+ <Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/>
+ <Default Extension="xml" ContentType="application/xml"/>
+ <Override PartName="/xl/workbook.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml"/>
+ <Override PartName="/xl/worksheets/sheet1.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml"/>
+ <Override PartName="/xl/styles.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml"/>
+ <Override PartName="/xl/sharedStrings.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.sharedStrings+xml"/>
+ </Types>
+ """.replace(/\n\s*/g, '')
+
+ rels: """
+ <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+ <Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">
+ <Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="xl/workbook.xml"/>
+ </Relationships>
+ """.replace(/\n\s*/g, '')
+
+ workbook: """
+ <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+ <workbook xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships">
+ <fileVersion appName="xl" lastEdited="5" lowestEdited="5" rupBuild="9303"/>
+ <workbookPr defaultThemeVersion="124226"/>
+ <bookViews>
+ <workbookView xWindow="480" yWindow="60" windowWidth="18195" windowHeight="8505"/>
+ </bookViews>
+ <sheets>
+ <sheet name="hello" sheetId="1" r:id="rId1"/>
+ </sheets>
+ <calcPr calcId="145621"/>
+ </workbook>
+ """.replace(/\n\s*/g, '')
+
+ workbookRels: """
+ <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+ <Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">
+ <Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet" Target="worksheets/sheet1.xml"/>
+ <Relationship Id="rId2" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/sharedStrings" Target="sharedStrings.xml"/>
+ <Relationship Id="rId3" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles" Target="styles.xml"/>
+ </Relationships>
+ """.replace(/\n\s*/g, '')
+
+ styles: """
+ <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+ <styleSheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="x14ac" xmlns:x14ac="http://schemas.microsoft.com/office/spreadsheetml/2009/9/ac">
+ <fonts count="1" x14ac:knownFonts="1">
+ <font>
+ <sz val="11"/>
+ <color theme="1"/>
+ <name val="Calibri"/>
+ <family val="2"/>
+ <scheme val="minor"/>
+ </font>
+ </fonts>
+ <fills count="2">
+ <fill>
+ <patternFill patternType="none"/>
+ </fill>
+ <fill>
+ <patternFill patternType="gray125"/>
+ </fill>
+ </fills>
+ <borders count="1">
+ <border>
+ <left/>
+ <right/>
+ <top/>
+ <bottom/>
+ <diagonal/>
+ </border>
+ </borders>
+ <cellStyleXfs count="1">
+ <xf numFmtId="0" fontId="0" fillId="0" borderId="0"/>
+ </cellStyleXfs>
+ <cellXfs count="1">
+ <xf numFmtId="0" fontId="0" fillId="0" borderId="0" xfId="0"/>
+ </cellXfs>
+ <cellStyles count="1">
+ <cellStyle name="Normal" xfId="0" builtinId="0"/>
+ </cellStyles>
+ <dxfs count="0"/>
+ <tableStyles count="0" defaultTableStyle="TableStyleMedium2" defaultPivotStyle="PivotStyleLight16"/>
+ <extLst>
+ <ext uri="{EB79DEF2-80B8-43e5-95BD-54CBDDF9020C}" xmlns:x14="http://schemas.microsoft.com/office/spreadsheetml/2009/9/main">
+ <x14:slicerStyles defaultSlicerStyle="SlicerStyleLight1"/>
+ </ext>
+ </extLst>
+ </styleSheet>
+ """.replace(/\n\s*/g, '')
+
+ strings: """
+ <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+ <sst xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" count="1" uniqueCount="1">
+ <si>
+ <t>Ruben</t>
+ </si>
+ </sst>
+ """.replace(/\n\s*/g, '')
+
+ sheet: """
+ <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+ <worksheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="x14ac" xmlns:x14ac="http://schemas.microsoft.com/office/spreadsheetml/2009/9/ac">
+ <dimension ref="A1:B1"/>
+ <sheetViews>
+ <sheetView workbookViewId="0"/>
+ </sheetViews>
+ <sheetFormatPr defaultRowHeight="15" x14ac:dyDescent="0.25"/>
+ <sheetData>
+ <row r="1">
+ <c r="A1" t="n">
+ <v>100</v>
+ </c>
+ <c r="B1" t="s">
+ <v>0</v>
+ </c>
+ </row>
+ </sheetData>
+ </worksheet>
+ """.replace(/\n\s*/g, '')
+
@@ -0,0 +1,44 @@
+fs = require('fs')
+temp = require('temp')
+path = require('path')
+async = require('async')
+zipper = require('zipper')
+
+blobs = require('./blobs')
+
+module.exports =
+ write: (out, data, cb) ->
+ tempPath = ''
+
+ filename = (folder, name) ->
+ parts = Array::slice.call(arguments)
+ parts.unshift(tempPath)
+ return path.join.apply(@, parts)
+
+ zipfile = new zipper.Zipper(out)
+
+ async.series [
+ (cb) -> temp.mkdir 'xlsx', (err, p) ->
+ tempPath = p
+ # Debug:
+ #tempPath = 'tmp'
+ cb(err)
+ (cb) -> fs.mkdir(filename('_rels'), cb)
+ (cb) -> fs.mkdir(filename('xl'), cb)
+ (cb) -> fs.mkdir(filename('xl', '_rels'), cb)
+ (cb) -> fs.mkdir(filename('xl', 'worksheets'), cb)
+ (cb) -> fs.writeFile(filename('[Content_Types].xml'), blobs.contentTypes, cb)
+ (cb) -> fs.writeFile(filename('_rels', '.rels'), blobs.rels, cb)
+ (cb) -> fs.writeFile(filename('xl', 'workbook.xml'), blobs.workbook, cb)
+ (cb) -> fs.writeFile(filename('xl', 'styles.xml'), blobs.styles, cb)
+ (cb) -> fs.writeFile(filename('xl', 'sharedStrings.xml'), blobs.strings, cb)
+ (cb) -> fs.writeFile(filename('xl', '_rels', 'workbook.xml.rels'), blobs.workbookRels, cb)
+ (cb) -> fs.writeFile(filename('xl', 'worksheets', 'sheet1.xml'), blobs.sheet, cb)
+ (cb) -> zipfile.addFile(filename('[Content_Types].xml'), '[Content_Types].xml', cb)
+ (cb) -> zipfile.addFile(filename('_rels', '.rels'), '_rels/.rels', cb)
+ (cb) -> zipfile.addFile(filename('xl', 'workbook.xml'), 'xl/workbook.xml', cb)
+ (cb) -> zipfile.addFile(filename('xl', 'styles.xml'), 'xl/styles.xml', cb)
+ (cb) -> zipfile.addFile(filename('xl', 'sharedStrings.xml'), 'xl/sharedStrings.xml', cb)
+ (cb) -> zipfile.addFile(filename('xl', '_rels', 'workbook.xml.rels'), 'xl/_rels/workbook.xml.rels', cb)
+ (cb) -> zipfile.addFile(filename('xl', 'worksheets', 'sheet1.xml'), 'xl/worksheets/sheet1.xml', cb)
+ ], cb
Oops, something went wrong.

0 comments on commit 34def28

Please sign in to comment.