347 lines
11 KiB
JavaScript
347 lines
11 KiB
JavaScript
/* global Currency,OpenDocument,Node */
|
|
|
|
/**
|
|
*
|
|
* @constructor
|
|
* @param {OpenDocument.XmlWriter} xmlWriter
|
|
*/
|
|
OpenDocument.OdsConverter = function (xmlWriter) {
|
|
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;
|
|
};
|
|
|
|
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);
|
|
odsConverter.convert(table, options);
|
|
return xmlWriter.xml;
|
|
};
|
|
|
|
OpenDocument.OdsConverter.prototype.convert = function (table, options) {
|
|
if (typeof table === "string") {
|
|
table = document.getElementById(table);
|
|
}
|
|
var converter = this;
|
|
var styleManager = this.styleManager;
|
|
var _getRowStyleName = OpenDocument.OdsConverter.default_getRowStyleName;
|
|
var _getCellStyleName = OpenDocument.OdsConverter.default_getCellStyleName;
|
|
var textDataAttribute = "text";
|
|
var defaultCurrencyCode = "";
|
|
_checkArguments();
|
|
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) {
|
|
xw
|
|
.openTableRow(_getRowStyleName(row, styleManager));
|
|
for(let cell of row.cells) {
|
|
_addCell(cell);
|
|
}
|
|
xw
|
|
.closeTableRow();
|
|
}
|
|
xw
|
|
.closeTable(xw);
|
|
this.ods(xw.xml);
|
|
|
|
function _checkArguments() {
|
|
if (options) {
|
|
if (options.rowStyleName) {
|
|
_getRowStyleName = options.rowStyleName;
|
|
}
|
|
if (options.cellStyleName) {
|
|
_getCellStyleName = options.cellStyleName;
|
|
}
|
|
if (options.textDataAttribute) {
|
|
textDataAttribute = options.textDataAttribute;
|
|
}
|
|
}
|
|
defaultCurrencyCode = table.dataset["odCurrency"];
|
|
let sheetName = table.dataset["odSheetname"];
|
|
if (sheetName) {
|
|
converter.sheetName = sheetName;
|
|
}
|
|
let fixedRows = table.dataset["odFixedRows"];
|
|
if (fixedRows) {
|
|
converter.fixedRows = fixedRows;
|
|
}
|
|
let fixedColumns = table.dataset["odFixedColumns"];
|
|
if (fixedColumns) {
|
|
converter.fixedColumns = fixedColumns;
|
|
}
|
|
}
|
|
|
|
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":
|
|
odCell.styleName = styleManager.getAutomaticCellStyleName("date", odCell.styleName);
|
|
xw
|
|
.addDateTableCell(odCell);
|
|
break;
|
|
case "currency":
|
|
let currencyCode = cell.dataset["odCurrency"];
|
|
if (!currencyCode) {
|
|
currencyCode = 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[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 = node.dataset["odHidden"];
|
|
switch(display) {
|
|
case "none":
|
|
break;
|
|
case "block":
|
|
if (!odHidden) {
|
|
__addText(node.innerText, true);
|
|
}
|
|
previousBlock = true;
|
|
break;
|
|
default:
|
|
if (!odHidden) {
|
|
__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;
|
|
}
|
|
return "";
|
|
};
|
|
|
|
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";
|
|
}
|
|
};
|