Dépôt des premiers fichiers

This commit is contained in:
Vincent Calame 2022-07-17 01:21:31 +02:00
parent 7ac1c7900f
commit 1716825d9f
11 changed files with 2103 additions and 0 deletions

52
demos/dev.css Normal file
View File

@ -0,0 +1,52 @@
body {
font-family: sans-serif;
}
table {
border-collapse: collapse;
margin-left: 40px;
}
td {
border-width: 1px;
border-color: #2e3436;
border-style: solid;
font-size: small;
}
.hidden {
display: none;
}
.grandecellule {
font-size: 1.4rem;
}
/***************************
* Styles ODS
* *************************/
cell.Header {
font-style: italic;
background-color: #2244aa;
}
cell.Grande ~ .essai {
font-size: 12pt;
padding: 0.3cm;
border: 0.75pt solid #333;
}
cell.EncorePlusGrande ~ .grandecellule {
font-size: 18pt;
}
column.Longue ~ .longuecolonne {
width: 7cm;
}
row.Entete {
height: 2cm;
background-color: #ff00ff;
}

92
demos/dev.html Normal file
View File

@ -0,0 +1,92 @@
<!DOCTYPE html>
<html lang="fr">
<head>
<title>Exemple pour le développement</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta http-equiv="Content-Script-Type" content="text/javascript">
<link href="dev.css" rel="stylesheet" type="text/css">
<script type="text/javascript" src="../src/js/currency/Currency.js"></script>
<script type="text/javascript" src="../src/js/xmlwriter/XmlWriter.js"></script>
<script type="text/javascript" src="../src/js/opendocument/OpenDocument.js"></script>
<script type="text/javascript" src="../src/js/opendocument/OpenDocument.Elements.js"></script>
<script type="text/javascript" src="../src/js/opendocument/OpenDocument.CellCounter.js"></script>
<script type="text/javascript" src="../src/js/opendocument/OpenDocument.XmlWriter.js"></script>
<script type="text/javascript" src="../src/js/opendocument/OpenDocument.Style.js"></script>
<script type="text/javascript" src="../src/js/opendocument/OpenDocument.StyleManager.js"></script>
<script type="text/javascript" src="../src/js/opendocument/OpenDocument.OdsConverter.js"></script>
<script>
function fodsLink() {
let link = document.getElementById("link");
link.href = URL.createObjectURL(
OpenDocument.OdsConverter.convertToBlob("table")
);
setTimeout(function () {
URL.revokeObjectURL(link.href);
}, 4E4); // 40s
return true;
}
function fodsContent() {
document.getElementById("text").innerText = OpenDocument.OdsConverter.convertToXml("table");
}
</script>
</head>
<body onload="fodsContent()">
<h1>Exemple pour le développement</h1>
<p>Le contenu du fichier .fods est affiché après la table</p>
<div>
<p><a href="blob:" download="test1.fods" id="link" onclick="fodsLink()" id="link">Version ODS</a></p>
<table id="table"
data-od-sheetname="Tableau de suivi"
data-od-currency="EUR"
data-od-fixed-rows="2"
data-od-fixed-columns="1">
<col data-od-style="Longue">
<colgroup>
<col>
</colgroup>
<colgroup span="2" class="longuecolonne">
</colgroup>
<thead>
<tr data-od-style="Entete">
<th colspan="3">Colonne 1</th>
<th rowspan="2">Colonne 3</th>
</tr>
<tr>
<th>Sous-colonne 1-1</th>
<th>Sous-colonne 1-2</th>
<th>Sous-colonne 1-3</th>
</tr>
</thead>
<tbody>
<tr>
<td>Cellule 1.1</td>
<td rowspan="2" id="test">Cellule <em>1.2</em>
<div class="hidden">
Caché par None
</div> Suite</td>
<td>Cellule 1.3
<div data-od-hidden="true">
Caché dans OD
</div> Test à des lignes vides </td>
<td>Cellule 1.4</td>
</tr>
<tr>
<td colspan="2" data-od-style="EncorePlusGrande">Cellule 2.1 (Très grande)</td>
<!--<td>Cellule 2.2</td>-->
<td data-od-style="Bold">Cellule 2.3</td>
<td data-od-type="number" class="grandecellule">-160</td>
</tr>
<tr>
<td>Cellule 3.1</td>
<td>Cellule 3.2</td>
<td data-od-type="currency" data-text="1000">1000 €</td>
<td data-od-type="currency" data-od-currency="USD" data-text="-1315" class="essai">-$2500</td>
</tr>
</tbody>
</table>
<pre id="text"></pre>
</div>
</body>
</html>

View File

@ -0,0 +1,90 @@
/* global Intl */
/**
*
* @constructor
*/
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);
};
/**
*
* @param {String} code
* @returns {Currency}
*/
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;
}
}
};

View File

@ -0,0 +1,57 @@
/* global OpenDocument,Currency,XmlWriter */
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);
}
};

View File

@ -0,0 +1,29 @@
/* global OpenDocument */
OpenDocument.Elements = {};
OpenDocument.Elements.Cell = function (value, styleName, rowSpan, colSpan) {
this.value = value;
this.styleName = styleName;
this.rowSpan = rowSpan;
this.colSpan = colSpan;
};
/***********************************************************
*
* @constructor
* @param {String} styleName
* @param {Number} columnsRepeated
* @param {String} defaultCellStyleName
* @returns {OpenDocument.TableColumn}
*/
OpenDocument.Elements.TableColumn = function (styleName, columnsRepeated, defaultCellStyleName) {
this.styleName = styleName;
this.columnsRepeated = columnsRepeated;
if (defaultCellStyleName) {
this.defaultCellStyleName = defaultCellStyleName;
} else {
this.defaultCellStyleName = "Default";
}
};

View File

@ -0,0 +1,328 @@
/* 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[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 = col.dataset["odStyle"];
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;
};
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";
}
};

View File

@ -0,0 +1,255 @@
/* global OpenDocument */
/***********************************************************
*
* @constructor
* @param {String} type
* @param {String} styleName
* @returns {OpenDocument.Style}
*/
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;
}
var property = {
name: propertyName,
value: value
};
this.propertiesMaps.get(stylePropertyDef.category).set(propertyName, property);
};
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]);
}
}
};
/**
*
* @param {OpenDocument.XmlWriter} xmlWriter
* @returns {undefined}
*/
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;
}
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"
}
};
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;
};

View File

@ -0,0 +1,399 @@
/* global OpenDocument */
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.automaticStyleNumber = 1;
this.currencyMap = 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, currencyCode) {
var styleKey = type + ":";
if (type === "currency") {
styleKey += currencyCode + ":";
}
styleKey += parentStyleName;
if (this.hasStyle("cell-automatic", styleKey)) {
return this.getStyle("cell-automatic", styleKey).name;
}
var name = OpenDocument.CELLSTYLE_PREFIX + this.automaticStyleNumber;
this.automaticStyleNumber++;
var dataStyleName = null;
switch(type) {
case "date":
dataStyleName = OpenDocument.ISODATE_DATASTYLE_NAME;
break;
case "currency":
let number;
if (this.currencyMap.has(currencyCode)) {
number = this.currencyMap.get(currencyCode);
} else {
number = this.automaticStyleNumber;
this.automaticStyleNumber++;
this.currencyMap.set(currencyCode, number);
}
dataStyleName = OpenDocument.DATASTYLE_PREFIX + number;
break;
}
var cellStyle = new OpenDocument.Style("cell", name);
if (parentStyleName) {
cellStyle.setParent(parentStyleName);
} else {
cellStyle.setParent(OpenDocument.DEFAULT_CELLSTYLE_NAME);
}
if (dataStyleName) {
cellStyle.setDataStyle(dataStyleName);
}
this.putStyle("cell-automatic", cellStyle, styleKey);
return name;
};
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 "";
};
/**
*
* @param {OpenDocument.XmlWriter} xmlWriter
* @returns {undefined}
*/
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) {
xmlWriter
.addDateStyle();
for(let entry of this.currencyMap) {
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 '~':
__addMatchingClass(_parseClass(tokens[index +1]));
index ++;
break;
case '+':
__setParent(_parseClass(tokens[index +1]));
index ++;
break;
}
index ++;
}
}
function __addMatchingClass(matchingClass) {
if (!matchingClass) {
return;
}
let map = styleManager.matchingClassMaps.get(type);
if (map) {
map.set(matchingClass, style.styleName);
}
}
function __setParent(parentStyleName) {
if (!parentStyleName) {
return;
}
style.setParent(parentStyleName);
}
}
function _parseClass(classToken) {
if (!classToken.startsWith('.')) {
return false;
}
return classToken.substring(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"
}
}
];

View File

@ -0,0 +1,568 @@
/* global OpenDocument,Currency,XmlWriter */
/**
*
* @constructor
* @param {type} options
*/
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 () {
this
.startOpenTag("number:date-style")
.addAttribute("style:name", OpenDocument.ISODATE_DATASTYLE_NAME)
.endOpenTag()
.startOpenTag("number:year")
.addAttribute("number:style", "long")
.closeEmptyTag()
.addSimpleElement("number:text", "-")
.startOpenTag("number:month")
.addAttribute("number:style", "long")
.closeEmptyTag()
.addSimpleElement("number:text", "-")
.startOpenTag("number:day")
.addAttribute("number:style", "long")
.closeEmptyTag()
.closeTag("number:date-style");
return this;
};
OpenDocument.XmlWriter.prototype.addCurrencyStyle = function (currencyCode, number) {
var currency = Currency.get(currencyCode);
var dataStyleName = OpenDocument.DATASTYLE_PREFIX + number;
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;
};

View File

@ -0,0 +1,42 @@
/**
* Objet global définissant l'espace de nom OpenDocument
*
* @namespace OpenDocument
*/
var OpenDocument = {};
OpenDocument.DEFAULT_CELLSTYLE_NAME = "Default";
OpenDocument.ISODATE_DATASTYLE_NAME = "N101";
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.toChar = function (columnNumber) {
return (columnNumber + 64);
};

View File

@ -0,0 +1,191 @@
/**
*
* @constructor
* @param {type} options
*/
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('<?xml version="1.0" encoding="UTF-8"?>');
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("<![CDATA[");
var length = text.length;
var carac;
for (let i = 0; i < length; i++) {
carac = text.charAt(i);
if (carac === ']') {
if ((i < (length - 1)) && (text.charAt(i + 1) === ']')) {
this.write("]]>");
this.write("]]");
this.write("<![CDATA[");
i = i + 1;
} else {
this.write(']');
}
} else {
this.write(carac);
}
}
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("&amp;");
break;
case '"':
this.write("&quot;");
break;
case '<':
this.write("&lt;");
break;
case '>':
this.write("&gt;");
break;
case '\'':
this.write("&apos;");
break;
case '\u00A0':
this.write("&#x00A0;");
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;
};