Refactor column adding

This commit is contained in:
Martin Aspeli
2013-09-13 00:01:42 +01:00
parent cb8c0bd51d
commit 10c9ce27f7
+72 -52
View File
@@ -50,77 +50,94 @@ module.exports = (function() {
Workbook.prototype.substitute = function(sheet, substitutions) {
var self = this;
function getCurrentCell(currentCell, currentRow, col) {
if(currentCell === null) {
return self.joinRef({
row: currentRow,
col: self.splitRef(col.attrib.r).col
});
} else {
return self.nextCol(currentCell);
}
function getCurrentRow(row, rowsInserted) {
return parseInt(row.attrib.r, 10) + rowsInserted;
}
function getCurrentCell(cell, currentRow, cellsInserted) {
var ref = self.joinRef({
row: currentRow,
col: self.splitRef(cell.attrib.r).col
});
// TODO: optimise
// TODO: deal with negatives?
for(var i = 0; i < cellsInserted; ++i) {
ref = self.nextCol(ref);
}
return ref;
}
// Get sheet and parse XML tree
var file = WORKSHEETS + "sheet" + sheet + ".xml",
tree = etree.parse(self.archive.file(file).asText()),
root = tree.getroot();
// Loop over /worksheet/sheetData/row
var sheetData = root.find("sheetData"),
currentRow = null,
rowsInserted = 0,
rows = [];
sheetData.findall("row").forEach(function(row) {
// Update row@r (row reference) in case we have inserted additional rows.
row.attrib.r = currentRow = parseInt(row.attrib.r, 10) + rowsInserted;
rows.push(row);
var appendRow = true;
row.attrib.r = currentRow = getCurrentRow(row, rowsInserted);
// Loop over row/c (columns)
var cols = [],
var cells = [],
currentCell = null,
cellsInserted = 0;
row.findall("c").forEach(function(col) {
row.findall("c").forEach(function(cell) {
var appendCell = true;
cell.attrib.r = currentCell = getCurrentCell(cell, currentRow, cellsInserted);
// If c[@t="s"] (string column), look up /c/v@text as integer in
// If c[@t="s"] (string cellumn), look up /c/v@text as integer in
// `this.sharedStrings`
if(col.attrib.t === "s") {
var cellValue = col.find("v"),
if(cell.attrib.t === "s") {
var cellValue = cell.find("v"),
stringIndex = parseInt(cellValue.text, 10),
string = self.sharedStrings[stringIndex];
// Determine if we have a substitution
// Look for a shared string that may contain placeholders
if(string !== undefined) {
// Replace each placeholder
// Loop over placeholders
var placeholders = self.extractPlaceholders(string);
placeholders.forEach(function(placeholder) {
// Only substitute things for which we have a substition
var substitution = substitutions[placeholder.name];
if(substitution === undefined) {
return;
}
var substituted = self.substituteScalar(col, string, placeholder, substitution);
var substituted = self.substituteScalar(cell, string, placeholder, substitution);
if(substituted !== undefined) {
string = substituted; // in case we have multiple placeholders
} else if(placeholder.full && substitution instanceof Array) {
// A column or table substitution
// A table substitution (rows)
if(placeholder.type === "table") { // multiple rows
// TODO
} else if(placeholder.type === "normal") { // columns on this row
// A list substitution (columns)
} else if(placeholder.type === "normal") {
appendCell = false; // don't double-insert cells
--cellsInserted; // we technically delete one before we start adding back
substitution.forEach(function(substitutionElement, idx) {
// add a cell for each element in the list
substitution.forEach(function(substitutionElement) {
++cellsInserted;
var newCol = self.cloneElement(col);
if(cellsInserted > 0) {
currentCell = self.nextCol(currentCell);
}
var newCol = self.cloneElement(cell);
self.insertValue(newCol, substitutionElement);
newCol.attrib.r = currentCell = getCurrentCell(currentCell, currentRow, newCol);
cols.push(newCol);
newCol.attrib.r = currentCell;
cells.push(newCol);
});
}
}
@@ -130,20 +147,23 @@ module.exports = (function() {
// if we are inserting rows or columns, we may not want to keep the original cell anymore
if(appendCell) {
col.attrib.r = currentCell = getCurrentCell(currentCell, currentRow, col);
cols.push(col);
cells.push(cell);
}
});
// We may have inserted columns, so re-build the children of the row
self.replaceChildren(row, cols);
if(appendRow) {
rows.push(row);
// Update row spans attribute
if(cellsInserted !== 0 && row.attrib.spans) {
var rowSpan = row.attrib.spans.split(':').map(function(f) { return parseInt(f, 10); });
rowSpan[1] += cellsInserted;
row.attrib.spans = rowSpan.join(":");
// We may have inserted columns, so re-build the children of the row
self.replaceChildren(row, cells);
// Update row spans attribute
if(cellsInserted !== 0 && row.attrib.spans) {
var rowSpan = row.attrib.spans.split(':').map(function(f) { return parseInt(f, 10); });
rowSpan[1] += cellsInserted;
row.attrib.spans = rowSpan.join(":");
}
}
});
@@ -330,48 +350,48 @@ module.exports = (function() {
}
};
Workbook.prototype.insertCellValue = function(col, substitution) {
Workbook.prototype.insertCellValue = function(cell, substitution) {
var self = this;
var cellValue = col.find("v"),
var cellValue = cell.find("v"),
stringified = self.stringify(substitution);
if(typeof(substitution) === "number") {
col.attrib.t = "n";
cell.attrib.t = "n";
cellValue.text = stringified;
} else if(typeof(substitution) === "boolean" ) {
col.attrib.t = "b";
cell.attrib.t = "b";
cellValue.text = stringified;
} else if(substitution instanceof Date) {
col.attrib.t = "d";
cell.attrib.t = "d";
cellValue.text = stringified;
} else {
col.attrib.t = "s";
cell.attrib.t = "s";
cellValue.text = self.stringIndex(stringified);
}
};
Workbook.prototype.substituteScalar = function(col, string, placeholder, substitution) {
Workbook.prototype.substituteScalar = function(cell, string, placeholder, substitution) {
var self = this;
var cellValue = col.find("v"),
var cellValue = cell.find("v"),
stringified = self.stringify(substitution),
newString = stringified;
if(placeholder.full && typeof(substitution) === "number") {
col.attrib.t = "n";
cell.attrib.t = "n";
cellValue.text = stringified;
} else if(placeholder.full && typeof(substitution) === "boolean" ) {
col.attrib.t = "b";
cell.attrib.t = "b";
cellValue.text = stringified;
} else if(placeholder.full && substitution instanceof Date) {
col.attrib.t = "d";
cell.attrib.t = "d";
cellValue.text = stringified;
} else if(placeholder.full && typeof(substitution) === "string") {
col.attrib.t = "s";
cell.attrib.t = "s";
self.replaceString(string, stringified);
} else if(!placeholder.full) {
col.attrib.t = "s";
cell.attrib.t = "s";
newString = string.replace(placeholder.placeholder, stringified);
self.replaceString(string, newString);
} else {