mirror of
https://github.com/optilude/xlsx-template.git
synced 2026-07-02 08:27:39 +08:00
Sketch of col insert functionality
This commit is contained in:
+85
-41
@@ -50,6 +50,17 @@ 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);
|
||||
}
|
||||
}
|
||||
|
||||
// Get sheet and parse XML tree
|
||||
var file = WORKSHEETS + "sheet" + sheet + ".xml",
|
||||
tree = etree.parse(self.archive.file(file).asText()),
|
||||
@@ -57,40 +68,24 @@ module.exports = (function() {
|
||||
|
||||
// Loop over /worksheet/sheetData/row
|
||||
var sheetData = root.find("sheetData"),
|
||||
currentRow = null,
|
||||
rowsInserted = 0,
|
||||
rows = [];
|
||||
sheetData.findall("row").forEach(function(row, rowIndex) {
|
||||
rows.push(row);
|
||||
|
||||
sheetData.findall("row").forEach(function(row) {
|
||||
|
||||
// Update row@r (row reference) in case we have inserted additional rows.
|
||||
var currentRow = parseInt(row.attrib.r, 10) + rowsInserted;
|
||||
|
||||
// Update row@r (row reference) if we have inserted additional rows.
|
||||
if(rowsInserted > 0) {
|
||||
row.attrib.r = currentRow;
|
||||
}
|
||||
row.attrib.r = currentRow;
|
||||
rows.push(row);
|
||||
|
||||
// Loop over row/c (columns)
|
||||
var cols = [],
|
||||
currentCell = null,
|
||||
cellsInserted = 0;
|
||||
|
||||
row.findall("c").forEach(function(col, colIndex) {
|
||||
cols.push(col);
|
||||
|
||||
// Update col@r (col reference) based on current row and cell.
|
||||
// This is necessary because we may clone rows and columns.
|
||||
if(currentCell === null) {
|
||||
currentCell = self.joinRef({
|
||||
row: currentRow,
|
||||
col: self.splitRef(col.attrib.r).col
|
||||
});
|
||||
} else {
|
||||
currentCell = self.nextCol(currentCell);
|
||||
}
|
||||
|
||||
if(col.attrib.r != currentCell) {
|
||||
col.attrib.r = currentCell;
|
||||
}
|
||||
row.findall("c").forEach(function(col) {
|
||||
var appendCell = true;
|
||||
|
||||
// If c[@t="s"] (string column), look up /c/v@text as integer in
|
||||
// `this.sharedStrings`
|
||||
@@ -105,37 +100,48 @@ module.exports = (function() {
|
||||
// Replace each placeholder
|
||||
var placeholders = self.extractPlaceholders(string);
|
||||
placeholders.forEach(function(placeholder) {
|
||||
|
||||
var substitution = substitutions[placeholder.name];
|
||||
if(substitution === undefined) {
|
||||
return;
|
||||
}
|
||||
|
||||
var substituted = self.substituteScalar(col, string, placeholder, substitution);
|
||||
if(substituted !== undefined && placeholder.full && substitution instanceof Array) {
|
||||
if(substituted !== undefined) {
|
||||
string = substituted; // in case we have multiple placeholders
|
||||
} else if(placeholder.full && substitution instanceof Array) {
|
||||
// A column or table substitution
|
||||
if(placeholder.type === "table") {
|
||||
if(placeholder.type === "table") { // multiple rows
|
||||
// TODO
|
||||
} else if(placeholder.type === "normal") {
|
||||
if(substitution.length === 0) {
|
||||
|
||||
} else {
|
||||
|
||||
}
|
||||
} else if(placeholder.type === "normal") { // columns on this row
|
||||
appendCell = false; // don't double-insert cells
|
||||
--cellsInserted; // we technically delete one before we start adding back
|
||||
substitution.forEach(function(substitutionElement, idx) {
|
||||
++cellsInserted;
|
||||
var newCol = self.cloneElement(col);
|
||||
self.insertValue(newCol, substitutionElement);
|
||||
newCol.attrib.r = currentCell = getCurrentCell(currentCell, currentRow, newCol);
|
||||
cols.push(newCol);
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
// We may have inserted columns, so re-build the children of the row
|
||||
row.delSlice(0, row.len());
|
||||
cols.forEach(function(col) {
|
||||
row.append(col);
|
||||
});
|
||||
self.replaceChildren(row, cols);
|
||||
|
||||
// Update row spans attribute
|
||||
if(cellsInserted > 0 && row.attrib.spans) {
|
||||
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(":");
|
||||
@@ -144,10 +150,7 @@ module.exports = (function() {
|
||||
});
|
||||
|
||||
// We may have inserted rows, so re-build the children of the sheetData
|
||||
sheetData.delSlice(0, sheetData.len());
|
||||
rows.forEach(function(row) {
|
||||
sheetData.append(row);
|
||||
});
|
||||
self.replaceChildren(sheetData, rows);
|
||||
|
||||
// TODO: Update <mergeCells />
|
||||
|
||||
@@ -328,6 +331,27 @@ module.exports = (function() {
|
||||
}
|
||||
};
|
||||
|
||||
Workbook.prototype.insertCellValue = function(col, substitution) {
|
||||
var self = this;
|
||||
|
||||
var cellValue = col.find("v"),
|
||||
stringified = self.stringify(substitution);
|
||||
|
||||
if(typeof(substitution) === "number") {
|
||||
col.attrib.t = "n";
|
||||
cellValue.text = stringified;
|
||||
} else if(typeof(substitution) === "boolean" ) {
|
||||
col.attrib.t = "b";
|
||||
cellValue.text = stringified;
|
||||
} else if(substitution instanceof Date) {
|
||||
col.attrib.t = "d";
|
||||
cellValue.text = stringified;
|
||||
} else {
|
||||
col.attrib.t = "s";
|
||||
cellValue.text = self.stringIndex(stringified);
|
||||
}
|
||||
};
|
||||
|
||||
Workbook.prototype.substituteScalar = function(col, string, placeholder, substitution) {
|
||||
var self = this;
|
||||
|
||||
@@ -358,5 +382,25 @@ module.exports = (function() {
|
||||
return newString;
|
||||
};
|
||||
|
||||
|
||||
Workbook.prototype.cloneElement = function(element) {
|
||||
var self = this;
|
||||
|
||||
var newElement = etree.Element(element.tag, element.attrib);
|
||||
newElement.text = element.text;
|
||||
newElement.tail = element.tail;
|
||||
newElement.getchildren().forEach(function(child) {
|
||||
newElement.append(self.cloneElement(child));
|
||||
});
|
||||
return newElement;
|
||||
};
|
||||
|
||||
Workbook.prototype.replaceChildren = function(parent, children) {
|
||||
parent.delSlice(0, parent.len());
|
||||
children.forEach(function(child) {
|
||||
parent.append(child);
|
||||
});
|
||||
};
|
||||
|
||||
return Workbook;
|
||||
})();
|
||||
Reference in New Issue
Block a user