javascript - Creating Transform stream using ExcelJS for writing xlsx -
i'm using exceljs module , writing wrapper purposes, implements transform stream api (yes, node version 0.10.40).
exceljs has stream api , according example in exceljs module can use 1 (execute node index.js > test.xlsx
):
var stream = require('stream'), excel = require('exceljs'); var rs = new stream.readable({objectmode: true}); rs.push({name: 'one'}); rs.push({name: 'two'}); rs.push({name: 'three'}); rs.push(null); var workbook = new excel.stream.xlsx.workbookwriter({stream: process.stdout}), worksheet = workbook.addworksheet('sheet 1'); worksheet.columns = [{header: 'name', key: 'name'}]; rs.on('data', function(doc) { worksheet.addrow({ name: doc.name }).commit(); }); rs.on('end', function(doc) { worksheet.commit(); workbook.commit(); });
and working fine, looks not clean. because cannot use .pipe
.
what need:
'use strict'; var buffer = require('buffer'), stream = require('stream'), util = require('util'), excel = require('exceljs'); var rs = new stream.readable({objectmode: true}); rs.push({name: 'one'}); rs.push({name: 'two'}); rs.push({name: 'three'}); rs.push(null); var exceltransform = function(options) { stream.transform.call(this, options); this._writablestate.objectmode = true; this._readablestate.objectmode = false; this.workbook = new excel.stream.xlsx.workbookwriter({stream: this}); this.worksheet = this.workbook.addworksheet('sheet 1'); this.worksheet.columns = [{header: 'name', key: 'name'}]; }; util.inherits(exceltransform, stream.transform); exceltransform.prototype._transform = function(chunk, encoding, callback) { if (buffer.buffer.isbuffer(chunk)) { this.push(chunk); } else { this.worksheet.addrow({ name: chunk.name }).commit(); } callback(); }; exceltransform.prototype._flush = function(callback) { this.worksheet.commit(); this.workbook.commit(); callback(); }; rs.pipe(new exceltransform()).pipe(process.stdout);
but not working , giving me empty output.
the output empty because you're pushing nothing out of transform stream. you're in object mode never goes in if:
if (buffer.buffer.isbuffer(chunk)) { this.push(chunk); }
here working pipeable version (the data streamed @ once @ end):
var stream = require('stream'); var util = require('util'); var excel = require('exceljs'); var bl = require('bl'); var exceltransform = function(options) { stream.transform.call(this, { objectmode: true }); this.workbook = options.workbook; // can make optional checking , // creating empty worksheet if none provided this.worksheet = options.worksheet; } util.inherits(exceltransform, stream.transform); exceltransform.prototype._transform = function(doc, encoding, callback) { this.worksheet.addrow({ name: doc.name }); callback(); }; exceltransform.prototype._flush = function(callback) { this.workbook.commit(); // commit when you're done var = this; // bl drains stream , create buffer object can push this.workbook.stream.pipe(bl(function(err, data) { that.push(data); callback(); })); }; // it's better provide workbook parameter exceltransform var workbook = new excel.stream.xlsx.workbookwriter(); var worksheet = workbook.addworksheet('sheet 1'); worksheet.columns = [{ header: 'name', key: 'name' }]; var rs = new stream.readable({ objectmode: true }); rs.push({ name: 'one' }); rs.push({ name: 'two' }); rs.push({ name: 'three' }); rs.push(null); rs.pipe(new exceltransform({ workbook: workbook, worksheet: worksheet })).pipe(process.stdout);
another solution, streaming time:
var stream = require('stream'); var util = require('util'); var excel = require('exceljs'); var exceltransform = function(options) { stream.transform.call(this, { writableobjectmode: true, readableobjectmode: false }); this.workbook = options.workbook; var = this; this.workbook.stream.on('readable', function() { var chunk = workbook.stream.read(); that.push(chunk); }); this.worksheet = options.worksheet; } util.inherits(exceltransform, stream.transform); exceltransform.prototype._transform = function(doc, encoding, callback) { this.worksheet.addrow({ name: doc.name }).commit(); callback(); }; exceltransform.prototype._flush = function(callback) { this.workbook.commit(); // final commit }; // it's better provide workbook parameter exceltransform var workbook = new excel.stream.xlsx.workbookwriter(); var worksheet = workbook.addworksheet('sheet 1'); worksheet.columns = [{ header: 'name', key: 'name' }]; var rs = new stream.readable({ objectmode: true }); rs.push({ name: 'one' }); rs.push({ name: 'two' }); rs.push({ name: 'three' }); rs.push(null); rs.pipe(new exceltransform({ workbook: workbook, worksheet: worksheet })).pipe(process.stdout);
Comments
Post a Comment