row-xform.js 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. const BaseXform = require('../base-xform');
  2. const utils = require('../../../utils/utils');
  3. const CellXform = require('./cell-xform');
  4. class RowXform extends BaseXform {
  5. constructor(options) {
  6. super();
  7. this.maxItems = options && options.maxItems;
  8. this.map = {
  9. c: new CellXform(),
  10. };
  11. }
  12. get tag() {
  13. return 'row';
  14. }
  15. prepare(model, options) {
  16. const styleId = options.styles.addStyleModel(model.style);
  17. if (styleId) {
  18. model.styleId = styleId;
  19. }
  20. const cellXform = this.map.c;
  21. model.cells.forEach(cellModel => {
  22. cellXform.prepare(cellModel, options);
  23. });
  24. }
  25. render(xmlStream, model, options) {
  26. xmlStream.openNode('row');
  27. xmlStream.addAttribute('r', model.number);
  28. if (model.height) {
  29. xmlStream.addAttribute('ht', model.height);
  30. xmlStream.addAttribute('customHeight', '1');
  31. }
  32. if (model.hidden) {
  33. xmlStream.addAttribute('hidden', '1');
  34. }
  35. if (model.min > 0 && model.max > 0 && model.min <= model.max) {
  36. xmlStream.addAttribute('spans', `${model.min}:${model.max}`);
  37. }
  38. if (model.styleId) {
  39. xmlStream.addAttribute('s', model.styleId);
  40. xmlStream.addAttribute('customFormat', '1');
  41. }
  42. xmlStream.addAttribute('x14ac:dyDescent', '0.25');
  43. if (model.outlineLevel) {
  44. xmlStream.addAttribute('outlineLevel', model.outlineLevel);
  45. }
  46. if (model.collapsed) {
  47. xmlStream.addAttribute('collapsed', '1');
  48. }
  49. const cellXform = this.map.c;
  50. model.cells.forEach(cellModel => {
  51. cellXform.render(xmlStream, cellModel, options);
  52. });
  53. xmlStream.closeNode();
  54. }
  55. parseOpen(node) {
  56. if (this.parser) {
  57. this.parser.parseOpen(node);
  58. return true;
  59. }
  60. if (node.name === 'row') {
  61. this.numRowsSeen += 1;
  62. const spans = node.attributes.spans
  63. ? node.attributes.spans.split(':').map(span => parseInt(span, 10))
  64. : [undefined, undefined];
  65. const model = (this.model = {
  66. number: parseInt(node.attributes.r, 10),
  67. min: spans[0],
  68. max: spans[1],
  69. cells: [],
  70. });
  71. if (node.attributes.s) {
  72. model.styleId = parseInt(node.attributes.s, 10);
  73. }
  74. if (utils.parseBoolean(node.attributes.hidden)) {
  75. model.hidden = true;
  76. }
  77. if (utils.parseBoolean(node.attributes.bestFit)) {
  78. model.bestFit = true;
  79. }
  80. if (node.attributes.ht) {
  81. model.height = parseFloat(node.attributes.ht);
  82. }
  83. if (node.attributes.outlineLevel) {
  84. model.outlineLevel = parseInt(node.attributes.outlineLevel, 10);
  85. }
  86. if (utils.parseBoolean(node.attributes.collapsed)) {
  87. model.collapsed = true;
  88. }
  89. return true;
  90. }
  91. this.parser = this.map[node.name];
  92. if (this.parser) {
  93. this.parser.parseOpen(node);
  94. return true;
  95. }
  96. return false;
  97. }
  98. parseText(text) {
  99. if (this.parser) {
  100. this.parser.parseText(text);
  101. }
  102. }
  103. parseClose(name) {
  104. if (this.parser) {
  105. if (!this.parser.parseClose(name)) {
  106. this.model.cells.push(this.parser.model);
  107. if (this.maxItems && this.model.cells.length > this.maxItems) {
  108. throw new Error(`Max column count (${this.maxItems}) exceeded`);
  109. }
  110. this.parser = undefined;
  111. }
  112. return true;
  113. }
  114. return false;
  115. }
  116. reconcile(model, options) {
  117. model.style = model.styleId ? options.styles.getStyleModel(model.styleId) : {};
  118. if (model.styleId !== undefined) {
  119. model.styleId = undefined;
  120. }
  121. const cellXform = this.map.c;
  122. model.cells.forEach(cellModel => {
  123. cellXform.reconcile(cellModel, options);
  124. });
  125. }
  126. }
  127. module.exports = RowXform;