mirror of
https://github.com/optilude/xlsx-template.git
synced 2026-07-02 08:27:39 +08:00
Refactor column adding
This commit is contained in:
+72
-52
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user