worksheet-writer.js 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813
  1. "use strict";
  2. function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }
  3. function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
  4. function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
  5. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  6. function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
  7. function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
  8. var _ = require('../../utils/under-dash');
  9. var RelType = require('../../xlsx/rel-type');
  10. var colCache = require('../../utils/col-cache');
  11. var Encryptor = require('../../utils/encryptor');
  12. var Dimensions = require('../../doc/range');
  13. var StringBuf = require('../../utils/string-buf');
  14. var Row = require('../../doc/row');
  15. var Column = require('../../doc/column');
  16. var SheetRelsWriter = require('./sheet-rels-writer');
  17. var SheetCommentsWriter = require('./sheet-comments-writer');
  18. var DataValidations = require('../../doc/data-validations');
  19. var xmlBuffer = new StringBuf(); // ============================================================================================
  20. // Xforms
  21. var ListXform = require('../../xlsx/xform/list-xform');
  22. var DataValidationsXform = require('../../xlsx/xform/sheet/data-validations-xform');
  23. var SheetPropertiesXform = require('../../xlsx/xform/sheet/sheet-properties-xform');
  24. var SheetFormatPropertiesXform = require('../../xlsx/xform/sheet/sheet-format-properties-xform');
  25. var ColXform = require('../../xlsx/xform/sheet/col-xform');
  26. var RowXform = require('../../xlsx/xform/sheet/row-xform');
  27. var HyperlinkXform = require('../../xlsx/xform/sheet/hyperlink-xform');
  28. var SheetViewXform = require('../../xlsx/xform/sheet/sheet-view-xform');
  29. var SheetProtectionXform = require('../../xlsx/xform/sheet/sheet-protection-xform');
  30. var PageMarginsXform = require('../../xlsx/xform/sheet/page-margins-xform');
  31. var PageSetupXform = require('../../xlsx/xform/sheet/page-setup-xform');
  32. var AutoFilterXform = require('../../xlsx/xform/sheet/auto-filter-xform');
  33. var PictureXform = require('../../xlsx/xform/sheet/picture-xform');
  34. var ConditionalFormattingsXform = require('../../xlsx/xform/sheet/cf/conditional-formattings-xform');
  35. var HeaderFooterXform = require('../../xlsx/xform/sheet/header-footer-xform');
  36. var RowBreaksXform = require('../../xlsx/xform/sheet/row-breaks-xform'); // since prepare and render are functional, we can use singletons
  37. var xform = {
  38. dataValidations: new DataValidationsXform(),
  39. sheetProperties: new SheetPropertiesXform(),
  40. sheetFormatProperties: new SheetFormatPropertiesXform(),
  41. columns: new ListXform({
  42. tag: 'cols',
  43. length: false,
  44. childXform: new ColXform()
  45. }),
  46. row: new RowXform(),
  47. hyperlinks: new ListXform({
  48. tag: 'hyperlinks',
  49. length: false,
  50. childXform: new HyperlinkXform()
  51. }),
  52. sheetViews: new ListXform({
  53. tag: 'sheetViews',
  54. length: false,
  55. childXform: new SheetViewXform()
  56. }),
  57. sheetProtection: new SheetProtectionXform(),
  58. pageMargins: new PageMarginsXform(),
  59. pageSeteup: new PageSetupXform(),
  60. autoFilter: new AutoFilterXform(),
  61. picture: new PictureXform(),
  62. conditionalFormattings: new ConditionalFormattingsXform(),
  63. headerFooter: new HeaderFooterXform(),
  64. rowBreaks: new RowBreaksXform()
  65. }; // ============================================================================================
  66. var WorksheetWriter = /*#__PURE__*/function () {
  67. function WorksheetWriter(options) {
  68. _classCallCheck(this, WorksheetWriter);
  69. // in a workbook, each sheet will have a number
  70. this.id = options.id; // and a name
  71. this.name = options.name || "Sheet".concat(this.id); // add a state
  72. this.state = options.state || 'visible'; // rows are stored here while they need to be worked on.
  73. // when they are committed, they will be deleted.
  74. this._rows = []; // column definitions
  75. this._columns = null; // column keys (addRow convenience): key ==> this._columns index
  76. this._keys = {}; // keep a record of all row and column pageBreaks
  77. this._merges = [];
  78. this._merges.add = function () {}; // ignore cell instruction
  79. // keep record of all hyperlinks
  80. this._sheetRelsWriter = new SheetRelsWriter(options);
  81. this._sheetCommentsWriter = new SheetCommentsWriter(this, this._sheetRelsWriter, options); // keep a record of dimensions
  82. this._dimensions = new Dimensions(); // first uncommitted row
  83. this._rowZero = 1; // committed flag
  84. this.committed = false; // for data validations
  85. this.dataValidations = new DataValidations(); // for sharing formulae
  86. this._formulae = {};
  87. this._siFormulae = 0; // keep a record of conditionalFormattings
  88. this.conditionalFormatting = []; // keep a record of all row and column pageBreaks
  89. this.rowBreaks = []; // for default row height, outline levels, etc
  90. this.properties = Object.assign({}, {
  91. defaultRowHeight: 15,
  92. dyDescent: 55,
  93. outlineLevelCol: 0,
  94. outlineLevelRow: 0
  95. }, options.properties);
  96. this.headerFooter = Object.assign({}, {
  97. differentFirst: false,
  98. differentOddEven: false,
  99. oddHeader: null,
  100. oddFooter: null,
  101. evenHeader: null,
  102. evenFooter: null,
  103. firstHeader: null,
  104. firstFooter: null
  105. }, options.headerFooter); // for all things printing
  106. this.pageSetup = Object.assign({}, {
  107. margins: {
  108. left: 0.7,
  109. right: 0.7,
  110. top: 0.75,
  111. bottom: 0.75,
  112. header: 0.3,
  113. footer: 0.3
  114. },
  115. orientation: 'portrait',
  116. horizontalDpi: 4294967295,
  117. verticalDpi: 4294967295,
  118. fitToPage: !!(options.pageSetup && (options.pageSetup.fitToWidth || options.pageSetup.fitToHeight) && !options.pageSetup.scale),
  119. pageOrder: 'downThenOver',
  120. blackAndWhite: false,
  121. draft: false,
  122. cellComments: 'None',
  123. errors: 'displayed',
  124. scale: 100,
  125. fitToWidth: 1,
  126. fitToHeight: 1,
  127. paperSize: undefined,
  128. showRowColHeaders: false,
  129. showGridLines: false,
  130. horizontalCentered: false,
  131. verticalCentered: false,
  132. rowBreaks: null,
  133. colBreaks: null
  134. }, options.pageSetup); // using shared strings creates a smaller xlsx file but may use more memory
  135. this.useSharedStrings = options.useSharedStrings || false;
  136. this._workbook = options.workbook;
  137. this.hasComments = false; // views
  138. this._views = options.views || []; // auto filter
  139. this.autoFilter = options.autoFilter || null;
  140. this._media = []; // worksheet protection
  141. this.sheetProtection = null; // start writing to stream now
  142. this._writeOpenWorksheet();
  143. this.startedData = false;
  144. }
  145. _createClass(WorksheetWriter, [{
  146. key: "destroy",
  147. // destroy - not a valid operation for a streaming writer
  148. // even though some streamers might be able to, it's a bad idea.
  149. value: function destroy() {
  150. throw new Error('Invalid Operation: destroy');
  151. }
  152. }, {
  153. key: "commit",
  154. value: function commit() {
  155. var _this = this;
  156. if (this.committed) {
  157. return;
  158. } // commit all rows
  159. this._rows.forEach(function (cRow) {
  160. if (cRow) {
  161. // write the row to the stream
  162. _this._writeRow(cRow);
  163. }
  164. }); // we _cannot_ accept new rows from now on
  165. this._rows = null;
  166. if (!this.startedData) {
  167. this._writeOpenSheetData();
  168. }
  169. this._writeCloseSheetData();
  170. this._writeAutoFilter();
  171. this._writeMergeCells(); // for some reason, Excel can't handle dimensions at the bottom of the file
  172. // this._writeDimensions();
  173. this._writeHyperlinks();
  174. this._writeConditionalFormatting();
  175. this._writeDataValidations();
  176. this._writeSheetProtection();
  177. this._writePageMargins();
  178. this._writePageSetup();
  179. this._writeBackground();
  180. this._writeHeaderFooter();
  181. this._writeRowBreaks(); // Legacy Data tag for comments
  182. this._writeLegacyData();
  183. this._writeCloseWorksheet(); // signal end of stream to workbook
  184. this.stream.end();
  185. this._sheetCommentsWriter.commit(); // also commit the hyperlinks if any
  186. this._sheetRelsWriter.commit();
  187. this.committed = true;
  188. } // return the current dimensions of the writer
  189. }, {
  190. key: "getColumnKey",
  191. value: function getColumnKey(key) {
  192. return this._keys[key];
  193. }
  194. }, {
  195. key: "setColumnKey",
  196. value: function setColumnKey(key, value) {
  197. this._keys[key] = value;
  198. }
  199. }, {
  200. key: "deleteColumnKey",
  201. value: function deleteColumnKey(key) {
  202. delete this._keys[key];
  203. }
  204. }, {
  205. key: "eachColumnKey",
  206. value: function eachColumnKey(f) {
  207. _.each(this._keys, f);
  208. } // get a single column by col number. If it doesn't exist, it and any gaps before it
  209. // are created.
  210. }, {
  211. key: "getColumn",
  212. value: function getColumn(c) {
  213. if (typeof c === 'string') {
  214. // if it matches a key'd column, return that
  215. var col = this._keys[c];
  216. if (col) return col; // otherwise, assume letter
  217. c = colCache.l2n(c);
  218. }
  219. if (!this._columns) {
  220. this._columns = [];
  221. }
  222. if (c > this._columns.length) {
  223. var n = this._columns.length + 1;
  224. while (n <= c) {
  225. this._columns.push(new Column(this, n++));
  226. }
  227. }
  228. return this._columns[c - 1];
  229. } // =========================================================================
  230. // Rows
  231. }, {
  232. key: "eachRow",
  233. // iterate over every uncommitted row in the worksheet, including maybe empty rows
  234. value: function eachRow(options, iteratee) {
  235. if (!iteratee) {
  236. iteratee = options;
  237. options = undefined;
  238. }
  239. if (options && options.includeEmpty) {
  240. var n = this._nextRow;
  241. for (var i = this._rowZero; i < n; i++) {
  242. iteratee(this.getRow(i), i);
  243. }
  244. } else {
  245. this._rows.forEach(function (row) {
  246. if (row.hasValues) {
  247. iteratee(row, row.number);
  248. }
  249. });
  250. }
  251. }
  252. }, {
  253. key: "_commitRow",
  254. value: function _commitRow(cRow) {
  255. // since rows must be written in order, we commit all rows up till and including cRow
  256. var found = false;
  257. while (this._rows.length && !found) {
  258. var row = this._rows.shift();
  259. this._rowZero++;
  260. if (row) {
  261. this._writeRow(row);
  262. found = row.number === cRow.number;
  263. this._rowZero = row.number + 1;
  264. }
  265. }
  266. }
  267. }, {
  268. key: "findRow",
  269. // find a row (if exists) by row number
  270. value: function findRow(rowNumber) {
  271. var index = rowNumber - this._rowZero;
  272. return this._rows[index];
  273. }
  274. }, {
  275. key: "getRow",
  276. value: function getRow(rowNumber) {
  277. var index = rowNumber - this._rowZero; // may fail if rows have been comitted
  278. if (index < 0) {
  279. throw new Error('Out of bounds: this row has been committed');
  280. }
  281. var row = this._rows[index];
  282. if (!row) {
  283. this._rows[index] = row = new Row(this, rowNumber);
  284. }
  285. return row;
  286. }
  287. }, {
  288. key: "addRow",
  289. value: function addRow(value) {
  290. var row = new Row(this, this._nextRow);
  291. this._rows[row.number - this._rowZero] = row;
  292. row.values = value;
  293. return row;
  294. } // ================================================================================
  295. // Cells
  296. // returns the cell at [r,c] or address given by r. If not found, return undefined
  297. }, {
  298. key: "findCell",
  299. value: function findCell(r, c) {
  300. var address = colCache.getAddress(r, c);
  301. var row = this.findRow(address.row);
  302. return row ? row.findCell(address.column) : undefined;
  303. } // return the cell at [r,c] or address given by r. If not found, create a new one.
  304. }, {
  305. key: "getCell",
  306. value: function getCell(r, c) {
  307. var address = colCache.getAddress(r, c);
  308. var row = this.getRow(address.row);
  309. return row.getCellEx(address);
  310. }
  311. }, {
  312. key: "mergeCells",
  313. value: function mergeCells() {
  314. for (var _len = arguments.length, cells = new Array(_len), _key = 0; _key < _len; _key++) {
  315. cells[_key] = arguments[_key];
  316. }
  317. // may fail if rows have been comitted
  318. var dimensions = new Dimensions(cells); // check cells aren't already merged
  319. this._merges.forEach(function (merge) {
  320. if (merge.intersects(dimensions)) {
  321. throw new Error('Cannot merge already merged cells');
  322. }
  323. }); // apply merge
  324. var master = this.getCell(dimensions.top, dimensions.left);
  325. for (var i = dimensions.top; i <= dimensions.bottom; i++) {
  326. for (var j = dimensions.left; j <= dimensions.right; j++) {
  327. if (i > dimensions.top || j > dimensions.left) {
  328. this.getCell(i, j).merge(master);
  329. }
  330. }
  331. } // index merge
  332. this._merges.push(dimensions);
  333. } // ===========================================================================
  334. // Conditional Formatting
  335. }, {
  336. key: "addConditionalFormatting",
  337. value: function addConditionalFormatting(cf) {
  338. this.conditionalFormatting.push(cf);
  339. }
  340. }, {
  341. key: "removeConditionalFormatting",
  342. value: function removeConditionalFormatting(filter) {
  343. if (typeof filter === 'number') {
  344. this.conditionalFormatting.splice(filter, 1);
  345. } else if (filter instanceof Function) {
  346. this.conditionalFormatting = this.conditionalFormatting.filter(filter);
  347. } else {
  348. this.conditionalFormatting = [];
  349. }
  350. } // =========================================================================
  351. }, {
  352. key: "addBackgroundImage",
  353. value: function addBackgroundImage(imageId) {
  354. this._background = {
  355. imageId: imageId
  356. };
  357. }
  358. }, {
  359. key: "getBackgroundImageId",
  360. value: function getBackgroundImageId() {
  361. return this._background && this._background.imageId;
  362. } // =========================================================================
  363. // Worksheet Protection
  364. }, {
  365. key: "protect",
  366. value: function protect(password, options) {
  367. var _this2 = this;
  368. // TODO: make this function truly async
  369. // perhaps marshal to worker thread or something
  370. return new Promise(function (resolve) {
  371. _this2.sheetProtection = {
  372. sheet: true
  373. };
  374. if (options && 'spinCount' in options) {
  375. // force spinCount to be integer >= 0
  376. options.spinCount = Number.isFinite(options.spinCount) ? Math.round(Math.max(0, options.spinCount)) : 100000;
  377. }
  378. if (password) {
  379. _this2.sheetProtection.algorithmName = 'SHA-512';
  380. _this2.sheetProtection.saltValue = Encryptor.randomBytes(16).toString('base64');
  381. _this2.sheetProtection.spinCount = options && 'spinCount' in options ? options.spinCount : 100000; // allow user specified spinCount
  382. _this2.sheetProtection.hashValue = Encryptor.convertPasswordToHash(password, 'SHA512', _this2.sheetProtection.saltValue, _this2.sheetProtection.spinCount);
  383. }
  384. if (options) {
  385. _this2.sheetProtection = Object.assign(_this2.sheetProtection, options);
  386. if (!password && 'spinCount' in options) {
  387. delete _this2.sheetProtection.spinCount;
  388. }
  389. }
  390. resolve();
  391. });
  392. }
  393. }, {
  394. key: "unprotect",
  395. value: function unprotect() {
  396. this.sheetProtection = null;
  397. } // ================================================================================
  398. }, {
  399. key: "_write",
  400. value: function _write(text) {
  401. xmlBuffer.reset();
  402. xmlBuffer.addText(text);
  403. this.stream.write(xmlBuffer);
  404. }
  405. }, {
  406. key: "_writeSheetProperties",
  407. value: function _writeSheetProperties(xmlBuf, properties, pageSetup) {
  408. var sheetPropertiesModel = {
  409. outlineProperties: properties && properties.outlineProperties,
  410. tabColor: properties && properties.tabColor,
  411. pageSetup: pageSetup && pageSetup.fitToPage ? {
  412. fitToPage: pageSetup.fitToPage
  413. } : undefined
  414. };
  415. xmlBuf.addText(xform.sheetProperties.toXml(sheetPropertiesModel));
  416. }
  417. }, {
  418. key: "_writeSheetFormatProperties",
  419. value: function _writeSheetFormatProperties(xmlBuf, properties) {
  420. var sheetFormatPropertiesModel = properties ? {
  421. defaultRowHeight: properties.defaultRowHeight,
  422. dyDescent: properties.dyDescent,
  423. outlineLevelCol: properties.outlineLevelCol,
  424. outlineLevelRow: properties.outlineLevelRow
  425. } : undefined;
  426. if (properties.defaultColWidth) {
  427. sheetFormatPropertiesModel.defaultColWidth = properties.defaultColWidth;
  428. }
  429. xmlBuf.addText(xform.sheetFormatProperties.toXml(sheetFormatPropertiesModel));
  430. }
  431. }, {
  432. key: "_writeOpenWorksheet",
  433. value: function _writeOpenWorksheet() {
  434. xmlBuffer.reset();
  435. xmlBuffer.addText('<?xml version="1.0" encoding="UTF-8" standalone="yes"?>');
  436. xmlBuffer.addText('<worksheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main"' + ' xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships"' + ' xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"' + ' mc:Ignorable="x14ac"' + ' xmlns:x14ac="http://schemas.microsoft.com/office/spreadsheetml/2009/9/ac">');
  437. this._writeSheetProperties(xmlBuffer, this.properties, this.pageSetup);
  438. xmlBuffer.addText(xform.sheetViews.toXml(this.views));
  439. this._writeSheetFormatProperties(xmlBuffer, this.properties);
  440. this.stream.write(xmlBuffer);
  441. }
  442. }, {
  443. key: "_writeColumns",
  444. value: function _writeColumns() {
  445. var cols = Column.toModel(this.columns);
  446. if (cols) {
  447. xform.columns.prepare(cols, {
  448. styles: this._workbook.styles
  449. });
  450. this.stream.write(xform.columns.toXml(cols));
  451. }
  452. }
  453. }, {
  454. key: "_writeOpenSheetData",
  455. value: function _writeOpenSheetData() {
  456. this._write('<sheetData>');
  457. }
  458. }, {
  459. key: "_writeRow",
  460. value: function _writeRow(row) {
  461. if (!this.startedData) {
  462. this._writeColumns();
  463. this._writeOpenSheetData();
  464. this.startedData = true;
  465. }
  466. if (row.hasValues || row.height) {
  467. var model = row.model;
  468. var options = {
  469. styles: this._workbook.styles,
  470. sharedStrings: this.useSharedStrings ? this._workbook.sharedStrings : undefined,
  471. hyperlinks: this._sheetRelsWriter.hyperlinksProxy,
  472. merges: this._merges,
  473. formulae: this._formulae,
  474. siFormulae: this._siFormulae,
  475. comments: []
  476. };
  477. xform.row.prepare(model, options);
  478. this.stream.write(xform.row.toXml(model));
  479. if (options.comments.length) {
  480. this.hasComments = true;
  481. this._sheetCommentsWriter.addComments(options.comments);
  482. }
  483. }
  484. }
  485. }, {
  486. key: "_writeCloseSheetData",
  487. value: function _writeCloseSheetData() {
  488. this._write('</sheetData>');
  489. }
  490. }, {
  491. key: "_writeMergeCells",
  492. value: function _writeMergeCells() {
  493. if (this._merges.length) {
  494. xmlBuffer.reset();
  495. xmlBuffer.addText("<mergeCells count=\"".concat(this._merges.length, "\">"));
  496. this._merges.forEach(function (merge) {
  497. xmlBuffer.addText("<mergeCell ref=\"".concat(merge, "\"/>"));
  498. });
  499. xmlBuffer.addText('</mergeCells>');
  500. this.stream.write(xmlBuffer);
  501. }
  502. }
  503. }, {
  504. key: "_writeHyperlinks",
  505. value: function _writeHyperlinks() {
  506. // eslint-disable-next-line no-underscore-dangle
  507. this.stream.write(xform.hyperlinks.toXml(this._sheetRelsWriter._hyperlinks));
  508. }
  509. }, {
  510. key: "_writeConditionalFormatting",
  511. value: function _writeConditionalFormatting() {
  512. var options = {
  513. styles: this._workbook.styles
  514. };
  515. xform.conditionalFormattings.prepare(this.conditionalFormatting, options);
  516. this.stream.write(xform.conditionalFormattings.toXml(this.conditionalFormatting));
  517. }
  518. }, {
  519. key: "_writeRowBreaks",
  520. value: function _writeRowBreaks() {
  521. this.stream.write(xform.rowBreaks.toXml(this.rowBreaks));
  522. }
  523. }, {
  524. key: "_writeDataValidations",
  525. value: function _writeDataValidations() {
  526. this.stream.write(xform.dataValidations.toXml(this.dataValidations.model));
  527. }
  528. }, {
  529. key: "_writeSheetProtection",
  530. value: function _writeSheetProtection() {
  531. this.stream.write(xform.sheetProtection.toXml(this.sheetProtection));
  532. }
  533. }, {
  534. key: "_writePageMargins",
  535. value: function _writePageMargins() {
  536. this.stream.write(xform.pageMargins.toXml(this.pageSetup.margins));
  537. }
  538. }, {
  539. key: "_writePageSetup",
  540. value: function _writePageSetup() {
  541. this.stream.write(xform.pageSeteup.toXml(this.pageSetup));
  542. }
  543. }, {
  544. key: "_writeHeaderFooter",
  545. value: function _writeHeaderFooter() {
  546. this.stream.write(xform.headerFooter.toXml(this.headerFooter));
  547. }
  548. }, {
  549. key: "_writeAutoFilter",
  550. value: function _writeAutoFilter() {
  551. this.stream.write(xform.autoFilter.toXml(this.autoFilter));
  552. }
  553. }, {
  554. key: "_writeBackground",
  555. value: function _writeBackground() {
  556. if (this._background) {
  557. if (this._background.imageId !== undefined) {
  558. var image = this._workbook.getImage(this._background.imageId);
  559. var pictureId = this._sheetRelsWriter.addMedia({
  560. Target: "../media/".concat(image.name),
  561. Type: RelType.Image
  562. });
  563. this._background = _objectSpread(_objectSpread({}, this._background), {}, {
  564. rId: pictureId
  565. });
  566. }
  567. this.stream.write(xform.picture.toXml({
  568. rId: this._background.rId
  569. }));
  570. }
  571. }
  572. }, {
  573. key: "_writeLegacyData",
  574. value: function _writeLegacyData() {
  575. if (this.hasComments) {
  576. xmlBuffer.reset();
  577. xmlBuffer.addText("<legacyDrawing r:id=\"".concat(this._sheetCommentsWriter.vmlRelId, "\"/>"));
  578. this.stream.write(xmlBuffer);
  579. }
  580. }
  581. }, {
  582. key: "_writeDimensions",
  583. value: function _writeDimensions() {// for some reason, Excel can't handle dimensions at the bottom of the file
  584. // and we don't know the dimensions until the commit, so don't write them.
  585. // this._write('<dimension ref="' + this._dimensions + '"/>');
  586. }
  587. }, {
  588. key: "_writeCloseWorksheet",
  589. value: function _writeCloseWorksheet() {
  590. this._write('</worksheet>');
  591. }
  592. }, {
  593. key: "workbook",
  594. get: function get() {
  595. return this._workbook;
  596. }
  597. }, {
  598. key: "stream",
  599. get: function get() {
  600. if (!this._stream) {
  601. // eslint-disable-next-line no-underscore-dangle
  602. this._stream = this._workbook._openStream("/xl/worksheets/sheet".concat(this.id, ".xml")); // pause stream to prevent 'data' events
  603. this._stream.pause();
  604. }
  605. return this._stream;
  606. }
  607. }, {
  608. key: "dimensions",
  609. get: function get() {
  610. return this._dimensions;
  611. }
  612. }, {
  613. key: "views",
  614. get: function get() {
  615. return this._views;
  616. } // =========================================================================
  617. // Columns
  618. // get the current columns array.
  619. }, {
  620. key: "columns",
  621. get: function get() {
  622. return this._columns;
  623. } // set the columns from an array of column definitions.
  624. // Note: any headers defined will overwrite existing values.
  625. ,
  626. set: function set(value) {
  627. var _this3 = this;
  628. // calculate max header row count
  629. this._headerRowCount = value.reduce(function (pv, cv) {
  630. var headerCount = cv.header && 1 || cv.headers && cv.headers.length || 0;
  631. return Math.max(pv, headerCount);
  632. }, 0); // construct Column objects
  633. var count = 1;
  634. var columns = this._columns = [];
  635. value.forEach(function (defn) {
  636. var column = new Column(_this3, count++, false);
  637. columns.push(column);
  638. column.defn = defn;
  639. });
  640. }
  641. }, {
  642. key: "_nextRow",
  643. get: function get() {
  644. return this._rowZero + this._rows.length;
  645. }
  646. }, {
  647. key: "lastRow",
  648. get: function get() {
  649. // returns last uncommitted row
  650. if (this._rows.length) {
  651. return this._rows[this._rows.length - 1];
  652. }
  653. return undefined;
  654. }
  655. }]);
  656. return WorksheetWriter;
  657. }();
  658. module.exports = WorksheetWriter;
  659. //# sourceMappingURL=worksheet-writer.js.map