我使用ExcelJS模块并为我的目的编写包装器,它实现了Transform Stream API(是的,节点版本是0.10.40)。
ExcelJS有一个流API,根据ExcelJS模块中的示例,我们可以使用这样的一个(执行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();
});
它工作正常,但看起来不是很干净。因为我们无法使用.pipe
。
我需要什么:
'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);
但这不起作用,给我空的输出。
答案 0 :(得分:4)
输出为空,因为您没有从变换流中推送任何内容。您处于对象模式,因此如果出现以下情况,它将永远不会出现:
if (buffer.Buffer.isBuffer(chunk)) {
this.push(chunk);
}
这是一个可工作的可管理版本(数据最后一次流式传输):
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;
// you can make this optional by checking for it and
// creating an 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 only when you're done
var that = this;
// bl drains the stream and create a Buffer object you can then push
this.workbook.stream.pipe(bl(function(err, data) {
that.push(data);
callback();
}));
};
// it's better to provide the workbook as a parameter to 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);
另一种解决方案,一直流式传输:
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 that = 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 to provide the workbook as a parameter to the 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);
答案 1 :(得分:0)
下面的代码片段对我有用
import { Workbook } from 'exceljs';
import { createReadStream } from 'fs';
function readExcelFile(){
const stream = createReadStream("./test.xlsx");
const workbook = new Workbook();
const streamWorkBook = await workbook.xlsx.read(stream);
const sheet = streamWorkBook.getWorksheet("Sheet1");
//Get all the rows data [1st and 2nd column]
for (let i = 1; i <= sheet.rowCount; i++) {
console.log(sheet.getRow(i).getCell(1).value);
console.log(sheet.getRow(i).getCell(2).value);
}
}