sheet-rels-writer.js 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. /* eslint-disable max-classes-per-file */
  2. const utils = require('../../utils/utils');
  3. const RelType = require('../../xlsx/rel-type');
  4. class HyperlinksProxy {
  5. constructor(sheetRelsWriter) {
  6. this.writer = sheetRelsWriter;
  7. }
  8. push(hyperlink) {
  9. this.writer.addHyperlink(hyperlink);
  10. }
  11. }
  12. class SheetRelsWriter {
  13. constructor(options) {
  14. // in a workbook, each sheet will have a number
  15. this.id = options.id;
  16. // count of all relationships
  17. this.count = 0;
  18. // keep record of all hyperlinks
  19. this._hyperlinks = [];
  20. this._workbook = options.workbook;
  21. }
  22. get stream() {
  23. if (!this._stream) {
  24. // eslint-disable-next-line no-underscore-dangle
  25. this._stream = this._workbook._openStream(`/xl/worksheets/_rels/sheet${this.id}.xml.rels`);
  26. }
  27. return this._stream;
  28. }
  29. get length() {
  30. return this._hyperlinks.length;
  31. }
  32. each(fn) {
  33. return this._hyperlinks.forEach(fn);
  34. }
  35. get hyperlinksProxy() {
  36. return this._hyperlinksProxy || (this._hyperlinksProxy = new HyperlinksProxy(this));
  37. }
  38. addHyperlink(hyperlink) {
  39. // Write to stream
  40. const relationship = {
  41. Target: hyperlink.target,
  42. Type: RelType.Hyperlink,
  43. TargetMode: 'External',
  44. };
  45. const rId = this._writeRelationship(relationship);
  46. // store sheet stuff for later
  47. this._hyperlinks.push({
  48. rId,
  49. address: hyperlink.address,
  50. });
  51. }
  52. addMedia(media) {
  53. return this._writeRelationship(media);
  54. }
  55. addRelationship(rel) {
  56. return this._writeRelationship(rel);
  57. }
  58. commit() {
  59. if (this.count) {
  60. // write xml utro
  61. this._writeClose();
  62. // and close stream
  63. this.stream.end();
  64. }
  65. }
  66. // ================================================================================
  67. _writeOpen() {
  68. this.stream.write(
  69. `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
  70. <Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">`
  71. );
  72. }
  73. _writeRelationship(relationship) {
  74. if (!this.count) {
  75. this._writeOpen();
  76. }
  77. const rId = `rId${++this.count}`;
  78. if (relationship.TargetMode) {
  79. this.stream.write(
  80. `<Relationship Id="${rId}"` +
  81. ` Type="${relationship.Type}"` +
  82. ` Target="${utils.xmlEncode(relationship.Target)}"` +
  83. ` TargetMode="${relationship.TargetMode}"` +
  84. '/>'
  85. );
  86. } else {
  87. this.stream.write(
  88. `<Relationship Id="${rId}" Type="${relationship.Type}" Target="${relationship.Target}"/>`
  89. );
  90. }
  91. return rId;
  92. }
  93. _writeClose() {
  94. this.stream.write('</Relationships>');
  95. }
  96. }
  97. module.exports = SheetRelsWriter;