@microsoft/connected-workbooks
Version:
Microsoft backed, Excel advanced xlsx workbook generation JavaScript library
290 lines (289 loc) • 17.6 kB
JavaScript
;
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __generator = (this && this.__generator) || function (thisArg, body) {
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
function verb(n) { return function (v) { return step([n, v]); }; }
function step(op) {
if (f) throw new TypeError("Generator is already executing.");
while (g && (g = 0, op[0] && (_ = 0)), _) try {
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
if (y = 0, t) op = [op[0] & 2, t.value];
switch (op[0]) {
case 0: case 1: t = op; break;
case 4: _.label++; return { value: op[1], done: false };
case 5: _.label++; y = op[1]; op = [0]; continue;
case 7: op = _.ops.pop(); _.trys.pop(); continue;
default:
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
if (t[2]) _.ops.pop();
_.trys.pop(); continue;
}
op = body.call(thisArg, _);
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
}
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
var types_1 = require("../types");
var constants_1 = require("./constants");
var documentUtils_1 = __importDefault(require("./documentUtils"));
var xmldom_qsa_1 = require("xmldom-qsa");
var updateDocProps = function (zip, docProps) {
if (docProps === void 0) { docProps = {}; }
return __awaiter(void 0, void 0, void 0, function () {
var _a, doc, properties, docPropsAutoUpdatedElementsArr, nowTime, docPropsModifiableElementsArr, serializer, newDoc;
return __generator(this, function (_b) {
switch (_b.label) {
case 0: return [4 /*yield*/, documentUtils_1.default.getDocPropsProperties(zip)];
case 1:
_a = _b.sent(), doc = _a.doc, properties = _a.properties;
docPropsAutoUpdatedElementsArr = Object.keys(types_1.DocPropsAutoUpdatedElements);
nowTime = new Date().toISOString();
docPropsAutoUpdatedElementsArr.forEach(function (tag) {
documentUtils_1.default.createOrUpdateProperty(doc, properties, types_1.DocPropsAutoUpdatedElements[tag], nowTime);
});
docPropsModifiableElementsArr = Object.keys(types_1.DocPropsModifiableElements);
docPropsModifiableElementsArr
.map(function (key) { return ({
name: types_1.DocPropsModifiableElements[key],
value: docProps[key],
}); })
.forEach(function (kvp) {
documentUtils_1.default.createOrUpdateProperty(doc, properties, kvp.name, kvp.value);
});
serializer = new xmldom_qsa_1.XMLSerializer();
newDoc = serializer.serializeToString(doc);
zip.file(constants_1.docPropsCoreXmlPath, newDoc);
return [2 /*return*/];
}
});
});
};
var clearLabelInfo = function (zip) { return __awaiter(void 0, void 0, void 0, function () {
var relsString, parser, doc, relationships, element, serializer, newDoc;
var _a, _b, _c, _d;
return __generator(this, function (_e) {
switch (_e.label) {
case 0:
// remove docMetadata folder that contains only LabelInfo.xml in template file.
zip.remove(constants_1.docMetadataXmlPath);
return [4 /*yield*/, ((_a = zip.file(constants_1.relsXmlPath)) === null || _a === void 0 ? void 0 : _a.async(constants_1.textResultType))];
case 1:
relsString = _e.sent();
if (relsString === undefined) {
throw new Error(constants_1.relsNotFoundErr);
}
parser = new xmldom_qsa_1.DOMParser();
doc = parser.parseFromString(relsString, constants_1.xmlTextResultType);
relationships = doc.querySelector("Relationships");
if (relationships === null) {
throw new Error(constants_1.unexpectedErr);
}
element = relationships.querySelector('Relationship[Target="docMetadata/LabelInfo.xml"]');
if (element) {
relationships.removeChild(element);
}
(_b = relationships.querySelector('Relationship[Target="xl/workbook.xml"]')) === null || _b === void 0 ? void 0 : _b.setAttribute("Id", "rId1");
(_c = relationships.querySelector('Relationship[Target="docProps/core.xml"]')) === null || _c === void 0 ? void 0 : _c.setAttribute("Id", "rId2");
(_d = relationships.querySelector('Relationship[Target="docProps/app.xml"]')) === null || _d === void 0 ? void 0 : _d.setAttribute("Id", "rId3");
serializer = new xmldom_qsa_1.XMLSerializer();
newDoc = serializer.serializeToString(doc);
zip.file(constants_1.relsXmlPath, newDoc);
return [2 /*return*/];
}
});
}); };
var updateConnections = function (connectionsXmlString, queryName, refreshOnOpen) {
var _a, _b, _c;
var parser = new xmldom_qsa_1.DOMParser();
var serializer = new xmldom_qsa_1.XMLSerializer();
var refreshOnLoadValue = refreshOnOpen ? constants_1.trueValue : constants_1.falseValue;
var connectionsDoc = parser.parseFromString(connectionsXmlString, constants_1.xmlTextResultType);
var connectionsProperties = connectionsDoc.getElementsByTagName(constants_1.element.databaseProperties);
var dbPr = connectionsProperties[0];
dbPr.setAttribute(constants_1.elementAttributes.refreshOnLoad, refreshOnLoadValue);
// Update query details to match queryName
(_a = dbPr.parentNode) === null || _a === void 0 ? void 0 : _a.setAttribute(constants_1.elementAttributes.name, constants_1.elementAttributesValues.connectionName(queryName));
(_b = dbPr.parentNode) === null || _b === void 0 ? void 0 : _b.setAttribute(constants_1.elementAttributes.description, constants_1.elementAttributesValues.connectionDescription(queryName));
dbPr.setAttribute(constants_1.elementAttributes.connection, constants_1.elementAttributesValues.connection(queryName));
dbPr.setAttribute(constants_1.elementAttributes.command, constants_1.elementAttributesValues.connectionCommand(queryName));
var connectionId = (_c = dbPr.parentNode) === null || _c === void 0 ? void 0 : _c.getAttribute(constants_1.elementAttributes.id);
var connectionXmlFileString = serializer.serializeToString(connectionsDoc);
if (connectionId === null) {
throw new Error(constants_1.connectionsNotFoundErr);
}
return { connectionId: connectionId, connectionXmlFileString: connectionXmlFileString };
};
var updateSharedStrings = function (sharedStringsXmlString, queryName) {
var parser = new xmldom_qsa_1.DOMParser();
var serializer = new xmldom_qsa_1.XMLSerializer();
var sharedStringsDoc = parser.parseFromString(sharedStringsXmlString, constants_1.xmlTextResultType);
var sharedStringsTable = sharedStringsDoc.getElementsByTagName(constants_1.element.sharedStringTable)[0];
if (!sharedStringsTable) {
throw new Error(constants_1.sharedStringsNotFoundErr);
}
var textElementCollection = sharedStringsDoc.getElementsByTagName(constants_1.element.text);
var textElement = null;
var sharedStringIndex = textElementCollection.length;
if (textElementCollection && textElementCollection.length) {
for (var i = 0; i < textElementCollection.length; i++) {
if (textElementCollection[i].textContent === queryName) {
textElement = textElementCollection[i];
sharedStringIndex = i + 1;
break;
}
}
}
if (textElement === null) {
if (sharedStringsDoc.documentElement.namespaceURI) {
textElement = sharedStringsDoc.createElementNS(sharedStringsDoc.documentElement.namespaceURI, constants_1.element.text);
textElement.textContent = queryName;
var siElement = sharedStringsDoc.createElementNS(sharedStringsDoc.documentElement.namespaceURI, constants_1.element.sharedStringItem);
siElement.appendChild(textElement);
sharedStringsDoc.getElementsByTagName(constants_1.element.sharedStringTable)[0].appendChild(siElement);
}
var value = sharedStringsTable.getAttribute(constants_1.elementAttributes.count);
if (value) {
sharedStringsTable.setAttribute(constants_1.elementAttributes.count, (parseInt(value) + 1).toString());
}
var uniqueValue = sharedStringsTable.getAttribute(constants_1.elementAttributes.uniqueCount);
if (uniqueValue) {
sharedStringsTable.setAttribute(constants_1.elementAttributes.uniqueCount, (parseInt(uniqueValue) + 1).toString());
}
}
var newSharedStrings = serializer.serializeToString(sharedStringsDoc);
return { sharedStringIndex: sharedStringIndex, newSharedStrings: newSharedStrings };
};
var updateWorksheet = function (sheetsXmlString, sharedStringIndex) {
var parser = new xmldom_qsa_1.DOMParser();
var serializer = new xmldom_qsa_1.XMLSerializer();
var sheetsDoc = parser.parseFromString(sheetsXmlString, constants_1.xmlTextResultType);
sheetsDoc.getElementsByTagName(constants_1.element.cellValue)[0].innerHTML = sharedStringIndex.toString();
var newSheet = serializer.serializeToString(sheetsDoc);
return newSheet;
};
var updatePivotTablesandQueryTables = function (zip, queryName, refreshOnOpen, connectionId) { return __awaiter(void 0, void 0, void 0, function () {
var found, queryTablePromises, pivotCachePromises;
var _a, _b;
return __generator(this, function (_c) {
switch (_c.label) {
case 0:
found = false;
queryTablePromises = [];
(_a = zip.folder(constants_1.queryTablesPath)) === null || _a === void 0 ? void 0 : _a.forEach(function (relativePath, queryTableFile) { return __awaiter(void 0, void 0, void 0, function () {
return __generator(this, function (_a) {
queryTablePromises.push((function () {
return queryTableFile.async(constants_1.textResultType).then(function (queryTableString) {
return {
path: relativePath,
queryTableXmlString: queryTableString,
};
});
})());
return [2 /*return*/];
});
}); });
return [4 /*yield*/, Promise.all(queryTablePromises)];
case 1:
(_c.sent()).forEach(function (_a) {
var path = _a.path, queryTableXmlString = _a.queryTableXmlString;
var _b = updateQueryTable(queryTableXmlString, connectionId, refreshOnOpen), isQueryTableUpdated = _b.isQueryTableUpdated, newQueryTable = _b.newQueryTable;
zip.file(constants_1.queryTablesPath + path, newQueryTable);
if (isQueryTableUpdated) {
found = true;
}
});
if (found) {
return [2 /*return*/];
}
pivotCachePromises = [];
(_b = zip.folder(constants_1.pivotCachesPath)) === null || _b === void 0 ? void 0 : _b.forEach(function (relativePath, pivotCacheFile) { return __awaiter(void 0, void 0, void 0, function () {
return __generator(this, function (_a) {
if (relativePath.startsWith(constants_1.pivotCachesPathPrefix)) {
pivotCachePromises.push((function () {
return pivotCacheFile.async(constants_1.textResultType).then(function (pivotCacheString) {
return {
path: relativePath,
pivotCacheXmlString: pivotCacheString,
};
});
})());
}
return [2 /*return*/];
});
}); });
return [4 /*yield*/, Promise.all(pivotCachePromises)];
case 2:
(_c.sent()).forEach(function (_a) {
var path = _a.path, pivotCacheXmlString = _a.pivotCacheXmlString;
var _b = updatePivotTable(pivotCacheXmlString, connectionId, refreshOnOpen), isPivotTableUpdated = _b.isPivotTableUpdated, newPivotTable = _b.newPivotTable;
zip.file(constants_1.pivotCachesPath + path, newPivotTable);
if (isPivotTableUpdated) {
found = true;
}
});
if (!found) {
throw new Error(constants_1.queryAndPivotTableNotFoundErr);
}
return [2 /*return*/];
}
});
}); };
var updateQueryTable = function (tableXmlString, connectionId, refreshOnOpen) {
var refreshOnLoadValue = refreshOnOpen ? constants_1.trueValue : constants_1.falseValue;
var isQueryTableUpdated = false;
var parser = new xmldom_qsa_1.DOMParser();
var serializer = new xmldom_qsa_1.XMLSerializer();
var queryTableDoc = parser.parseFromString(tableXmlString, constants_1.xmlTextResultType);
var queryTable = queryTableDoc.getElementsByTagName(constants_1.element.queryTable)[0];
var newQueryTable = constants_1.emptyValue;
if (queryTable.getAttribute(constants_1.elementAttributes.connectionId) == connectionId) {
queryTable.setAttribute(constants_1.elementAttributes.refreshOnLoad, refreshOnLoadValue);
newQueryTable = serializer.serializeToString(queryTableDoc);
isQueryTableUpdated = true;
}
return { isQueryTableUpdated: isQueryTableUpdated, newQueryTable: newQueryTable };
};
var updatePivotTable = function (tableXmlString, connectionId, refreshOnOpen) {
var refreshOnLoadValue = refreshOnOpen ? constants_1.trueValue : constants_1.falseValue;
var isPivotTableUpdated = false;
var parser = new xmldom_qsa_1.DOMParser();
var serializer = new xmldom_qsa_1.XMLSerializer();
var pivotCacheDoc = parser.parseFromString(tableXmlString, constants_1.xmlTextResultType);
var cacheSource = pivotCacheDoc.getElementsByTagName(constants_1.element.cacheSource)[0];
var newPivotTable = constants_1.emptyValue;
if (cacheSource.getAttribute(constants_1.elementAttributes.connectionId) == connectionId) {
cacheSource = cacheSource.parentElement;
cacheSource.setAttribute(constants_1.elementAttributes.refreshOnLoad, refreshOnLoadValue);
newPivotTable = serializer.serializeToString(pivotCacheDoc);
isPivotTableUpdated = true;
}
return { isPivotTableUpdated: isPivotTableUpdated, newPivotTable: newPivotTable };
};
exports.default = {
updateDocProps: updateDocProps,
clearLabelInfo: clearLabelInfo,
updateConnections: updateConnections,
updateSharedStrings: updateSharedStrings,
updateWorksheet: updateWorksheet,
updatePivotTablesandQueryTables: updatePivotTablesandQueryTables,
updateQueryTable: updateQueryTable,
updatePivotTable: updatePivotTable,
};