to-spreadsheet
Version:
npm package to create spreadsheet in node environment and in browser
155 lines (154 loc) • 6.83 kB
JavaScript
;
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);
}
});
};