|
@@ -1,33 +1,109 @@
|
|
import JSZip from "jszip";
|
|
import JSZip from "jszip";
|
|
|
|
|
|
import {
|
|
import {
|
|
|
|
+ PassThrough,
|
|
|
|
+ Duplex,
|
|
|
|
+} from 'readable-stream';
|
|
|
|
+
|
|
|
|
+import {
|
|
|
|
+ BrowserUtils,
|
|
WorkBook,
|
|
WorkBook,
|
|
} from "../internal";
|
|
} from "../internal";
|
|
|
|
|
|
-/**
|
|
|
|
- * export xlsx
|
|
|
|
- */
|
|
|
|
export class XLSX {
|
|
export class XLSX {
|
|
protected _workbook: WorkBook;
|
|
protected _workbook: WorkBook;
|
|
|
|
|
|
- /**
|
|
|
|
- * create xlsx
|
|
|
|
- * @param workbook
|
|
|
|
- */
|
|
|
|
public constructor(workbook: WorkBook) {
|
|
public constructor(workbook: WorkBook) {
|
|
this._workbook = workbook;
|
|
this._workbook = workbook;
|
|
}
|
|
}
|
|
|
|
|
|
- /**
|
|
|
|
- * load file buffer
|
|
|
|
- * @param buffer
|
|
|
|
- */
|
|
|
|
|
|
+ public async read(stream: Duplex): Promise<WorkBook> {
|
|
|
|
+ if (!stream[Symbol.asyncIterator] && stream.pipe) {
|
|
|
|
+ stream = stream.pipe(new PassThrough());
|
|
|
|
+ }
|
|
|
|
+ const chunks = [];
|
|
|
|
+ for await (const chunk of stream) {
|
|
|
|
+ chunks.push(chunk);
|
|
|
|
+ }
|
|
|
|
+ return this.load(Buffer.concat(chunks));
|
|
|
|
+ }
|
|
|
|
+
|
|
public async load(buffer: Buffer): Promise<WorkBook> {
|
|
public async load(buffer: Buffer): Promise<WorkBook> {
|
|
- const zip = await JSZip.loadAsync(buffer);
|
|
|
|
- const files = Object.values(zip.files);
|
|
|
|
|
|
+ const jszip = await JSZip.loadAsync(buffer);
|
|
|
|
+ const files = Object.values(jszip.files);
|
|
|
|
+
|
|
for (const file of files) {
|
|
for (const file of files) {
|
|
|
|
+ if (!file.dir) {
|
|
|
|
+ let fileName = file.name;
|
|
|
|
+ if (fileName[0] === '/') {
|
|
|
|
+ fileName = fileName.substring(1);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ let stream: PassThrough;
|
|
|
|
+ if (fileName.match(/xl\/media\//)
|
|
|
|
+ || fileName.match(/xl\/theme\/([a-zA-Z0-9]+)[.]xml/)) {
|
|
|
|
+ stream = new PassThrough();
|
|
|
|
+ stream.write(await file.async('nodebuffer'));
|
|
|
|
+ } else {
|
|
|
|
+ stream = new PassThrough({
|
|
|
|
+ writableObjectMode: true,
|
|
|
|
+ readableObjectMode: true,
|
|
|
|
+ });
|
|
|
|
+ let content;
|
|
|
|
+ if (process.browser) {
|
|
|
|
+ content = BrowserUtils.bufferToString(await file.async('nodebuffer'));
|
|
|
|
+ } else {
|
|
|
|
+ content = await file.async('string');
|
|
|
|
+ }
|
|
|
|
+ const chunkSize = 16 * 1024;
|
|
|
|
+ for (let i = 0; i < content.length; i += chunkSize) {
|
|
|
|
+ stream.write(content.substring(i, i + chunkSize));
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ stream.end();
|
|
|
|
|
|
|
|
+ switch (fileName) {
|
|
|
|
+ case 'xl/workbook.xml': {
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ case 'xl/styles.xml': {
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ case 'xl/_rels/workbook.xml.rels': {
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ case '_rels/.rels': {
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ case 'xl/sharedStrings.xml': {
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ case 'docProps/app.xml': {
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ case 'docProps/core.xml': {
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ default: {}
|
|
|
|
+ }
|
|
|
|
+ }
|
|
}
|
|
}
|
|
return null;
|
|
return null;
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ public async readFile(filename: string): Promise<WorkBook> {
|
|
|
|
+ return null;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ public async write(stream: Duplex): Promise<XLSX> {
|
|
|
|
+ return null;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ public async writeBuffer(): Promise<XLSX> {
|
|
|
|
+ return null;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ public async writeFile(filename: string): Promise<XLSX> {
|
|
|
|
+ return null;
|
|
|
|
+ }
|
|
}
|
|
}
|