UNPKG

to-spreadsheet

Version:

npm package to create spreadsheet in node environment and in browser

155 lines (154 loc) 6.83 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.EnvironmentType = exports.generateExcel = void 0; const content_types_xml_1 = require("./content-types.xml"); const _rels_1 = require("./_rels/.rels"); const app_xml_1 = require("./docProps/app.xml"); const core_xml_1 = require("./docProps/core.xml"); const workbook_xml_rels_1 = require("./xl/_rels/workbook.xml.rels"); const sharedStrings_xml_1 = require("./xl/sharedStrings.xml"); const styles_xml_1 = require("./xl/styles.xml"); const theme1_xml_1 = require("./xl/theme/theme1.xml"); const workbook_xml_1 = require("./xl/workbook.xml"); const sheet_xml_1 = require("./xl/worksheets/sheet.xml"); const index_1 = require("./index"); const util_1 = require("./util"); const generateTree = (workbook) => { const styleMap = new Map(); styleMap.set("default", {}); let hasDateCells = false; workbook.sheets.forEach(sheet => { sheet.rows.forEach(row => { row.cells.forEach(cell => { if (cell.type === index_1.ICellType.date) { hasDateCells = true; } if ('style' in cell && cell.style) { const styleKey = (0, util_1.getStyleKey)(cell.style); styleMap.set(styleKey, cell.style); } }); }); }); return Object.assign({ "[Content_Types].xml": (0, content_types_xml_1.generateContentTypesXml)(workbook), "_rels/.rels": (0, _rels_1.generateRels)(), "docProps/app.xml": (0, app_xml_1.generateAppXml)(workbook), "docProps/core.xml": (0, core_xml_1.generateCoreXml)({}), "xl/_rels/workbook.xml.rels": (0, workbook_xml_rels_1.generateWorkBookXmlRels)(workbook), "xl/sharedStrings.xml": (0, sharedStrings_xml_1.generateSharedStrings)(workbook), "xl/styles.xml": (0, styles_xml_1.generateStyleXml)(styleMap, hasDateCells), "xl/theme/theme1.xml": (0, theme1_xml_1.generateTheme1)(), "xl/workbook.xml": (0, workbook_xml_1.generateWorkBookXml)(workbook) }, workbook.sheets.reduce((acc, sheet, idx) => (Object.assign(Object.assign({}, acc), { [`xl/worksheets/sheet${idx + 1}.xml`]: (0, sheet_xml_1.generateSheetXml)(sheet, styleMap, hasDateCells) })), {})); }; var EnvironmentType; (function (EnvironmentType) { EnvironmentType[EnvironmentType["NODE"] = 0] = "NODE"; EnvironmentType[EnvironmentType["BROWSER"] = 1] = "BROWSER"; })(EnvironmentType || (EnvironmentType = {})); exports.EnvironmentType = EnvironmentType; const generateExcel = (dump, environmentType = EnvironmentType.NODE) => { const strings = []; const sheets = dump.map(({ title, content }) => { const rows = content.map(row => { const cells = []; row.forEach(content => { if (typeof content === 'number') { cells.push({ type: index_1.ICellType.number, value: content }); } else if (typeof content === 'string') { const type = index_1.ICellType.string; let value = strings.indexOf(content); if (value === -1) { strings.push(content); value = strings.length - 1; } cells.push({ type: index_1.ICellType.string, value }); } else if (content instanceof util_1.SkipCell) { for (let i = 0; i < content.getSkipCell(); i++) { cells.push({ type: index_1.ICellType.skip, value: undefined }); } } else if (content instanceof util_1.Equation) { cells.push({ type: index_1.ICellType.equation, value: content }); } else if (content && typeof content === 'object' && 'type' in content) { const cell = content; if (cell.type === index_1.ICellType.string && typeof cell.value === 'string') { let stringIndex = strings.indexOf(cell.value); if (stringIndex === -1) { strings.push(cell.value); stringIndex = strings.length - 1; } cells.push(Object.assign(Object.assign({}, cell), { value: stringIndex })); } else { cells.push(cell); } } else { cells.push({ type: index_1.ICellType.skip }); } }); return { cells }; }); return { title, rows }; }); const workbook = { sheets, strings, filename: "tem.xlsx" }; if (environmentType === EnvironmentType.BROWSER) { return generateExcelWorkbookBrowser(workbook); } else { return generateExcelWorkbookNode(workbook); } }; exports.generateExcel = generateExcel; const generateExcelWorkbookNode = (workbook) => { return new Promise((resolve, reject) => { const fs = require('fs'); const archiver = require('archiver'); const output = fs.createWriteStream(`${__dirname}/${workbook.filename}.xlsx`); const archive = archiver("zip", { zlib: { level: 9 }, }); output.on("close", () => { console.debug(archive.pointer() + " total bytes"); console.debug("archiver has been finalized and the output file descriptor has closed."); resolve(); }); output.on("end", () => { console.debug("Data has been drained"); }); archive.on("warning", (err) => { if (err.code === "ENOENT") { } else { reject(err); } }); archive.on("error", (err) => { reject(err); }); archive.pipe(output); Object.entries(generateTree(workbook)).map(([filename, fileContent]) => { archive.append(fileContent, { name: filename }); }); archive.finalize(); }); }; const generateExcelWorkbookBrowser = (workbook) => { return new Promise((resolve, reject) => { try { const JSZip = require('jszip'); const { saveAs } = require('file-saver'); const zip = new JSZip(); const tree = generateTree(workbook); Object.entries(tree).forEach(([filename, fileContent]) => { zip.file(filename, fileContent); }); zip.generateAsync({ type: "blob" }).then((blob) => { saveAs(blob, `${workbook.filename}.xlsx`); resolve(); }); } catch (error) { reject(error); } }); };