Skip to content

Commit

Permalink
fix: flushing rows in the end; correctly wait for drain event when wr…
Browse files Browse the repository at this point in the history
…iting to transform stream. (#16)
  • Loading branch information
jirimoravcik authored Jul 22, 2021
1 parent 1644db2 commit b660f6f
Show file tree
Hide file tree
Showing 5 changed files with 28 additions and 18 deletions.
10 changes: 8 additions & 2 deletions src/XLSXRowTransform.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import { Transform } from 'stream';
import { Row } from './templates';
import { Row, SheetHeader, SheetFooter } from './templates';

/** Class representing a XLSX Row transformation from array to Row. */
/** Class representing a XLSX Row transformation from array to Row. Also adds the necessary XLSX header and footer. */
export default class XLSXRowTransform extends Transform {
constructor(shouldFormat) {
super({ objectMode: true });
this.rowCount = 0;
this.shouldFormat = shouldFormat;
this.push(SheetHeader);
}
/**
* Transform array to row string
Expand All @@ -18,4 +19,9 @@ export default class XLSXRowTransform extends Transform {
this.rowCount++;
callback(null, xlsxRow);
}

_flush(callback) {
this.push(SheetFooter);
callback();
}
}
21 changes: 10 additions & 11 deletions src/XLSXTransformStream.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import Archiver from 'archiver';
import { PassThrough, Transform } from 'stream';
import { Transform } from 'stream';
import XLSXRowTransform from './XLSXRowTransform';
import * as templates from './templates';

Expand All @@ -16,10 +16,7 @@ export default class XLSXTransformStream extends Transform {
this.initializeArchiver();
this.rowTransform = new XLSXRowTransform(this.options.shouldFormat);

this.sheetStream = new PassThrough();
this.sheetStream.write(templates.SheetHeader);
this.rowTransform.pipe(this.sheetStream);
this.zip.append(this.sheetStream, {
this.zip.append(this.rowTransform, {
name: 'xl/worksheets/sheet1.xml',
});
}
Expand Down Expand Up @@ -65,13 +62,15 @@ export default class XLSXTransformStream extends Transform {
}

_transform(row, encoding, callback) {
this.rowTransform.write(row);
callback();
if (this.rowTransform.write(row)) {
process.nextTick(callback);
} else {
this.rowTransform.once('drain', callback);
}
}

async _flush(callback) {
this.sheetStream.end(templates.SheetFooter);
await this.zip.finalize();
callback();
_flush(callback) {
this.rowTransform.end();
this.zip.finalize().then(callback);
}
}
7 changes: 4 additions & 3 deletions test/XLSXRowTransform.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,15 @@
import { expect } from 'chai';
import { Readable, PassThrough } from 'stream';
import XLSXRowTransform from '../src/XLSXRowTransform';
import { SheetHeader, SheetFooter } from '../src/templates';

describe('The XLSXRowTransform', () => {
it('Correctly transforms an array of data into a XLSX row format', async () => {
const expectedResult = `
it('Correctly transforms an array of data into a XLSX row format with header and footer', async () => {
const expectedResult = `${SheetHeader}
<row r="1" spans="1:2" x14ac:dyDescent="0.2">
<c r="A1" t="inlineStr"><is><t>test</t></is></c>
<c r="B1" t="n"><v>123</v></c>
</row>`;
</row>${SheetFooter}`;
const inputStream = Readable.from([['test', 123]]);
const transform = new XLSXRowTransform();
const outputStream = new PassThrough();
Expand Down
8 changes: 6 additions & 2 deletions test/XLSXTransformStream.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,10 @@ import path from 'path';
import unzipper from 'unzipper';
import XLSXTransformStream from '../src/XLSXTransformStream';

const TEST_ROWS_COUNT = 500;

describe('The XLSXTransformStream', () => {
it('The transformed xlsx file corresponds to the snapshot xlsx file', async () => {
it(`The transformed xlsx file corresponds to the snapshot xlsx file (${TEST_ROWS_COUNT} rows)`, async () => {
const snapshotFiles = {};
await fs.createReadStream(path.resolve(__dirname, 'test.xlsx'))
.pipe(unzipper.Parse())
Expand All @@ -18,7 +20,9 @@ describe('The XLSXTransformStream', () => {
const inputStream = new Readable({ objectMode: true });
const testFiles = {};

inputStream.push(['Testing', 1]);
for (let i = 0; i < TEST_ROWS_COUNT; i++) {
inputStream.push(['Testing', i + 1]);
}
inputStream.push(null);

await inputStream
Expand Down
Binary file modified test/test.xlsx
Binary file not shown.

0 comments on commit b660f6f

Please sign in to comment.