/* version: v1.0 */
var Html2Ods = function (output, table, options) {
function Currency (code, symbol, fractionDigit, symbolBefore, formatFunction) {
this.code = code;
this.symbol = symbol;
this.fractionDigit = fractionDigit;
this.symbolBefore = symbolBefore;
var multiplicator = 1;
for(var i = 0; i < fractionDigit; i++) {
multiplicator = multiplicator * 10;
}
this.subunitMultiplicator = multiplicator;
if (formatFunction) {
this.formatFunction = formatFunction;
}
};
Currency.prototype.formatAmount = function (moneyLong, locale) {
var decimalValue = moneyLong / (this.subunitMultiplicator);
if (this.formatFunction) {
return this.formatFunction(decimalValue, locale);
} else {
return decimalValue.toLocaleString(locale, {
style: "currency",
currency: this.code
});
}
};
Currency.prototype.toDecimalValue = function (moneyLong) {
return moneyLong / (this.subunitMultiplicator);
};
Currency.MAP = {};
Currency.formatAmount = function (moneyLong, currencyCode, locale) {
var currency = Currency.get(currencyCode);
return currency.formatAmount(moneyLong, locale);
};
Currency.toDecimalValue = function (moneyLong, currencyCode) {
var currency = Currency.get(currencyCode);
return currency.toDecimalValue(moneyLong);
};
Currency.get = function (code) {
if (Currency.MAP.hasOwnProperty(code)) {
return Currency.MAP[code];
}
var currency;
var symbolBefore = _isSymbolBefore(code);
if (code === 'CFA') {
currency = new Currency("CFA", "CFA", 0, symbolBefore, function(decimalValue, locale) {
return decimalValue.toLocaleString(locale, {
style: "decimal",
maximumFractionDigits: 0
}) + " CFA";
});
} else {
var numberFormat = new Intl.NumberFormat('en', { style: 'currency', currency: code });
var options = numberFormat.resolvedOptions();
var fractionDigit = options.maximumFractionDigits;
var format = numberFormat.format(987);
var idx = format.indexOf(9);
var symbol = format.substring(0, idx);
currency = new Currency(code, symbol, fractionDigit, symbolBefore);
}
Currency.MAP[code] = currency;
return currency;
function _isSymbolBefore (code) {
switch(code) {
case "USD":
case "GBP":
return true;
default:
return false;
}
}
};
XmlWriter = function (options) {
this.xml = "";
this.indentLength = -999999;
if (options) {
if (options.indentLength) {
this.indentLength = options.indentLength;
} else if (options.prettyXml) {
this.indentLength = 0;
}
}
};
XmlWriter.prototype.appendXMLDeclaration = function () {
this.write('');
if (this.indentLength < 0) {
this.write('\n');
}
return this;
};
XmlWriter.prototype.startOpenTag = function (tagName, indentBefore) {
if (indentBefore === undefined) {
indentBefore = true;
}
if (indentBefore) {
this.appendIndent();
}
this.write('<');
this.write(tagName);
return this;
};
XmlWriter.prototype.endOpenTag = function () {
this.write('>');
this.increaseIndentValue();
return this;
};
XmlWriter.prototype.closeEmptyTag = function () {
this.write('/');
this.write('>');
return this;
};
XmlWriter.prototype.openTag = function (tagName, indentBefore) {
if (indentBefore === undefined) {
indentBefore = true;
}
if (indentBefore) {
this.appendIndent();
}
this.write('<');
this.write(tagName);
this.write('>');
this.increaseIndentValue();
return this;
};
XmlWriter.prototype.closeTag = function (tagName, indentBefore) {
if (indentBefore === undefined) {
indentBefore = true;
}
this.decreaseIndentValue();
if (indentBefore) {
this.appendIndent();
}
this.write('<');
this.write('/');
this.write(tagName);
this.write('>');
return this;
};
XmlWriter.prototype.addText = function (text) {
if (text) {
this.escape(text);
}
return this;
};
XmlWriter.prototype.addCData = function (text) {
this.write("");
this.write("]]");
this.write("");
return this;
};
XmlWriter.prototype.addAttribute = function (attributeName, value) {
if ((value === 0) || (value)) {
this.write(' ');
this.write(attributeName);
this.write('=');
this.write('\"');
this.escape(value.toString());
this.write('\"');
}
return this;
};
XmlWriter.prototype.addSimpleElement = function (tagName, value) {
if (value) {
this.startOpenTag(tagName);
this.endOpenTag();
this.addText(value);
this.closeTag(tagName, false);
}
return this;
};
XmlWriter.prototype.addEmptyElement = function (tagName) {
this.startOpenTag(tagName);
this.closeEmptyTag();
return this;
};
XmlWriter.prototype.write = function (text) {
this.xml += text;
return this;
};
XmlWriter.prototype.escape = function (text) {
var carac;
for(let i = 0, len = text.length; i < len; i++) {
carac = text.charAt(i);
switch (carac) {
case '&':
this.write("&");
break;
case '"':
this.write(""");
break;
case '<':
this.write("<");
break;
case '>':
this.write(">");
break;
case '\'':
this.write("'");
break;
case '\u00A0':
this.write(" ");
break;
default:
this.write(carac);
}
}
return this;
};
XmlWriter.prototype.appendIndent = function () {
if (this.indentLength > -1) {
this.write('\n');
for(let i = 0, len = this.indentLength; i < len; i++) {
this.write('\t');
}
}
return this;
};
XmlWriter.prototype.increaseIndentValue = function () {
this.indentLength = this.indentLength + 1;
return this;
};
XmlWriter.prototype.decreaseIndentValue = function () {
this.indentLength = this.indentLength - 1;
return this;
};
var OpenDocument = {};
OpenDocument.DEFAULT_CELLSTYLE_NAME = "Default";
OpenDocument.COLUMNSTYLE_PREFIX = "co";
OpenDocument.CELLSTYLE_PREFIX = "ce";
OpenDocument.DATASTYLE_PREFIX = "N";
OpenDocument.SPREADSHEET_MIMETYPE = "application/vnd.oasis.opendocument.spreadsheet";
OpenDocument.checkSheetName = function (name) {
var result = "";
var carac;
for (let i = 0, len = name.length; i < len; i++) {
carac = name.charAt(i);
switch (carac) {
case '[':
carac = '(';
break;
case ']':
carac = ')';
break;
case '*':
case ':':
case '/':
case '?':
case '\\':
carac = '-';
break;
}
result += carac;
}
return result;
};
OpenDocument.checkHiddenValue = function (element) {
let odHidden = element.dataset["odHidden"];
if (!odHidden) {
return 0;
}
switch(odHidden.toLowerCase()) {
case 'true':
case '1':
case 'yes':
return 1;
case 'false':
case '0':
case '-1':
case 'no':
return -1;
default:
return 0;
}
};
OpenDocument.toChar = function (columnNumber) {
return (columnNumber + 64);
};
OpenDocument.Elements = {};
OpenDocument.Elements.Cell = function (value, styleName, rowSpan, colSpan) {
this.value = value;
this.styleName = styleName;
this.rowSpan = rowSpan;
this.colSpan = colSpan;
};
OpenDocument.Elements.TableColumn = function (styleName, columnsRepeated, defaultCellStyleName) {
this.styleName = styleName;
this.columnsRepeated = columnsRepeated;
if (defaultCellStyleName) {
this.defaultCellStyleName = defaultCellStyleName;
} else {
this.defaultCellStyleName = "Default";
}
};
OpenDocument.CellCounter = function () {
this.row = 0;
this.column = 0;
this.rowMap = new Map();
};
OpenDocument.CellCounter.prototype.reinit = function () {
this.row = 0;
this.column = 0;
this.rowMap.clear();
};
OpenDocument.CellCounter.prototype.newRow = function () {
this.row = this.row + 1;
this.column = 1;
};
OpenDocument.CellCounter.prototype.newCell = function (rowSpan, colSpan) {
let currentRow = this.row;
let currentColumn = this.column;
let jump = 0;
let coveredCellArray = this.rowMap.get(currentRow);
if (coveredCellArray) {
while(true) {
if (coveredCellArray.indexOf(currentColumn) !== -1) {
currentColumn++;
jump++;
} else {
break;
}
}
}
if (rowSpan > 1) {
for(let i = 1; i < rowSpan; i++) {
for(let j = 0; j < colSpan; j++) {
this.putCoveredCell(currentRow + i, currentColumn + j);
}
}
}
if (colSpan > 1) {
currentColumn += (colSpan - 1);
}
this.column = currentColumn + 1;
return jump;
};
OpenDocument.CellCounter.prototype.putCoveredCell = function (row, column) {
if (this.rowMap.has(row)) {
this.rowMap.get(row).push(column);
} else {
let array = new Array();
array.push(column);
this.rowMap.set(row, array);
}
};
OpenDocument.XmlWriter = function (options) {
XmlWriter.call(this, options);
this.cellCounter = new OpenDocument.CellCounter();
};
OpenDocument.XmlWriter.prototype = Object.create(XmlWriter.prototype);
OpenDocument.XmlWriter.prototype.constructor = OpenDocument.XmlWriter;
OpenDocument.XmlWriter.prototype.openDocument = function (mimetype) {
this
.startOpenTag("office:document")
.addXmlnsAttributes()
.addAttribute("office:mimetype", mimetype)
.endOpenTag();
return this;
};
OpenDocument.XmlWriter.prototype.closeDocument = function () {
this
.closeTag("office:document");
return this;
};
OpenDocument.XmlWriter.prototype.openDocumentContent = function () {
this
.startOpenTag("office:document-content")
.addXmlnsAttributes()
.endOpenTag();
return this;
};
OpenDocument.XmlWriter.prototype.addXmlnsAttributes = function () {
this
.addAttribute("xmlns:office", "urn:oasis:names:tc:opendocument:xmlns:office:1.0")
.addAttribute("xmlns:style", "urn:oasis:names:tc:opendocument:xmlns:style:1.0")
.addAttribute("xmlns:text", "urn:oasis:names:tc:opendocument:xmlns:text:1.0")
.addAttribute("xmlns:table", "urn:oasis:names:tc:opendocument:xmlns:table:1.0")
.addAttribute("xmlns:draw", "urn:oasis:names:tc:opendocument:xmlns:drawing:1.0")
.addAttribute("xmlns:fo", "urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0")
.addAttribute("xmlns:config", "urn:oasis:names:tc:opendocument:xmlns:config:1.0")
.addAttribute("xmlns:xlink", "http://www.w3.org/1999/xlink")
.addAttribute("xmlns:dc", "http://purl.org/dc/elements/1.1/")
.addAttribute("xmlns:meta", "urn:oasis:names:tc:opendocument:xmlns:meta:1.0")
.addAttribute("xmlns:number", "urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0")
.addAttribute("xmlns:presentation", "urn:oasis:names:tc:opendocument:xmlns:presentation:1.0")
.addAttribute("xmlns:svg", "urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0")
.addAttribute("xmlns:chart", "urn:oasis:names:tc:opendocument:xmlns:chart:1.0")
.addAttribute("xmlns:dr3d", "urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0")
.addAttribute("xmlns:math", "http://www.w3.org/1998/Math/MathML")
.addAttribute("xmlns:form", "urn:oasis:names:tc:opendocument:xmlns:form:1.0")
.addAttribute("xmlns:script", "urn:oasis:names:tc:opendocument:xmlns:script:1.0")
.addAttribute("xmlns:ooo", "http://openoffice.org/2004/office")
.addAttribute("xmlns:ooow", "http://openoffice.org/2004/writer")
.addAttribute("xmlns:oooc", "http://openoffice.org/2004/calc")
.addAttribute("xmlns:dom", "http://www.w3.org/2001/xml-events")
.addAttribute("xmlns:xforms", "http://www.w3.org/2002/xforms")
.addAttribute("xmlns:xsd", "http://www.w3.org/2001/XMLSchema")
.addAttribute("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance")
.addAttribute("xmlns:rpt", "http://openoffice.org/2005/report")
.addAttribute("xmlns:of", "urn:oasis:names:tc:opendocument:xmlns:of:1.2")
.addAttribute("xmlns:xhtml", "http://www.w3.org/1999/xhtml")
.addAttribute("xmlns:grddl", "http://www.w3.org/2003/g/data-view#")
.addAttribute("xmlns:tableooo", "http://openoffice.org/2009/table")
.addAttribute("xmlns:vdrawooo", "http://openoffice.org/2010/draw")
.addAttribute("xmlns:calcext", "urn:org:documentfoundation:names:experimental:calc:xmlns:calcext:1.0")
.addAttribute("xmlns:loext", "urn:org:documentfoundation:names:experimental:office:xmlns:loext:1.0")
.addAttribute("xmlns:field", "urn:openoffice:names:experimental:ooo-ms-interop:xmlns:field:1.0")
.addAttribute("xmlns:formx", "urn:openoffice:names:experimental:ooxml-odf-interop:xmlns:form:1.0")
.addAttribute("xmlns:css3t", "http://www.w3.org/TR/css3-text/")
.addAttribute("office:version", "1.2");
return this;
};
OpenDocument.XmlWriter.prototype.openDocumentContentVersion1 = function () {
this
.startOpenTag("office:document-content")
.addAttribute("xmlns:office", "urn:oasis:names:tc:opendocument:xmlns:office:1.0")
.addAttribute("xmlns:style", "urn:oasis:names:tc:opendocument:xmlns:style:1.0")
.addAttribute("xmlns:text", "urn:oasis:names:tc:opendocument:xmlns:text:1.0")
.addAttribute("xmlns:table", "urn:oasis:names:tc:opendocument:xmlns:table:1.0")
.addAttribute("xmlns:draw", "urn:oasis:names:tc:opendocument:xmlns:drawing:1.0")
.addAttribute("xmlns:fo", "urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0")
.addAttribute("xmlns:xlink", "http://www.w3.org/1999/xlink")
.addAttribute("xmlns:dc", "http://purl.org/dc/elements/1.1/")
.addAttribute("xmlns:meta", "urn:oasis:names:tc:opendocument:xmlns:meta:1.0")
.addAttribute("xmlns:number", "urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0")
.addAttribute("xmlns:svg", "urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0")
.addAttribute("xmlns:chart", "urn:oasis:names:tc:opendocument:xmlns:chart:1.0")
.addAttribute("xmlns:dr3d", "urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0")
.addAttribute("xmlns:math", "http://www.w3.org/1998/Math/MathML")
.addAttribute("xmlns:form", "urn:oasis:names:tc:opendocument:xmlns:form:1.0")
.addAttribute("xmlns:script", "urn:oasis:names:tc:opendocument:xmlns:script:1.0")
.addAttribute("xmlns:ooo", "http://openoffice.org/2004/office")
.addAttribute("xmlns:ooow", "http://openoffice.org/2004/writer")
.addAttribute("xmlns:oooc", "http://openoffice.org/2004/calc")
.addAttribute("xmlns:dom", "http://www.w3.org/2001/xml-events")
.addAttribute("xmlns:xforms", "http://www.w3.org/2002/xforms")
.addAttribute("xmlns:xsd", "http://www.w3.org/2001/XMLSchema")
.addAttribute("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance")
.addAttribute("office:version", "1.0")
.endOpenTag();
return this;
};
OpenDocument.XmlWriter.prototype.closeDocumentContent = function () {
this
.closeTag("office:document-content");
return this;
};
OpenDocument.XmlWriter.prototype.openStyles = function () {
this
.openTag("office:styles");
return this;
};
OpenDocument.XmlWriter.prototype.closeStyles = function () {
this
.closeTag("office:styles");
return this;
};
OpenDocument.XmlWriter.prototype.openAutomaticStyles = function () {
this
.openTag("office:automatic-styles");
return this;
};
OpenDocument.XmlWriter.prototype.closeAutomaticStyles = function () {
this
.closeTag("office:automatic-styles");
return this;
};
OpenDocument.XmlWriter.prototype.openBody = function () {
this
.openTag("office:body");
return this;
};
OpenDocument.XmlWriter.prototype.closeBody = function () {
this
.closeTag("office:body");
return this;
};
OpenDocument.XmlWriter.prototype.openSpreadsheet = function () {
this
.openTag("office:spreadsheet");
return this;
};
OpenDocument.XmlWriter.prototype.closeSpreadsheet = function () {
this
.closeTag("office:spreadsheet");
return this;
};
OpenDocument.XmlWriter.prototype.openStyle = function (styleName, styleFamily, parentStyleName) {
this
.startStyleOpenTag(styleName, styleFamily, parentStyleName)
.endOpenTag();
return this;
};
OpenDocument.XmlWriter.prototype.startStyleOpenTag = function (styleName, styleFamily, parentStyleName) {
this
.startOpenTag("style:style")
.addAttribute("style:name", styleName);
if (styleName.indexOf("_20_") > -1) {
let displayName = styleName.replace("_20_", " ");
this
.addAttribute("style:display-name", displayName);
}
this
.addAttribute("style:family", styleFamily)
.addAttribute("style:parent-style-name", parentStyleName);
return this;
};
OpenDocument.XmlWriter.prototype.closeStyle = function () {
this
.closeTag("style:style");
return this;
};
OpenDocument.XmlWriter.prototype.addDateStyle = function (datePattern, dataStyleName) {
var xmlWriter = this;
var length = datePattern.length;
var buffer = "";
xmlWriter
.startOpenTag("number:date-style")
.addAttribute("style:name", dataStyleName)
.endOpenTag();
for(let i = 0; i < length; i++) {
let char = datePattern.charAt(i);
let jump = 0;
switch(char) {
case 'M':
jump = _parseMonth(i);
break;
case 'D':
jump = _parseDay(i);
break;
case 'Y':
jump = _parseYear(i);
if (jump === 0) {
_buf(char);
}
break;
default:
_buf(char);
}
i = i + jump;
}
_flush();
xmlWriter
.closeTag("number:date-style");
return this;
function _buf(char) {
buffer = buffer + char;
}
function _parseMonth(index) {
_flush();
let jump = 0;
let next = index + 1;
if ((next < length) && (datePattern.charAt(next) === 'M')) {
jump = 1;
}
_addNumberElement("number:month", (jump === 1));
return jump;
}
function _parseDay(index) {
_flush();
let jump = 0;
let next = index + 1;
if ((next < length) && (datePattern.charAt(next) === 'D')) {
jump = 1;
}
_addNumberElement("number:day", (jump === 1));
return jump;
}
function _parseYear(index) {
let next = index + 1;
if ((next === length) || (datePattern.charAt(next) !== 'Y')) {
return 0;
}
_flush();
let jump = 1;
if (next < (length -2)) {
if ((datePattern.charAt(next + 1) === 'Y') && (datePattern.charAt(next + 2) === 'Y')) {
jump = 3;
}
}
_addNumberElement("number:year", (jump === 3));
return jump;
}
function _flush() {
if (buffer) {
xmlWriter.addSimpleElement("number:text", buffer);
buffer = "";
}
}
function _addNumberElement(name, isLong) {
xmlWriter
.startOpenTag(name);
if (isLong) {
xmlWriter
.addAttribute("number:style", "long");
}
xmlWriter
.closeEmptyTag();
}
};
OpenDocument.XmlWriter.prototype.addCurrencyStyle = function (currencyCode, dataStyleName) {
var currency = Currency.get(currencyCode);
this
.startOpenTag("number:currency-style")
.addAttribute("style:name", dataStyleName + "P0")
.addAttribute("style:volatile", "true")
.endOpenTag();
if (currency.symbolBefore) {
this
.addSimpleElement("number:currency-symbol", currency.symbol);
}
this
.startOpenTag("number:number")
.addAttribute("number:decimal-places", currency.fractionDigits)
.addAttribute("number:min-integer-digits", "1")
.addAttribute("number:grouping", "true")
.closeEmptyTag();
if (!currency.symbolBefore) {
this
.addSimpleElement("number:text", " ")
.addSimpleElement("number:currency-symbol", currency.symbol);
}
this
.closeTag("number:currency-style")
.startOpenTag("number:currency-style")
.addAttribute("style:name", dataStyleName)
.endOpenTag()
.startOpenTag("style:text-properties")
.addAttribute("fo:color", "#ff0000")
.closeEmptyTag()
.addSimpleElement("number:text", "-");
if (currency.symbolBefore) {
this
.addSimpleElement("number:currency-symbol", currency.symbol);
}
this
.startOpenTag("number:number")
.addAttribute("number:decimal-places", currency.fractionDigits)
.addAttribute("number:min-integer-digits", "1")
.addAttribute("number:grouping", "true")
.closeEmptyTag();
if (!currency.symbolBefore) {
this
.addSimpleElement("number:text", " ")
.addSimpleElement("number:currency-symbol", currency.symbol);
}
this
.startOpenTag("style:map")
.addAttribute("style:condition", "value()>=0")
.addAttribute("style:apply-style-name", dataStyleName + "P0")
.closeEmptyTag()
.closeTag("number:currency-style");
return this;
};
OpenDocument.XmlWriter.prototype.openNamedExpressions = function () {
this
.openTag("table:named-expressions");
return this;
};
OpenDocument.XmlWriter.prototype.closeNamedExpressions = function () {
this
.closeTag("table:named-expressions");
return this;
};
OpenDocument.XmlWriter.prototype.addNamedRange = function (name, address) {
this
.startOpenTag("table:named-range")
.addAttribute("table:name", name)
.addAttribute("table:base-cell-address", address)
.addAttribute("table:cell-range-address", address)
.closeEmptyTag();
return this;
};
OpenDocument.XmlWriter.prototype.openTable = function (name) {
this.cellCounter.reinit();
this
.startOpenTag("table:table")
.addAttribute("table:name", OpenDocument.checkSheetName(name))
.endOpenTag();
return this;
};
OpenDocument.XmlWriter.prototype.closeTable = function () {
this
.closeTag("table:table");
return this;
};
OpenDocument.XmlWriter.prototype.addTableColumn = function (tableColumn) {
this
.startOpenTag("table:table-column")
.addAttribute("table:style-name", tableColumn.styleName);
if (tableColumn.columnsRepeated > 1) {
this
.addAttribute("table:number-columns-repeated", tableColumn.columnsRepeated);
}
this
.addAttribute("table:default-cell-style-name", tableColumn.defaultCellStyleName)
.closeEmptyTag();
return this;
};
OpenDocument.XmlWriter.prototype.openTableRow = function (rowStyleName) {
this.cellCounter.newRow();
this
.startOpenTag("table:table-row")
.addAttribute("table:style-name", rowStyleName)
.endOpenTag();
return this;
};
OpenDocument.XmlWriter.prototype.closeTableRow = function () {
this
.closeTag("table:table-row");
return this;
};
OpenDocument.XmlWriter.prototype.addEmptyTableCell = function (cell) {
this
.startCell(cell)
.endCell(cell, true);
return this;
};
OpenDocument.XmlWriter.prototype.addNumberTableCell = function (cell) {
this
.startCell(cell)
.addAttribute("office:value-type", "float")
.addAttribute("office:value", cell.value)
.endCell(cell, true);
return this;
};
OpenDocument.XmlWriter.prototype.addPercentageTableCell = function (cell) {
this
.startCell(cell)
.addAttribute("office:value-type", "percentage")
.addAttribute("office:value", cell.value)
.endCell(cell, true);
return this;
};
OpenDocument.XmlWriter.prototype.addDateTableCell = function (cell) {
this
.startCell(cell)
.addAttribute("office:value-type", "date")
.addAttribute("office:date-value", cell.value)
.endCell(cell, true);
return this;
};
OpenDocument.XmlWriter.prototype.addCurrencyTableCell = function (cell, currency) {
this
.startCell(cell)
.addAttribute("office:value-type", "currency")
.addAttribute("office:currency", currency)
.addAttribute("office:value", cell.value)
.endCell(cell, true);
return this;
};
OpenDocument.XmlWriter.prototype.addLinkStringTableCell = function (cell, linkString) {
this
.startCell(cell)
.addAttribute("office:value-type", "string")
.endOpenTag();
if ((linkString) && (linkString.length > 0)) {
this
.startOpenTag("text:p")
.endOpenTag()
.XmlWriter.prototype.addLink(linkString)
.closeTag("text:p", false);
}
this
.endCell(cell, false);
return this;
};
OpenDocument.XmlWriter.prototype.addStringTableCell = function (cell) {
this
.startCell(cell)
.addAttribute("office:value-type", "string")
.endOpenTag()
.splitText(cell.value)
.endCell(cell, false);
return this;
};
OpenDocument.XmlWriter.prototype.addFormulaTableCell = function (cell, valueType) {
this
.startCell(cell)
.addAttribute("table:formula", cell.value)
.addAttribute("office:value-type", valueType)
.endCell(cell, true);
return this;
};
OpenDocument.XmlWriter.prototype.splitText = function (value) {
if (value) {
var tokens = value.split('\n');
for (let token of tokens) {
this
.startOpenTag("text:p")
.endOpenTag()
.addText(token)
.closeTag("text:p", false);
}
}
return this;
};
OpenDocument.XmlWriter.prototype.addLink = function (link) {
this
.startOpenTag("text:a", false)
.addAttribute("xlink:href", link)
.endOpenTag()
.addText(link)
.closeTag("text:a", false);
return this;
};
OpenDocument.XmlWriter.prototype.startCell = function (cell) {
var jump = this.cellCounter.newCell(cell.rowSpan, cell.colSpan);
if (jump > 0) {
this
.startOpenTag("table:covered-table-cell");
if (jump > 1) {
this
.addAttribute("table:number-columns-repeated", jump)
}
this
.closeEmptyTag();
}
this
.startOpenTag("table:table-cell")
.addAttribute("table:style-name", cell.styleName);
if (cell.rowSpan > 1) {
this.addAttribute("table:number-rows-spanned", cell.rowSpan);
}
if (cell.colSpan > 1) {
this
.addAttribute("table:number-columns-spanned", cell.colSpan);
}
return this;
};
OpenDocument.XmlWriter.prototype.endCell = function (cell, emptyTag) {
if (emptyTag) {
this
.closeEmptyTag();
} else {
this
.closeTag("table:table-cell");
}
if (cell.colSpan > 1) {
this
.startOpenTag("table:covered-table-cell");
if (cell.colSpan > 2) {
this
.addAttribute("table:number-columns-repeated", (cell.colSpan - 1));
}
this
.closeEmptyTag();
}
return this;
};
OpenDocument.XmlWriter.prototype.openSettings = function () {
this
.openTag("office:settings");
return this;
};
OpenDocument.XmlWriter.prototype.closeSettings = function () {
this
.closeTag("office:settings");
return this;
};
OpenDocument.XmlWriter.prototype.openConfigItemSet = function (name) {
this
.startOpenTag("config:config-item-set")
.addAttribute("config:name", name)
.endOpenTag();
return this;
};
OpenDocument.XmlWriter.prototype.closeConfigItemSet = function () {
this
.closeTag("config:config-item-set");
return this;
};
OpenDocument.XmlWriter.prototype.openConfigItemMapIndexed = function (name) {
this
.startOpenTag("config:config-item-map-indexed")
.addAttribute("config:name", name)
.endOpenTag();
return this;
};
OpenDocument.XmlWriter.prototype.closeConfigItemMapIndexed = function () {
this
.closeTag("config:config-item-map-indexed");
return this;
};
OpenDocument.XmlWriter.prototype.openConfigItemMapNamed = function (name) {
this
.startOpenTag("config:config-item-map-named")
.addAttribute("config:name", name)
.endOpenTag();
return this;
};
OpenDocument.XmlWriter.prototype.closeConfigItemMapNamed = function () {
this
.closeTag("config:config-item-map-named");
return this;
};
OpenDocument.XmlWriter.prototype.openConfigItemMapEntry = function (name) {
this
.startOpenTag("config:config-item-map-entry")
.addAttribute("config:name", name)
.endOpenTag();
return this;
};
OpenDocument.XmlWriter.prototype.closeConfigItemMapEntry = function () {
this
.closeTag("config:config-item-map-entry");
return this;
};
OpenDocument.XmlWriter.prototype.addConfigItem = function (name, type, value) {
this
.startOpenTag("config:config-item", true)
.addAttribute("config:name", name)
.addAttribute("config:type", type)
.endOpenTag()
.addText(value)
.closeTag("config:config-item", false);
return this;
};
OpenDocument.Style = function (type, styleName) {
this.type = type;
this.styleName = styleName;
this.styleFamily = OpenDocument.Style.getMatchingStyleFamily(type);
this.parentStyleName = "";
this.dataStyleName = "";
this.propertiesMaps = new Map([
["paragraph", new Map()],
["text", new Map()],
["table-cell", new Map()],
["table-row", new Map()],
["table-column", new Map()]
]);
};
OpenDocument.Style.prototype.putStyleProperty = function (stylePropertyDef, value) {
var propertyName = stylePropertyDef.name;
switch(stylePropertyDef.format) {
case "color":
value = OpenDocument.Style.formatColor(value);
break;
case "wrap":
value = _convertWrap();
break;
}
var property = {
name: propertyName,
value: value
};
this.propertiesMaps.get(stylePropertyDef.category).set(propertyName, property);
function _convertWrap() {
switch(value) {
case "anywhere":
case "break-word":
return "wrap";
default:
return "no-wrap";
}
}
};
OpenDocument.Style.prototype.setParent = function (parentStyleName) {
this.parentStyleName = parentStyleName;
};
OpenDocument.Style.prototype.setDataStyle = function (dataStyleName) {
this.dataStyleName = dataStyleName;
};
OpenDocument.Style.prototype.isEmpty = function () {
for(let map of this.propertiesMaps.values()) {
if (map.size > 0) {
return false;
}
}
return true;
};
OpenDocument.Style.prototype.copyProperties = function (otherStyle) {
if (otherStyle.parentStyleName) {
this.setParent(otherStyle.parentStyleName);
}
for(let entry of otherStyle.propertiesMaps) {
let otherMap = entry[1];
let thisMap = this.propertiesMaps.get(entry[0]);
for(let entry2 of otherMap) {
thisMap.set(entry2[0], entry2[1]);
}
}
};
OpenDocument.Style.prototype.write = function (xmlWriter) {
xmlWriter
.startStyleOpenTag(this.styleName, this.styleFamily, this.parentStyleName)
.addAttribute("style:data-style-name", this.dataStyleName);
if (this.isEmpty()) {
xmlWriter
.closeEmptyTag();
} else {
xmlWriter
.endOpenTag();
for(let entry of this.propertiesMaps) {
let category = entry[0];
let map = entry[1];
if (map.size > 0) {
xmlWriter
.startOpenTag("style:" + category + "-properties");
for(let property of map.values()) {
xmlWriter
.addAttribute(property.name, property.value);
}
xmlWriter
.closeEmptyTag();
}
}
xmlWriter
.closeStyle();
}
};
OpenDocument.Style.getStylePropertyDef = function (type, name) {
name = _checkAlias();
if (OpenDocument.Style.STYLEPROPERTYDEFS.hasOwnProperty(name)) {
let propertyDef = OpenDocument.Style.STYLEPROPERTYDEFS[name];
if (propertyDef.categories) {
for(let propKey in propertyDef.categories) {
if (propKey === type) {
return Object.assign({}, propertyDef, {category: propertyDef.categories[propKey]});
}
}
return null;
} else {
return propertyDef;
}
} else {
return null;
}
function _checkAlias() {
switch(type) {
case "row":
switch(name) {
case "height":
return "row-height";
}
break;
case "column":
switch(name) {
case "width":
return "column-width";
}
break;
case "cell":
switch(name) {
case "overflow-wrap":
return "wrap-option";
}
break;
}
return name;
}
};
OpenDocument.Style.getMatchingStyleFamily = function (type) {
switch(type) {
case "cell":
return "table-cell";
case "row":
return "table-row";
case "column":
return "table-column";
}
};
OpenDocument.Style.STYLEPROPERTYDEFS = {
"background-color": {
name: "fo:background-color",
categories: {
"cell": "table-cell",
"row": "table-row"
},
format: "color"
},
"border": {
name: "fo:border",
category: "table-cell"
},
"border-bottom": {
name: "fo:border-bottom",
category: "table-cell"
},
"border-left": {
name: "fo:border-left",
category: "table-cell"
},
"border-right": {
name: "fo:border-right",
category: "table-cell"
},
"border-top": {
name: "fo:border-top",
category: "table-cell"
},
"color": {
name: "fo:color",
category: "text",
format: "color"
},
"column-width": {
name: "style:column-width",
category: "table-column"
},
"font-size": {
name: "fo:font-size",
category: "text"
},
"font-style": {
name: "fo:font-style",
category: "text"
},
"font-weight": {
name: "fo:font-weight",
category: "text"
},
"padding": {
name: "fo:padding",
category: "table-cell"
},
"padding-bottom": {
name: "fo:padding-bottom",
category: "table-cell"
},
"padding-left": {
name: "fo:padding-left",
category: "table-cell"
},
"padding-right": {
name: "fo:padding-right",
category: "table-cell"
},
"padding-top": {
name: "fo:padding-top",
category: "table-cell"
},
"row-height": {
name: "style:row-height",
category: "table-row"
},
"text-align": {
name: "fo:text-align",
category: "paragraph"
},
"use-optimal-row-height": {
name: "style:use-optimal-row-height",
category: "table-row"
},
"vertical-align": {
name: "style:vertical-align",
category: "table-cell"
},
"wrap-option": {
name: "fo:wrap-option",
category: "table-cell",
format: "wrap"
}
};
OpenDocument.Style.formatColor = function (color) {
let colorList = color.match(/rgb\((.*)\)/);
if (colorList) {
let hexresult = "#";
for(let token of colorList[1].split(",")) {
let hex = Number.parseInt(token.trim(), 10).toString(16);
if (hex.length === 1) {
hex = "0" + hex;
}
hexresult += hex;
}
color = hexresult;
}
return color;
};
OpenDocument.StyleManager = function () {
this.maps = new Map([
["cell-named", new Map()],
["row-named", new Map()],
["cell-automatic", new Map()],
["column-named", new Map()],
["column-automatic", new Map()]
]);
this.matchingClassMaps = new Map([
["cell", new Map()],
["row", new Map()],
["column", new Map()]
]);
for(let object of OpenDocument.StyleManager.DEFAULT_STYLES ) {
this.putStyle(object.type + "-named", _buildDefault(object));
}
this.automaticCellStyleNumber = 1;
this.dataStyleNumber = 1;
this.currencyDataStyleMap = new Map();
this.dateDataStyleMap = new Map();
OpenDocument.StyleManager.readDocumentStyleSheets(this);
function _buildDefault(object) {
let style = new OpenDocument.Style(object.type, object.name);
if (object.parent) {
style.setParent(object.parent);
}
for(let propertyName in object.properties) {
let stylePropertyDef = OpenDocument.Style.getStylePropertyDef(object.type, propertyName);
if (stylePropertyDef) {
style.putStyleProperty(stylePropertyDef, object.properties[propertyName]);
}
}
return style;
}
};
OpenDocument.StyleManager.prototype.putStyle = function (mapName, style, styleKey) {
if (!styleKey) {
styleKey = style.styleName;
}
var map = this.maps.get(mapName);
if (map.has(styleKey)) {
let existingStyle = map.get(styleKey);
existingStyle.copyProperties(style);
} else {
map.set(styleKey, style);
}
};
OpenDocument.StyleManager.prototype.hasStyle = function (mapName, styleKey) {
var map = this.maps.get(mapName);
if (map) {
return map.has(styleKey);
} else {
return false;
}
};
OpenDocument.StyleManager.prototype.getStyle = function (mapName, styleKey) {
var map = this.maps.get(mapName);
if (map) {
return map.get(styleKey);
} else {
return null;
}
return this.map.get(styleKey);
};
OpenDocument.StyleManager.prototype.getAutomaticCellStyleName = function (type, parentStyleName, cellOption) {
var styleKey = _buildStyleKey();
if (this.hasStyle("cell-automatic", styleKey)) {
return this.getStyle("cell-automatic", styleKey).styleName;
}
var automaticCellStyleName = this.getNewAutomaticeCellStyleName();
var dataStyleName = null;
switch(type) {
case "date":
dataStyleName = this.getMatchingDateDataStyleName(cellOption);
break;
case "currency":
dataStyleName = this.getMatchingCurrencyDataStyleName(cellOption);
break;
}
var cellStyle = new OpenDocument.Style("cell", automaticCellStyleName);
if (parentStyleName) {
cellStyle.setParent(parentStyleName);
} else {
cellStyle.setParent(OpenDocument.DEFAULT_CELLSTYLE_NAME);
}
if (dataStyleName) {
cellStyle.setDataStyle(dataStyleName);
}
this.putStyle("cell-automatic", cellStyle, styleKey);
return automaticCellStyleName;
function _buildStyleKey() {
let key = type + ":";
if (cellOption) {
key += cellOption + ":";
}
key += parentStyleName;
return key;
}
};
OpenDocument.StyleManager.prototype.getNewAutomaticeCellStyleName = function () {
var name = OpenDocument.CELLSTYLE_PREFIX + this.automaticCellStyleNumber;
this.automaticCellStyleNumber++;
return name;
};
OpenDocument.StyleManager.prototype.getMatchingCurrencyDataStyleName = function (currencyCode) {
if (this.currencyDataStyleMap.has(currencyCode)) {
return this.currencyDataStyleMap.get(currencyCode);
} else {
let dataStyleName = OpenDocument.DATASTYLE_PREFIX + this.dataStyleNumber;
this.dataStyleNumber++;
this.currencyDataStyleMap.set(currencyCode, dataStyleName);
return dataStyleName;
}
};
OpenDocument.StyleManager.prototype.getMatchingDateDataStyleName = function (datePattern) {
if (this.dateDataStyleMap.has(datePattern)) {
return this.dateDataStyleMap.get(datePattern);
} else {
let dataStyleName = OpenDocument.DATASTYLE_PREFIX + this.dataStyleNumber;
this.dataStyleNumber++;
this.dateDataStyleMap.set(datePattern, dataStyleName);
return dataStyleName;
}
};
OpenDocument.StyleManager.prototype.getMatchingStyleName = function (type, element) {
var map = this.matchingClassMaps.get(type);
if (map) {
for(let className of element.classList) {
if (map.has(className)) {
return map.get(className);
}
}
}
return "";
};
OpenDocument.StyleManager.prototype.writeStyles = function (mapName, xmlWriter) {
var map = this.maps.get(mapName);
if (map) {
for(let style of map.values()) {
style.write(xmlWriter);
}
}
};
OpenDocument.StyleManager.prototype.writeDataStyles = function (xmlWriter) {
for(let entry of this.dateDataStyleMap) {
xmlWriter
.addDateStyle(entry[0], entry[1]);
}
for(let entry of this.currencyDataStyleMap) {
xmlWriter
.addCurrencyStyle(entry[0], entry[1]);
}
};
OpenDocument.StyleManager.readDocumentStyleSheets = function (styleManager) {
var styleSheetList = document.styleSheets;
for(let i = 0, len = styleSheetList.length; i < len; i++) {
OpenDocument.StyleManager.readStyleSheet(styleManager, styleSheetList[i]);
}
};
OpenDocument.StyleManager.readStyleSheet = function (styleManager, styleSheet) {
var ruleList = styleSheet.cssRules;
for(let i = 0, len = ruleList.length; i < len; i++) {
let rule = ruleList[i];
if ((rule.selectorText) && (rule.style)) {
let selectorArray = _parseSelectorText(rule.selectorText);
for(let selector of selectorArray) {
_addStyle(selector, rule.style);
}
}
}
function _parseSelectorText(selectorText) {
let resultArray = new Array();
for(let token of selectorText.split(',')) {
let result = __parseToken(token);
if (result) {
switch(result[0]) {
case "cell":
case "row":
case "column":
resultArray.push(result);
break;
}
}
}
return resultArray;
function __parseToken(token) {
token = token.trim();
let idx = token.indexOf(' ');
let followingPart = "";
if (idx !== -1) {
followingPart = token.substring(idx +1).trim();
token = token.substring(0, idx);
}
let dotIndex = token.indexOf('.');
if (dotIndex === -1) {
return null;
}
let type = token.substring(0, dotIndex);
let name = token.substring(dotIndex + 1);
return [type, name, followingPart];
}
}
function _addStyle(selector, cssStyleDeclaration) {
let type = selector[0];
let style = new OpenDocument.Style(type, selector[1]);
let borderBuffer = false;
if (type === "cell") {
borderBuffer = new OpenDocument.StyleManager.BorderBuffer();
}
for(let i = 0, len = cssStyleDeclaration.length; i < len; i++) {
let propertyName = cssStyleDeclaration[i];
let propertyValue = cssStyleDeclaration.getPropertyValue(propertyName);
if (borderBuffer) {
let borderTest = propertyName.match(/^border-([a-z]+)-([a-z]+)/);
if (borderTest) {
borderBuffer.putSubproperty(borderTest[1], borderTest[2], propertyValue);
continue;
}
}
if (propertyName === "content") {
__parseDeclarationText(propertyValue);
} else {
let stylePropertyDef = OpenDocument.Style.getStylePropertyDef(type, propertyName);
if (stylePropertyDef) {
style.putStyleProperty(stylePropertyDef, propertyValue);
}
}
}
if (borderBuffer) {
borderBuffer.fillStyle(style);
}
_parseFollowingPart(selector[2]);
styleManager.putStyle(type + "-named", style);
function __parseDeclarationText(declarationText) {
let start = declarationText.indexOf('"');
if (start === -1) {
return;
}
let end = declarationText.lastIndexOf('"');
if (end === start) {
return;
}
let tokens = declarationText.substring(start + 1, end).split(';');
for(let token of tokens) {
let paire = token.split(':');
if (paire.length === 2) {
let name = paire[0].trim();
let value = paire[1].trim();
let stylePropertyDef = OpenDocument.Style.getStylePropertyDef(type, name);
if (stylePropertyDef) {
style.putStyleProperty(stylePropertyDef, value);
}
}
}
}
function _parseFollowingPart(followingPart) {
if (!followingPart) {
return;
}
let tokens = new Array();
for(let token of followingPart.split(" ")) {
token = token.trim();
if (token.length > 0) {
tokens.push(token);
}
}
let index = 0;
let length = tokens.length - 1;
while(index < length) {
let operatorToken = tokens[index];
switch(operatorToken) {
case '~':
for(let i = index +1; i <= length; i++) {
__addMatchingClasses(tokens[i]);
}
index = length;
break;
case '+':
__setParent(tokens[index +1]);
index ++;
break;
}
index ++;
}
}
function __addMatchingClasses(token) {
if (!token) {
return;
}
let map = styleManager.matchingClassMaps.get(type);
if (!map) {
return;
}
if (token.startsWith('.')) {
map.set(token.substring(1), style.styleName);
}
}
function __setParent(token) {
if (!token) {
return;
}
let dotIndex = token.indexOf('.');
if (dotIndex !== -1) {
style.setParent(token.substring(dotIndex + 1));
}
}
}
};
OpenDocument.StyleManager.BorderBuffer = function () {
this.map = new Map([
["bottom", false],
["left", false],
["right", false],
["top", false]
]);
};
OpenDocument.StyleManager.BorderBuffer.prototype.putSubproperty = function (position, subproperty, value) {
if (!this.map.has(position)) {
return;
}
let positionObject = this.map.get(position);
if (!positionObject) {
positionObject = {
width: "0.75pt",
color: "rgb(0, 0, 0)",
style: "solid"
};
this.map.set(position, positionObject);
}
if (positionObject.hasOwnProperty(subproperty)) {
if (subproperty === "color") {
value = OpenDocument.Style.formatColor(value);
}
positionObject[subproperty] = value;
};
};
OpenDocument.StyleManager.BorderBuffer.prototype.fillStyle = function (style) {
for(let entry of this.map) {
let position = entry[0];
let object = entry[1];
if (object) {
let stylePropertyDef = OpenDocument.Style.getStylePropertyDef("type", "border-" + position);
if (stylePropertyDef) {
let value = object.width + " " + object.style + " " + object.color;
style.putStyleProperty(stylePropertyDef, value);
}
}
}
};
OpenDocument.StyleManager.DEFAULT_STYLES = [
{
type: "cell",
name: "Standard",
parent: "",
properties: {
}
},
{
type: "cell",
name: "Bold",
parent: "Standard",
properties: {
"font-weight": "bold"
}
},
{
type: "cell",
name: "Italic",
parent: "Standard",
properties: {
"font-weight": "italic"
}
},
{
type: "cell",
name: "BoldItalic",
parent: "Standard",
properties: {
"font-weight": "bold",
"font-style": "italic"
}
},
{
type: "cell",
name: "Header",
properties: {
"font-weight": "bold",
"text-align": "center",
"vertical-align": "middle"
}
},
{
type: "row",
name: "Standard",
parent: "",
properties: {
}
},
{
type: "row",
name: "Header",
parent: "",
properties: {
}
}
];
OpenDocument.OdsConverter = function (xmlWriter, options) {
this.xmlWriter = xmlWriter;
this.sheetName = "";
this.nameMap = {};
this.flatOds = true;
this.styleManager = new OpenDocument.StyleManager();
this.cellStyleNumber = 1;
this.currencyMap = {};
this.fixedRows = 0;
this.fixedColumns = 0;
this.textDataAttribute = "text";
this.defaultCurrencyCode = "";
this.defaultDatePattern = "YYYY-MM-DD";
if (options) {
if (options.datePattern) {
this.defaultDatePattern = options.datePattern;
}
if (options.currency) {
this.defaultCurrencyCode = options.currency;
}
if (options.textAlias) {
this.textDataAttribute = options.textAlias;
}
}
};
OpenDocument.OdsConverter.convertToBlob = function (table, options) {
var xml = OpenDocument.OdsConverter.convertToXml(table, options);
return new Blob([xml], {type: OpenDocument.SPREADSHEET_MIMETYPE });
};
OpenDocument.OdsConverter.convertToXml = function (table, options) {
var xmlWriter = new OpenDocument.XmlWriter({prettyXml: true});
var odsConverter = new OpenDocument.OdsConverter(xmlWriter, options);
odsConverter.convert(table);
return xmlWriter.xml;
};
OpenDocument.OdsConverter.prototype.checkOdData = function (table) {
let odCurrency = table.dataset["odCurrency"];
if (odCurrency) {
this.defaultCurrencyCode = odCurrency;
}
let sheetName = table.dataset["odSheetname"];
if (sheetName) {
this.sheetName = sheetName;
}
let fixedRows = table.dataset["odFixedRows"];
if (fixedRows) {
this.fixedRows = fixedRows;
}
let fixedColumns = table.dataset["odFixedColumns"];
if (fixedColumns) {
this.fixedColumns = fixedColumns;
}
let odDatePattern = table.dataset["odDatePattern"];
if (odDatePattern) {
this.defaultDatePattern = odDatePattern;
}
};
OpenDocument.OdsConverter.prototype.convert = function (table) {
if (typeof table === "string") {
table = document.getElementById(table);
}
this.checkOdData(table);
var converter = this;
var styleManager = this.styleManager;
var _getRowStyleName = OpenDocument.OdsConverter.default_getRowStyleName;
var _getCellStyleName = OpenDocument.OdsConverter.default_getCellStyleName;
var columnArray = OpenDocument.OdsConverter.readTableColumns(table, styleManager);
var xw = new OpenDocument.XmlWriter({indentLength: 3});
xw
.openTable(converter.sheetName);
for(let tableColumn of columnArray) {
xw
.addTableColumn(tableColumn);
}
for(let row of table.rows) {
let display = window.getComputedStyle(row).display;
let odHidden = OpenDocument.checkHiddenValue(row);
if (((display === "none") && (odHidden !== -1)) || (odHidden === 1)) {
continue;
}
xw
.openTableRow(_getRowStyleName(row, styleManager));
for(let cell of row.cells) {
_addCell(cell);
}
xw
.closeTableRow();
}
xw
.closeTable(xw);
this.ods(xw.xml);
function _addCell(cell) {
let text = _getCellText(cell);
let odCell = new OpenDocument.Elements.Cell(text, _getCellStyleName(cell, styleManager), cell.rowSpan, cell.colSpan);
if (!text) {
xw
.addEmptyTableCell(odCell);
return;
}
let type = cell.dataset["odType"];
switch(type) {
case "number":
xw
.addNumberTableCell(odCell);
break;
case "date":
let datePattern = cell.dataset["odDatePattern"];
if (!datePattern) {
datePattern = converter.defaultDatePattern;
}
odCell.styleName = styleManager.getAutomaticCellStyleName("date", odCell.styleName, datePattern);
xw
.addDateTableCell(odCell);
break;
case "currency":
let currencyCode = cell.dataset["odCurrency"];
if (!currencyCode) {
currencyCode = converter.defaultCurrencyCode;
}
odCell.styleName = styleManager.getAutomaticCellStyleName("currency", odCell.styleName, currencyCode);
xw
.addCurrencyTableCell(odCell, currencyCode);
break;
default:
xw
.addStringTableCell(odCell);
}
}
function _getCellText(cellElement) {
let cellText = cellElement.dataset["odText"];
if (cellText) {
return cellText;
}
cellText = cellElement.dataset[converter.textDataAttribute];
if (cellText) {
return cellText;
}
cellText = "";
let previousBlock = false;
for(let node of cellElement.childNodes) {
if (node.nodeType === Node.ELEMENT_NODE) {
let display = window.getComputedStyle(node).display;
let odHidden = OpenDocument.checkHiddenValue(node);
switch(display) {
case "none":
break;
case "block":
if (odHidden !== 1) {
__addText(node.innerText, true);
}
previousBlock = true;
break;
default:
if (odHidden !== 1) {
__addText(node.innerText, false);
}
}
} else {
if (node.textContent) {
let text = node.textContent;
text = text.replace(/[\s\uFEFF\xA0]/g, ' ');
__addText(text, false);
}
}
}
return cellText.trim().replace(/ +/g, ' ');
function __addText(text, isBlock) {
if (!text) {
return false;
}
if ((previousBlock) || (isBlock)) {
cellText = cellText.trimEnd() + "\n";
previousBlock = false;
text = text.trimStart();
}
cellText += text;
return true;
}
}
};
OpenDocument.OdsConverter.prototype.ods = function (tableXml) {
var xw = this.xmlWriter;
xw.appendXMLDeclaration();
if (this.flatOds) {
xw
.openDocument(OpenDocument.SPREADSHEET_MIMETYPE);
} else {
xw
.openDocumentContent();
}
if ((this.fixedColumns > 0) || (this.fixedRows > 0)) {
xw
.openSettings()
.openConfigItemSet("ooo:view-settings")
.openConfigItemMapIndexed("Views")
.openConfigItemMapEntry( "")
.addConfigItem("ViewId", "string", "view1")
.openConfigItemMapNamed("Tables")
.openConfigItemMapEntry(this.sheetName);
if (this.fixedColumns > 0) {
xw
.addConfigItem("HorizontalSplitMode", "short", "2")
.addConfigItem("HorizontalSplitPosition", "int", this.fixedColumns)
.addConfigItem("PositionLeft", "int", "0")
.addConfigItem("PositionRight", "int", this.fixedColumns);
}
if (this.fixedRows > 0) {
xw
.addConfigItem("VerticalSplitMode", "short", "2")
.addConfigItem("VerticalSplitPosition", "int", this.fixedRows)
.addConfigItem("PositionTop", "int", "0")
.addConfigItem("PositionBottom", "int", this.fixedRows);
}
xw
.closeConfigItemMapEntry()
.closeConfigItemMapNamed()
.closeConfigItemMapEntry()
.closeConfigItemMapIndexed()
.closeConfigItemSet()
.closeSettings();
}
xw
.openStyles()
this.styleManager.writeStyles("cell-named", xw);
xw
.closeStyles();
xw
.openAutomaticStyles();
this.styleManager.writeStyles("row-named", xw);
this.styleManager.writeStyles("column-automatic", xw);
this.styleManager.writeDataStyles(xw);
this.styleManager.writeStyles("cell-automatic", xw);
xw
.closeAutomaticStyles()
.openBody()
.openSpreadsheet(xw)
.write(tableXml)
.closeSpreadsheet()
.closeBody();
if (this.flatOds) {
xw
.closeDocument();
} else {
xw
.closeDocumentContent();
}
};
OpenDocument.OdsConverter.prototype.checkSheetName = function (name) {
if (!name) {
name = "sheet";
}
name = OpenDocument.checkSheetName(name);
if (!this.nameMap.hasOwnProperty(name)) {
this.nameMap[name] = true;
return name;
} else {
var p = 2;
while (true) {
var newName = name + " (" + p + ")";
if (!this.nameMap.hasOwnProperty(newName)) {
this.nameMap[newName] = true;
return newName;
}
p++;
}
}
};
OpenDocument.OdsConverter.readTableColumns = function(table, styleManager) {
let colElementArray = new Array();
let result = new Array();
let colgroupList = table.getElementsByTagName("colgroup");
for(let colgroup of colgroupList) {
let colList = colgroup.getElementsByTagName("col");
if (colList.length > 0) {
for(let col of colList) {
colElementArray.push(col);
}
} else {
colElementArray.push(colgroup);
}
}
let columnNumber = 1;
for(let col of colElementArray) {
let columnName = OpenDocument.COLUMNSTYLE_PREFIX + columnNumber;
columnNumber++;
let columnStyle = new OpenDocument.Style("column", columnName);
let originalStyleName = _getColumnStyleName(col);
if (originalStyleName) {
let originalStyle = styleManager.getStyle("column-named", originalStyleName);
if (originalStyle) {
columnStyle.copyProperties(originalStyle);
}
}
let customWidth = col.dataset["odWidth"];
if (customWidth) {
columnStyle.putStyleProperty(OpenDocument.Style.STYLEPROPERTYDEFS["column-width"], customWidth);
}
styleManager.putStyle("column-automatic", columnStyle);
result.push(new OpenDocument.Elements.TableColumn(columnName, col.span, "Standard"));
}
return result;
function _getColumnStyleName(col) {
let styleName = col.dataset["odStyle"];;
if (styleName) {
return styleName;
}
styleName = styleManager.getMatchingStyleName("column", col);
if (styleName) {
return styleName;
}
return "";
}
};
OpenDocument.OdsConverter.default_getRowStyleName = function (row, styleManager) {
let styleName = row.dataset["odStyle"];
if (styleName) {
return styleName;
}
styleName = styleManager.getMatchingStyleName("row", row);
if (styleName) {
return styleName;
}
if ((row.parentNode.tagName) && (row.parentNode.tagName.toLowerCase() === "thead")) {
return "Header";
} else {
return "Standard";
}
};
OpenDocument.OdsConverter.default_getCellStyleName = function (cell, styleManager) {
let styleName = cell.dataset["odStyle"];
if (styleName) {
return styleName;
}
styleName = styleManager.getMatchingStyleName("cell", cell);
if (styleName) {
return styleName;
}
if (cell.tagName.toLowerCase() === "th") {
return "Header";
} else {
return "Standard";
}
};
switch(output) {
case "blob":
return OpenDocument.OdsConverter.convertToBlob(table, options);
case "xml":
return OpenDocument.OdsConverter.convertToXml(table, options);
default:
return null;
}
};
Html2Ods.blob = function (table, options) {
return Html2Ods("blob", table, options);
};
Html2Ods.xml = function (table, options) {
return Html2Ods("xml", table, options);
};