@alienkarma/exceljs 4.4.0-fork.12 → 4.4.0-fork.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (536) hide show
  1. package/LICENSE +22 -22
  2. package/README.md +3024 -3024
  3. package/README_zh.md +2878 -2878
  4. package/excel.js +13 -13
  5. package/index.d.ts +2040 -2040
  6. package/lib/csv/csv.js +191 -191
  7. package/lib/csv/line-buffer.js +74 -74
  8. package/lib/csv/stream-converter.js +135 -135
  9. package/lib/doc/anchor.js +91 -91
  10. package/lib/doc/cell.js +1124 -1124
  11. package/lib/doc/column.js +320 -320
  12. package/lib/doc/data/theme1.json +234 -234
  13. package/lib/doc/data-validations.js +19 -19
  14. package/lib/doc/defined-names.js +196 -196
  15. package/lib/doc/enums.js +48 -48
  16. package/lib/doc/image.js +59 -59
  17. package/lib/doc/modelcontainer.js +18 -18
  18. package/lib/doc/note.js +65 -65
  19. package/lib/doc/pivot-table.js +132 -132
  20. package/lib/doc/range.js +257 -257
  21. package/lib/doc/row.js +415 -415
  22. package/lib/doc/table.js +465 -465
  23. package/lib/doc/workbook.js +224 -224
  24. package/lib/doc/worksheet.js +949 -949
  25. package/lib/exceljs.bare.js +13 -13
  26. package/lib/exceljs.browser.js +36 -36
  27. package/lib/exceljs.nodejs.js +14 -14
  28. package/lib/stream/xlsx/hyperlink-reader.js +83 -83
  29. package/lib/stream/xlsx/sheet-comments-writer.js +121 -121
  30. package/lib/stream/xlsx/sheet-rels-writer.js +119 -119
  31. package/lib/stream/xlsx/workbook-reader.js +337 -337
  32. package/lib/stream/xlsx/workbook-writer.js +372 -366
  33. package/lib/stream/xlsx/worksheet-reader.js +374 -374
  34. package/lib/stream/xlsx/worksheet-writer.js +717 -717
  35. package/lib/utils/auto-drain.js +15 -15
  36. package/lib/utils/browser-buffer-decode.js +14 -14
  37. package/lib/utils/browser-buffer-encode.js +15 -15
  38. package/lib/utils/cell-matrix.js +165 -165
  39. package/lib/utils/col-cache.js +287 -287
  40. package/lib/utils/copy-style.js +43 -43
  41. package/lib/utils/encryptor.js +55 -55
  42. package/lib/utils/iterate-stream.js +48 -48
  43. package/lib/utils/parse-sax.js +30 -30
  44. package/lib/utils/shared-formula.js +44 -44
  45. package/lib/utils/shared-strings.js +35 -35
  46. package/lib/utils/stream-base64.js +72 -72
  47. package/lib/utils/stream-buf.js +364 -364
  48. package/lib/utils/string-buf.js +82 -82
  49. package/lib/utils/string-builder.js +35 -35
  50. package/lib/utils/stuttered-pipe.js +67 -67
  51. package/lib/utils/typed-stack.js +24 -24
  52. package/lib/utils/under-dash.js +184 -184
  53. package/lib/utils/utils.js +205 -205
  54. package/lib/utils/xml-stream.js +169 -169
  55. package/lib/utils/zip-stream.js +87 -87
  56. package/lib/xlsx/.rels +10 -10
  57. package/lib/xlsx/calcChain.xml +5 -5
  58. package/lib/xlsx/core.xml +6 -6
  59. package/lib/xlsx/defaultnumformats.js +153 -153
  60. package/lib/xlsx/rel-type.js +20 -20
  61. package/lib/xlsx/styles.xml +40 -40
  62. package/lib/xlsx/workbook.xml +16 -16
  63. package/lib/xlsx/xform/base-xform.js +145 -145
  64. package/lib/xlsx/xform/book/defined-name-xform.js +91 -91
  65. package/lib/xlsx/xform/book/sheet-xform.js +34 -34
  66. package/lib/xlsx/xform/book/workbook-calc-properties-xform.js +26 -26
  67. package/lib/xlsx/xform/book/workbook-pivot-cache-xform.js +29 -29
  68. package/lib/xlsx/xform/book/workbook-properties-xform.js +29 -29
  69. package/lib/xlsx/xform/book/workbook-view-xform.js +53 -53
  70. package/lib/xlsx/xform/book/workbook-xform.js +259 -259
  71. package/lib/xlsx/xform/comment/comment-xform.js +105 -105
  72. package/lib/xlsx/xform/comment/comments-xform.js +82 -82
  73. package/lib/xlsx/xform/comment/style/vml-position-xform.js +39 -39
  74. package/lib/xlsx/xform/comment/style/vml-protection-xform.js +36 -36
  75. package/lib/xlsx/xform/comment/vml-anchor-xform.js +60 -60
  76. package/lib/xlsx/xform/comment/vml-client-data-xform.js +95 -95
  77. package/lib/xlsx/xform/comment/vml-notes-xform.js +107 -107
  78. package/lib/xlsx/xform/comment/vml-shape-xform.js +95 -95
  79. package/lib/xlsx/xform/comment/vml-textbox-xform.js +64 -64
  80. package/lib/xlsx/xform/composite-xform.js +56 -56
  81. package/lib/xlsx/xform/core/app-heading-pairs-xform.js +32 -32
  82. package/lib/xlsx/xform/core/app-titles-of-parts-xform.js +28 -28
  83. package/lib/xlsx/xform/core/app-xform.js +100 -100
  84. package/lib/xlsx/xform/core/content-types-xform.js +135 -135
  85. package/lib/xlsx/xform/core/core-xform.js +136 -136
  86. package/lib/xlsx/xform/core/relationship-xform.js +25 -25
  87. package/lib/xlsx/xform/core/relationships-xform.js +73 -73
  88. package/lib/xlsx/xform/drawing/base-cell-anchor-xform.js +48 -48
  89. package/lib/xlsx/xform/drawing/blip-fill-xform.js +71 -71
  90. package/lib/xlsx/xform/drawing/blip-xform.js +42 -42
  91. package/lib/xlsx/xform/drawing/c-nv-pic-pr-xform.js +38 -38
  92. package/lib/xlsx/xform/drawing/c-nv-pr-xform.js +68 -68
  93. package/lib/xlsx/xform/drawing/cell-position-xform.js +77 -77
  94. package/lib/xlsx/xform/drawing/drawing-xform.js +109 -109
  95. package/lib/xlsx/xform/drawing/ext-lst-xform.js +43 -43
  96. package/lib/xlsx/xform/drawing/ext-xform.js +44 -44
  97. package/lib/xlsx/xform/drawing/hlink-click-xform.js +41 -41
  98. package/lib/xlsx/xform/drawing/nv-pic-pr-xform.js +65 -65
  99. package/lib/xlsx/xform/drawing/one-cell-anchor-xform.js +63 -63
  100. package/lib/xlsx/xform/drawing/pic-xform.js +77 -77
  101. package/lib/xlsx/xform/drawing/sp-pr.js +17 -17
  102. package/lib/xlsx/xform/drawing/two-cell-anchor-xform.js +62 -62
  103. package/lib/xlsx/xform/list-xform.js +95 -95
  104. package/lib/xlsx/xform/pivot-table/cache-field.js +43 -43
  105. package/lib/xlsx/xform/pivot-table/pivot-cache-definition-xform.js +77 -77
  106. package/lib/xlsx/xform/pivot-table/pivot-cache-records-xform.js +103 -103
  107. package/lib/xlsx/xform/pivot-table/pivot-table-xform.js +189 -189
  108. package/lib/xlsx/xform/sheet/auto-filter-xform.js +38 -38
  109. package/lib/xlsx/xform/sheet/cell-xform.js +498 -498
  110. package/lib/xlsx/xform/sheet/cf/cf-rule-xform.js +301 -301
  111. package/lib/xlsx/xform/sheet/cf/cfvo-xform.js +27 -27
  112. package/lib/xlsx/xform/sheet/cf/color-scale-xform.js +45 -45
  113. package/lib/xlsx/xform/sheet/cf/conditional-formatting-xform.js +48 -48
  114. package/lib/xlsx/xform/sheet/cf/conditional-formattings-xform.js +92 -92
  115. package/lib/xlsx/xform/sheet/cf/databar-xform.js +49 -49
  116. package/lib/xlsx/xform/sheet/cf/ext-lst-ref-xform.js +87 -87
  117. package/lib/xlsx/xform/sheet/cf/formula-xform.js +25 -25
  118. package/lib/xlsx/xform/sheet/cf/icon-set-xform.js +47 -47
  119. package/lib/xlsx/xform/sheet/cf-ext/cf-icon-ext-xform.js +27 -27
  120. package/lib/xlsx/xform/sheet/cf-ext/cf-rule-ext-xform.js +98 -98
  121. package/lib/xlsx/xform/sheet/cf-ext/cfvo-ext-xform.js +43 -43
  122. package/lib/xlsx/xform/sheet/cf-ext/conditional-formatting-ext-xform.js +62 -62
  123. package/lib/xlsx/xform/sheet/cf-ext/conditional-formattings-ext-xform.js +50 -50
  124. package/lib/xlsx/xform/sheet/cf-ext/databar-ext-xform.js +98 -98
  125. package/lib/xlsx/xform/sheet/cf-ext/f-ext-xform.js +25 -25
  126. package/lib/xlsx/xform/sheet/cf-ext/icon-set-ext-xform.js +73 -73
  127. package/lib/xlsx/xform/sheet/cf-ext/sqref-ext-xform.js +25 -25
  128. package/lib/xlsx/xform/sheet/col-xform.js +86 -86
  129. package/lib/xlsx/xform/sheet/data-validations-xform.js +257 -257
  130. package/lib/xlsx/xform/sheet/dimension-xform.js +29 -29
  131. package/lib/xlsx/xform/sheet/drawing-xform.js +33 -33
  132. package/lib/xlsx/xform/sheet/ext-lst-xform.js +86 -86
  133. package/lib/xlsx/xform/sheet/header-footer-xform.js +146 -146
  134. package/lib/xlsx/xform/sheet/hyperlink-xform.js +54 -54
  135. package/lib/xlsx/xform/sheet/merge-cell-xform.js +27 -27
  136. package/lib/xlsx/xform/sheet/merges.js +56 -56
  137. package/lib/xlsx/xform/sheet/outline-properties-xform.js +43 -43
  138. package/lib/xlsx/xform/sheet/page-breaks-xform.js +27 -27
  139. package/lib/xlsx/xform/sheet/page-margins-xform.js +49 -49
  140. package/lib/xlsx/xform/sheet/page-setup-properties-xform.js +35 -35
  141. package/lib/xlsx/xform/sheet/page-setup-xform.js +103 -103
  142. package/lib/xlsx/xform/sheet/picture-xform.js +33 -33
  143. package/lib/xlsx/xform/sheet/print-options-xform.js +49 -49
  144. package/lib/xlsx/xform/sheet/row-breaks-xform.js +39 -39
  145. package/lib/xlsx/xform/sheet/row-xform.js +142 -142
  146. package/lib/xlsx/xform/sheet/sheet-format-properties-xform.js +55 -55
  147. package/lib/xlsx/xform/sheet/sheet-properties-xform.js +90 -90
  148. package/lib/xlsx/xform/sheet/sheet-protection-xform.js +89 -89
  149. package/lib/xlsx/xform/sheet/sheet-view-xform.js +202 -202
  150. package/lib/xlsx/xform/sheet/table-part-xform.js +33 -33
  151. package/lib/xlsx/xform/sheet/worksheet-xform.js +548 -548
  152. package/lib/xlsx/xform/simple/boolean-xform.js +31 -31
  153. package/lib/xlsx/xform/simple/date-xform.js +66 -66
  154. package/lib/xlsx/xform/simple/float-xform.js +51 -51
  155. package/lib/xlsx/xform/simple/integer-xform.js +57 -57
  156. package/lib/xlsx/xform/simple/string-xform.js +51 -51
  157. package/lib/xlsx/xform/static-xform.js +64 -64
  158. package/lib/xlsx/xform/strings/phonetic-text-xform.js +98 -98
  159. package/lib/xlsx/xform/strings/rich-text-xform.js +101 -101
  160. package/lib/xlsx/xform/strings/shared-string-xform.js +102 -102
  161. package/lib/xlsx/xform/strings/shared-strings-xform.js +127 -127
  162. package/lib/xlsx/xform/strings/text-xform.js +44 -44
  163. package/lib/xlsx/xform/style/alignment-xform.js +172 -172
  164. package/lib/xlsx/xform/style/border-xform.js +207 -207
  165. package/lib/xlsx/xform/style/color-xform.js +63 -63
  166. package/lib/xlsx/xform/style/dxf-xform.js +111 -111
  167. package/lib/xlsx/xform/style/fill-xform.js +364 -364
  168. package/lib/xlsx/xform/style/font-xform.js +102 -102
  169. package/lib/xlsx/xform/style/numfmt-xform.js +63 -63
  170. package/lib/xlsx/xform/style/protection-xform.js +60 -60
  171. package/lib/xlsx/xform/style/style-xform.js +125 -125
  172. package/lib/xlsx/xform/style/styles-xform.js +527 -527
  173. package/lib/xlsx/xform/style/underline-xform.js +47 -47
  174. package/lib/xlsx/xform/table/auto-filter-xform.js +81 -81
  175. package/lib/xlsx/xform/table/custom-filter-xform.js +33 -33
  176. package/lib/xlsx/xform/table/filter-column-xform.js +96 -96
  177. package/lib/xlsx/xform/table/filter-xform.js +31 -31
  178. package/lib/xlsx/xform/table/table-column-xform.js +44 -44
  179. package/lib/xlsx/xform/table/table-style-info-xform.js +41 -41
  180. package/lib/xlsx/xform/table/table-xform.js +131 -131
  181. package/lib/xlsx/xlsx.js +774 -774
  182. package/lib/xlsx/xml/theme1.js +3 -3
  183. package/lib/xlsx/xml/theme1.xml +317 -317
  184. package/package.json +1 -1
  185. package/dist/LICENSE +0 -22
  186. package/dist/es5/csv/csv.js +0 -182
  187. package/dist/es5/csv/csv.js.map +0 -1
  188. package/dist/es5/csv/line-buffer.js +0 -68
  189. package/dist/es5/csv/line-buffer.js.map +0 -1
  190. package/dist/es5/csv/stream-converter.js +0 -110
  191. package/dist/es5/csv/stream-converter.js.map +0 -1
  192. package/dist/es5/doc/anchor.js +0 -73
  193. package/dist/es5/doc/anchor.js.map +0 -1
  194. package/dist/es5/doc/cell.js +0 -960
  195. package/dist/es5/doc/cell.js.map +0 -1
  196. package/dist/es5/doc/column.js +0 -274
  197. package/dist/es5/doc/column.js.map +0 -1
  198. package/dist/es5/doc/data-validations.js +0 -18
  199. package/dist/es5/doc/data-validations.js.map +0 -1
  200. package/dist/es5/doc/defined-names.js +0 -173
  201. package/dist/es5/doc/defined-names.js.map +0 -1
  202. package/dist/es5/doc/enums.js +0 -49
  203. package/dist/es5/doc/enums.js.map +0 -1
  204. package/dist/es5/doc/image.js +0 -69
  205. package/dist/es5/doc/image.js.map +0 -1
  206. package/dist/es5/doc/modelcontainer.js +0 -16
  207. package/dist/es5/doc/modelcontainer.js.map +0 -1
  208. package/dist/es5/doc/note.js +0 -64
  209. package/dist/es5/doc/note.js.map +0 -1
  210. package/dist/es5/doc/pivot-table.js +0 -137
  211. package/dist/es5/doc/pivot-table.js.map +0 -1
  212. package/dist/es5/doc/range.js +0 -229
  213. package/dist/es5/doc/range.js.map +0 -1
  214. package/dist/es5/doc/row.js +0 -382
  215. package/dist/es5/doc/row.js.map +0 -1
  216. package/dist/es5/doc/table.js +0 -441
  217. package/dist/es5/doc/table.js.map +0 -1
  218. package/dist/es5/doc/workbook.js +0 -205
  219. package/dist/es5/doc/workbook.js.map +0 -1
  220. package/dist/es5/doc/worksheet.js +0 -918
  221. package/dist/es5/doc/worksheet.js.map +0 -1
  222. package/dist/es5/exceljs.bare.js +0 -14
  223. package/dist/es5/exceljs.bare.js.map +0 -1
  224. package/dist/es5/exceljs.browser.js +0 -36
  225. package/dist/es5/exceljs.browser.js.map +0 -1
  226. package/dist/es5/exceljs.nodejs.js +0 -15
  227. package/dist/es5/exceljs.nodejs.js.map +0 -1
  228. package/dist/es5/index.js +0 -15
  229. package/dist/es5/stream/xlsx/hyperlink-reader.js +0 -90
  230. package/dist/es5/stream/xlsx/hyperlink-reader.js.map +0 -1
  231. package/dist/es5/stream/xlsx/sheet-comments-writer.js +0 -94
  232. package/dist/es5/stream/xlsx/sheet-comments-writer.js.map +0 -1
  233. package/dist/es5/stream/xlsx/sheet-rels-writer.js +0 -94
  234. package/dist/es5/stream/xlsx/sheet-rels-writer.js.map +0 -1
  235. package/dist/es5/stream/xlsx/workbook-reader.js +0 -362
  236. package/dist/es5/stream/xlsx/workbook-reader.js.map +0 -1
  237. package/dist/es5/stream/xlsx/workbook-writer.js +0 -347
  238. package/dist/es5/stream/xlsx/workbook-writer.js.map +0 -1
  239. package/dist/es5/stream/xlsx/worksheet-reader.js +0 -392
  240. package/dist/es5/stream/xlsx/worksheet-reader.js.map +0 -1
  241. package/dist/es5/stream/xlsx/worksheet-writer.js +0 -652
  242. package/dist/es5/stream/xlsx/worksheet-writer.js.map +0 -1
  243. package/dist/es5/utils/auto-drain.js +0 -18
  244. package/dist/es5/utils/auto-drain.js.map +0 -1
  245. package/dist/es5/utils/browser-buffer-decode.js +0 -15
  246. package/dist/es5/utils/browser-buffer-decode.js.map +0 -1
  247. package/dist/es5/utils/browser-buffer-encode.js +0 -18
  248. package/dist/es5/utils/browser-buffer-encode.js.map +0 -1
  249. package/dist/es5/utils/cell-matrix.js +0 -149
  250. package/dist/es5/utils/cell-matrix.js.map +0 -1
  251. package/dist/es5/utils/col-cache.js +0 -258
  252. package/dist/es5/utils/col-cache.js.map +0 -1
  253. package/dist/es5/utils/copy-style.js +0 -43
  254. package/dist/es5/utils/copy-style.js.map +0 -1
  255. package/dist/es5/utils/encryptor.js +0 -58
  256. package/dist/es5/utils/encryptor.js.map +0 -1
  257. package/dist/es5/utils/iterate-stream.js +0 -46
  258. package/dist/es5/utils/iterate-stream.js.map +0 -1
  259. package/dist/es5/utils/parse-sax.js +0 -47
  260. package/dist/es5/utils/parse-sax.js.map +0 -1
  261. package/dist/es5/utils/shared-formula.js +0 -42
  262. package/dist/es5/utils/shared-formula.js.map +0 -1
  263. package/dist/es5/utils/shared-strings.js +0 -32
  264. package/dist/es5/utils/shared-strings.js.map +0 -1
  265. package/dist/es5/utils/stream-base64.js +0 -66
  266. package/dist/es5/utils/stream-base64.js.map +0 -1
  267. package/dist/es5/utils/stream-buf.js +0 -343
  268. package/dist/es5/utils/stream-buf.js.map +0 -1
  269. package/dist/es5/utils/string-buf.js +0 -73
  270. package/dist/es5/utils/string-buf.js.map +0 -1
  271. package/dist/es5/utils/string-builder.js +0 -32
  272. package/dist/es5/utils/string-builder.js.map +0 -1
  273. package/dist/es5/utils/stuttered-pipe.js +0 -61
  274. package/dist/es5/utils/stuttered-pipe.js.map +0 -1
  275. package/dist/es5/utils/typed-stack.js +0 -23
  276. package/dist/es5/utils/typed-stack.js.map +0 -1
  277. package/dist/es5/utils/under-dash.js +0 -168
  278. package/dist/es5/utils/under-dash.js.map +0 -1
  279. package/dist/es5/utils/utils.js +0 -204
  280. package/dist/es5/utils/utils.js.map +0 -1
  281. package/dist/es5/utils/xml-stream.js +0 -151
  282. package/dist/es5/utils/xml-stream.js.map +0 -1
  283. package/dist/es5/utils/zip-stream.js +0 -79
  284. package/dist/es5/utils/zip-stream.js.map +0 -1
  285. package/dist/es5/xlsx/defaultnumformats.js +0 -230
  286. package/dist/es5/xlsx/defaultnumformats.js.map +0 -1
  287. package/dist/es5/xlsx/rel-type.js +0 -21
  288. package/dist/es5/xlsx/rel-type.js.map +0 -1
  289. package/dist/es5/xlsx/xform/base-xform.js +0 -139
  290. package/dist/es5/xlsx/xform/base-xform.js.map +0 -1
  291. package/dist/es5/xlsx/xform/book/defined-name-xform.js +0 -85
  292. package/dist/es5/xlsx/xform/book/defined-name-xform.js.map +0 -1
  293. package/dist/es5/xlsx/xform/book/sheet-xform.js +0 -32
  294. package/dist/es5/xlsx/xform/book/sheet-xform.js.map +0 -1
  295. package/dist/es5/xlsx/xform/book/workbook-calc-properties-xform.js +0 -24
  296. package/dist/es5/xlsx/xform/book/workbook-calc-properties-xform.js.map +0 -1
  297. package/dist/es5/xlsx/xform/book/workbook-pivot-cache-xform.js +0 -27
  298. package/dist/es5/xlsx/xform/book/workbook-pivot-cache-xform.js.map +0 -1
  299. package/dist/es5/xlsx/xform/book/workbook-properties-xform.js +0 -27
  300. package/dist/es5/xlsx/xform/book/workbook-properties-xform.js.map +0 -1
  301. package/dist/es5/xlsx/xform/book/workbook-view-xform.js +0 -51
  302. package/dist/es5/xlsx/xform/book/workbook-view-xform.js.map +0 -1
  303. package/dist/es5/xlsx/xform/book/workbook-xform.js +0 -241
  304. package/dist/es5/xlsx/xform/book/workbook-xform.js.map +0 -1
  305. package/dist/es5/xlsx/xform/comment/comment-xform.js +0 -103
  306. package/dist/es5/xlsx/xform/comment/comment-xform.js.map +0 -1
  307. package/dist/es5/xlsx/xform/comment/comments-xform.js +0 -76
  308. package/dist/es5/xlsx/xform/comment/comments-xform.js.map +0 -1
  309. package/dist/es5/xlsx/xform/comment/style/vml-position-xform.js +0 -35
  310. package/dist/es5/xlsx/xform/comment/style/vml-position-xform.js.map +0 -1
  311. package/dist/es5/xlsx/xform/comment/style/vml-protection-xform.js +0 -32
  312. package/dist/es5/xlsx/xform/comment/style/vml-protection-xform.js.map +0 -1
  313. package/dist/es5/xlsx/xform/comment/vml-anchor-xform.js +0 -53
  314. package/dist/es5/xlsx/xform/comment/vml-anchor-xform.js.map +0 -1
  315. package/dist/es5/xlsx/xform/comment/vml-client-data-xform.js +0 -97
  316. package/dist/es5/xlsx/xform/comment/vml-client-data-xform.js.map +0 -1
  317. package/dist/es5/xlsx/xform/comment/vml-notes-xform.js +0 -107
  318. package/dist/es5/xlsx/xform/comment/vml-notes-xform.js.map +0 -1
  319. package/dist/es5/xlsx/xform/comment/vml-shape-xform.js +0 -92
  320. package/dist/es5/xlsx/xform/comment/vml-shape-xform.js.map +0 -1
  321. package/dist/es5/xlsx/xform/comment/vml-textbox-xform.js +0 -61
  322. package/dist/es5/xlsx/xform/comment/vml-textbox-xform.js.map +0 -1
  323. package/dist/es5/xlsx/xform/composite-xform.js +0 -51
  324. package/dist/es5/xlsx/xform/composite-xform.js.map +0 -1
  325. package/dist/es5/xlsx/xform/core/app-heading-pairs-xform.js +0 -30
  326. package/dist/es5/xlsx/xform/core/app-heading-pairs-xform.js.map +0 -1
  327. package/dist/es5/xlsx/xform/core/app-titles-of-parts-xform.js +0 -27
  328. package/dist/es5/xlsx/xform/core/app-titles-of-parts-xform.js.map +0 -1
  329. package/dist/es5/xlsx/xform/core/app-xform.js +0 -93
  330. package/dist/es5/xlsx/xform/core/app-xform.js.map +0 -1
  331. package/dist/es5/xlsx/xform/core/content-types-xform.js +0 -127
  332. package/dist/es5/xlsx/xform/core/content-types-xform.js.map +0 -1
  333. package/dist/es5/xlsx/xform/core/core-xform.js +0 -158
  334. package/dist/es5/xlsx/xform/core/core-xform.js.map +0 -1
  335. package/dist/es5/xlsx/xform/core/relationship-xform.js +0 -23
  336. package/dist/es5/xlsx/xform/core/relationship-xform.js.map +0 -1
  337. package/dist/es5/xlsx/xform/core/relationships-xform.js +0 -65
  338. package/dist/es5/xlsx/xform/core/relationships-xform.js.map +0 -1
  339. package/dist/es5/xlsx/xform/drawing/base-cell-anchor-xform.js +0 -47
  340. package/dist/es5/xlsx/xform/drawing/base-cell-anchor-xform.js.map +0 -1
  341. package/dist/es5/xlsx/xform/drawing/blip-fill-xform.js +0 -61
  342. package/dist/es5/xlsx/xform/drawing/blip-fill-xform.js.map +0 -1
  343. package/dist/es5/xlsx/xform/drawing/blip-xform.js +0 -39
  344. package/dist/es5/xlsx/xform/drawing/blip-xform.js.map +0 -1
  345. package/dist/es5/xlsx/xform/drawing/c-nv-pic-pr-xform.js +0 -35
  346. package/dist/es5/xlsx/xform/drawing/c-nv-pic-pr-xform.js.map +0 -1
  347. package/dist/es5/xlsx/xform/drawing/c-nv-pr-xform.js +0 -62
  348. package/dist/es5/xlsx/xform/drawing/c-nv-pr-xform.js.map +0 -1
  349. package/dist/es5/xlsx/xform/drawing/cell-position-xform.js +0 -82
  350. package/dist/es5/xlsx/xform/drawing/cell-position-xform.js.map +0 -1
  351. package/dist/es5/xlsx/xform/drawing/drawing-xform.js +0 -98
  352. package/dist/es5/xlsx/xform/drawing/drawing-xform.js.map +0 -1
  353. package/dist/es5/xlsx/xform/drawing/ext-lst-xform.js +0 -40
  354. package/dist/es5/xlsx/xform/drawing/ext-lst-xform.js.map +0 -1
  355. package/dist/es5/xlsx/xform/drawing/ext-xform.js +0 -38
  356. package/dist/es5/xlsx/xform/drawing/ext-xform.js.map +0 -1
  357. package/dist/es5/xlsx/xform/drawing/hlink-click-xform.js +0 -38
  358. package/dist/es5/xlsx/xform/drawing/hlink-click-xform.js.map +0 -1
  359. package/dist/es5/xlsx/xform/drawing/nv-pic-pr-xform.js +0 -59
  360. package/dist/es5/xlsx/xform/drawing/nv-pic-pr-xform.js.map +0 -1
  361. package/dist/es5/xlsx/xform/drawing/one-cell-anchor-xform.js +0 -63
  362. package/dist/es5/xlsx/xform/drawing/one-cell-anchor-xform.js.map +0 -1
  363. package/dist/es5/xlsx/xform/drawing/pic-xform.js +0 -67
  364. package/dist/es5/xlsx/xform/drawing/pic-xform.js.map +0 -1
  365. package/dist/es5/xlsx/xform/drawing/sp-pr.js +0 -30
  366. package/dist/es5/xlsx/xform/drawing/sp-pr.js.map +0 -1
  367. package/dist/es5/xlsx/xform/drawing/two-cell-anchor-xform.js +0 -62
  368. package/dist/es5/xlsx/xform/drawing/two-cell-anchor-xform.js.map +0 -1
  369. package/dist/es5/xlsx/xform/list-xform.js +0 -91
  370. package/dist/es5/xlsx/xform/list-xform.js.map +0 -1
  371. package/dist/es5/xlsx/xform/pivot-table/cache-field.js +0 -48
  372. package/dist/es5/xlsx/xform/pivot-table/cache-field.js.map +0 -1
  373. package/dist/es5/xlsx/xform/pivot-table/pivot-cache-definition-xform.js +0 -73
  374. package/dist/es5/xlsx/xform/pivot-table/pivot-cache-definition-xform.js.map +0 -1
  375. package/dist/es5/xlsx/xform/pivot-table/pivot-cache-records-xform.js +0 -93
  376. package/dist/es5/xlsx/xform/pivot-table/pivot-cache-records-xform.js.map +0 -1
  377. package/dist/es5/xlsx/xform/pivot-table/pivot-table-xform.js +0 -176
  378. package/dist/es5/xlsx/xform/pivot-table/pivot-table-xform.js.map +0 -1
  379. package/dist/es5/xlsx/xform/sheet/auto-filter-xform.js +0 -40
  380. package/dist/es5/xlsx/xform/sheet/auto-filter-xform.js.map +0 -1
  381. package/dist/es5/xlsx/xform/sheet/cell-xform.js +0 -450
  382. package/dist/es5/xlsx/xform/sheet/cell-xform.js.map +0 -1
  383. package/dist/es5/xlsx/xform/sheet/cf/cf-rule-xform.js +0 -275
  384. package/dist/es5/xlsx/xform/sheet/cf/cf-rule-xform.js.map +0 -1
  385. package/dist/es5/xlsx/xform/sheet/cf/cfvo-xform.js +0 -25
  386. package/dist/es5/xlsx/xform/sheet/cf/cfvo-xform.js.map +0 -1
  387. package/dist/es5/xlsx/xform/sheet/cf/color-scale-xform.js +0 -38
  388. package/dist/es5/xlsx/xform/sheet/cf/color-scale-xform.js.map +0 -1
  389. package/dist/es5/xlsx/xform/sheet/cf/conditional-formatting-xform.js +0 -45
  390. package/dist/es5/xlsx/xform/sheet/cf/conditional-formatting-xform.js.map +0 -1
  391. package/dist/es5/xlsx/xform/sheet/cf/conditional-formattings-xform.js +0 -77
  392. package/dist/es5/xlsx/xform/sheet/cf/conditional-formattings-xform.js.map +0 -1
  393. package/dist/es5/xlsx/xform/sheet/cf/databar-xform.js +0 -42
  394. package/dist/es5/xlsx/xform/sheet/cf/databar-xform.js.map +0 -1
  395. package/dist/es5/xlsx/xform/sheet/cf/ext-lst-ref-xform.js +0 -71
  396. package/dist/es5/xlsx/xform/sheet/cf/ext-lst-ref-xform.js.map +0 -1
  397. package/dist/es5/xlsx/xform/sheet/cf/formula-xform.js +0 -22
  398. package/dist/es5/xlsx/xform/sheet/cf/formula-xform.js.map +0 -1
  399. package/dist/es5/xlsx/xform/sheet/cf/icon-set-xform.js +0 -43
  400. package/dist/es5/xlsx/xform/sheet/cf/icon-set-xform.js.map +0 -1
  401. package/dist/es5/xlsx/xform/sheet/cf-ext/cf-icon-ext-xform.js +0 -28
  402. package/dist/es5/xlsx/xform/sheet/cf-ext/cf-icon-ext-xform.js.map +0 -1
  403. package/dist/es5/xlsx/xform/sheet/cf-ext/cf-rule-ext-xform.js +0 -88
  404. package/dist/es5/xlsx/xform/sheet/cf-ext/cf-rule-ext-xform.js.map +0 -1
  405. package/dist/es5/xlsx/xform/sheet/cf-ext/cfvo-ext-xform.js +0 -38
  406. package/dist/es5/xlsx/xform/sheet/cf-ext/cfvo-ext-xform.js.map +0 -1
  407. package/dist/es5/xlsx/xform/sheet/cf-ext/conditional-formatting-ext-xform.js +0 -52
  408. package/dist/es5/xlsx/xform/sheet/cf-ext/conditional-formatting-ext-xform.js.map +0 -1
  409. package/dist/es5/xlsx/xform/sheet/cf-ext/conditional-formattings-ext-xform.js +0 -43
  410. package/dist/es5/xlsx/xform/sheet/cf-ext/conditional-formattings-ext-xform.js.map +0 -1
  411. package/dist/es5/xlsx/xform/sheet/cf-ext/databar-ext-xform.js +0 -75
  412. package/dist/es5/xlsx/xform/sheet/cf-ext/databar-ext-xform.js.map +0 -1
  413. package/dist/es5/xlsx/xform/sheet/cf-ext/f-ext-xform.js +0 -22
  414. package/dist/es5/xlsx/xform/sheet/cf-ext/f-ext-xform.js.map +0 -1
  415. package/dist/es5/xlsx/xform/sheet/cf-ext/icon-set-ext-xform.js +0 -66
  416. package/dist/es5/xlsx/xform/sheet/cf-ext/icon-set-ext-xform.js.map +0 -1
  417. package/dist/es5/xlsx/xform/sheet/cf-ext/sqref-ext-xform.js +0 -22
  418. package/dist/es5/xlsx/xform/sheet/cf-ext/sqref-ext-xform.js.map +0 -1
  419. package/dist/es5/xlsx/xform/sheet/col-xform.js +0 -78
  420. package/dist/es5/xlsx/xform/sheet/col-xform.js.map +0 -1
  421. package/dist/es5/xlsx/xform/sheet/data-validations-xform.js +0 -247
  422. package/dist/es5/xlsx/xform/sheet/data-validations-xform.js.map +0 -1
  423. package/dist/es5/xlsx/xform/sheet/dimension-xform.js +0 -28
  424. package/dist/es5/xlsx/xform/sheet/dimension-xform.js.map +0 -1
  425. package/dist/es5/xlsx/xform/sheet/drawing-xform.js +0 -32
  426. package/dist/es5/xlsx/xform/sheet/drawing-xform.js.map +0 -1
  427. package/dist/es5/xlsx/xform/sheet/ext-lst-xform.js +0 -69
  428. package/dist/es5/xlsx/xform/sheet/ext-lst-xform.js.map +0 -1
  429. package/dist/es5/xlsx/xform/sheet/header-footer-xform.js +0 -126
  430. package/dist/es5/xlsx/xform/sheet/header-footer-xform.js.map +0 -1
  431. package/dist/es5/xlsx/xform/sheet/hyperlink-xform.js +0 -50
  432. package/dist/es5/xlsx/xform/sheet/hyperlink-xform.js.map +0 -1
  433. package/dist/es5/xlsx/xform/sheet/merge-cell-xform.js +0 -26
  434. package/dist/es5/xlsx/xform/sheet/merge-cell-xform.js.map +0 -1
  435. package/dist/es5/xlsx/xform/sheet/merges.js +0 -52
  436. package/dist/es5/xlsx/xform/sheet/merges.js.map +0 -1
  437. package/dist/es5/xlsx/xform/sheet/outline-properties-xform.js +0 -35
  438. package/dist/es5/xlsx/xform/sheet/outline-properties-xform.js.map +0 -1
  439. package/dist/es5/xlsx/xform/sheet/page-breaks-xform.js +0 -24
  440. package/dist/es5/xlsx/xform/sheet/page-breaks-xform.js.map +0 -1
  441. package/dist/es5/xlsx/xform/sheet/page-margins-xform.js +0 -46
  442. package/dist/es5/xlsx/xform/sheet/page-margins-xform.js.map +0 -1
  443. package/dist/es5/xlsx/xform/sheet/page-setup-properties-xform.js +0 -32
  444. package/dist/es5/xlsx/xform/sheet/page-setup-properties-xform.js.map +0 -1
  445. package/dist/es5/xlsx/xform/sheet/page-setup-xform.js +0 -99
  446. package/dist/es5/xlsx/xform/sheet/page-setup-xform.js.map +0 -1
  447. package/dist/es5/xlsx/xform/sheet/picture-xform.js +0 -32
  448. package/dist/es5/xlsx/xform/sheet/picture-xform.js.map +0 -1
  449. package/dist/es5/xlsx/xform/sheet/print-options-xform.js +0 -45
  450. package/dist/es5/xlsx/xform/sheet/print-options-xform.js.map +0 -1
  451. package/dist/es5/xlsx/xform/sheet/row-breaks-xform.js +0 -37
  452. package/dist/es5/xlsx/xform/sheet/row-breaks-xform.js.map +0 -1
  453. package/dist/es5/xlsx/xform/sheet/row-xform.js +0 -128
  454. package/dist/es5/xlsx/xform/sheet/row-xform.js.map +0 -1
  455. package/dist/es5/xlsx/xform/sheet/sheet-format-properties-xform.js +0 -51
  456. package/dist/es5/xlsx/xform/sheet/sheet-format-properties-xform.js.map +0 -1
  457. package/dist/es5/xlsx/xform/sheet/sheet-properties-xform.js +0 -83
  458. package/dist/es5/xlsx/xform/sheet/sheet-properties-xform.js.map +0 -1
  459. package/dist/es5/xlsx/xform/sheet/sheet-protection-xform.js +0 -84
  460. package/dist/es5/xlsx/xform/sheet/sheet-protection-xform.js.map +0 -1
  461. package/dist/es5/xlsx/xform/sheet/sheet-view-xform.js +0 -190
  462. package/dist/es5/xlsx/xform/sheet/sheet-view-xform.js.map +0 -1
  463. package/dist/es5/xlsx/xform/sheet/table-part-xform.js +0 -32
  464. package/dist/es5/xlsx/xform/sheet/table-part-xform.js.map +0 -1
  465. package/dist/es5/xlsx/xform/sheet/worksheet-xform.js +0 -522
  466. package/dist/es5/xlsx/xform/sheet/worksheet-xform.js.map +0 -1
  467. package/dist/es5/xlsx/xform/simple/boolean-xform.js +0 -27
  468. package/dist/es5/xlsx/xform/simple/boolean-xform.js.map +0 -1
  469. package/dist/es5/xlsx/xform/simple/date-xform.js +0 -58
  470. package/dist/es5/xlsx/xform/simple/date-xform.js.map +0 -1
  471. package/dist/es5/xlsx/xform/simple/float-xform.js +0 -47
  472. package/dist/es5/xlsx/xform/simple/float-xform.js.map +0 -1
  473. package/dist/es5/xlsx/xform/simple/integer-xform.js +0 -53
  474. package/dist/es5/xlsx/xform/simple/integer-xform.js.map +0 -1
  475. package/dist/es5/xlsx/xform/simple/string-xform.js +0 -47
  476. package/dist/es5/xlsx/xform/simple/string-xform.js.map +0 -1
  477. package/dist/es5/xlsx/xform/static-xform.js +0 -61
  478. package/dist/es5/xlsx/xform/static-xform.js.map +0 -1
  479. package/dist/es5/xlsx/xform/strings/phonetic-text-xform.js +0 -98
  480. package/dist/es5/xlsx/xform/strings/phonetic-text-xform.js.map +0 -1
  481. package/dist/es5/xlsx/xform/strings/rich-text-xform.js +0 -92
  482. package/dist/es5/xlsx/xform/strings/rich-text-xform.js.map +0 -1
  483. package/dist/es5/xlsx/xform/strings/shared-string-xform.js +0 -99
  484. package/dist/es5/xlsx/xform/strings/shared-string-xform.js.map +0 -1
  485. package/dist/es5/xlsx/xform/strings/shared-strings-xform.js +0 -114
  486. package/dist/es5/xlsx/xform/strings/shared-strings-xform.js.map +0 -1
  487. package/dist/es5/xlsx/xform/strings/text-xform.js +0 -39
  488. package/dist/es5/xlsx/xform/strings/text-xform.js.map +0 -1
  489. package/dist/es5/xlsx/xform/style/alignment-xform.js +0 -139
  490. package/dist/es5/xlsx/xform/style/alignment-xform.js.map +0 -1
  491. package/dist/es5/xlsx/xform/style/border-xform.js +0 -185
  492. package/dist/es5/xlsx/xform/style/border-xform.js.map +0 -1
  493. package/dist/es5/xlsx/xform/style/color-xform.js +0 -66
  494. package/dist/es5/xlsx/xform/style/color-xform.js.map +0 -1
  495. package/dist/es5/xlsx/xform/style/dxf-xform.js +0 -106
  496. package/dist/es5/xlsx/xform/style/dxf-xform.js.map +0 -1
  497. package/dist/es5/xlsx/xform/style/fill-xform.js +0 -307
  498. package/dist/es5/xlsx/xform/style/fill-xform.js.map +0 -1
  499. package/dist/es5/xlsx/xform/style/font-xform.js +0 -175
  500. package/dist/es5/xlsx/xform/style/font-xform.js.map +0 -1
  501. package/dist/es5/xlsx/xform/style/numfmt-xform.js +0 -58
  502. package/dist/es5/xlsx/xform/style/numfmt-xform.js.map +0 -1
  503. package/dist/es5/xlsx/xform/style/protection-xform.js +0 -53
  504. package/dist/es5/xlsx/xform/style/protection-xform.js.map +0 -1
  505. package/dist/es5/xlsx/xform/style/style-xform.js +0 -118
  506. package/dist/es5/xlsx/xform/style/style-xform.js.map +0 -1
  507. package/dist/es5/xlsx/xform/style/styles-xform.js +0 -611
  508. package/dist/es5/xlsx/xform/style/styles-xform.js.map +0 -1
  509. package/dist/es5/xlsx/xform/style/underline-xform.js +0 -46
  510. package/dist/es5/xlsx/xform/style/underline-xform.js.map +0 -1
  511. package/dist/es5/xlsx/xform/table/auto-filter-xform.js +0 -75
  512. package/dist/es5/xlsx/xform/table/auto-filter-xform.js.map +0 -1
  513. package/dist/es5/xlsx/xform/table/custom-filter-xform.js +0 -30
  514. package/dist/es5/xlsx/xform/table/custom-filter-xform.js.map +0 -1
  515. package/dist/es5/xlsx/xform/table/filter-column-xform.js +0 -89
  516. package/dist/es5/xlsx/xform/table/filter-column-xform.js.map +0 -1
  517. package/dist/es5/xlsx/xform/table/filter-xform.js +0 -28
  518. package/dist/es5/xlsx/xform/table/filter-xform.js.map +0 -1
  519. package/dist/es5/xlsx/xform/table/table-column-xform.js +0 -42
  520. package/dist/es5/xlsx/xform/table/table-column-xform.js.map +0 -1
  521. package/dist/es5/xlsx/xform/table/table-style-info-xform.js +0 -40
  522. package/dist/es5/xlsx/xform/table/table-style-info-xform.js.map +0 -1
  523. package/dist/es5/xlsx/xform/table/table-xform.js +0 -122
  524. package/dist/es5/xlsx/xform/table/table-xform.js.map +0 -1
  525. package/dist/es5/xlsx/xlsx.js +0 -775
  526. package/dist/es5/xlsx/xlsx.js.map +0 -1
  527. package/dist/es5/xlsx/xml/theme1.js +0 -5
  528. package/dist/es5/xlsx/xml/theme1.js.map +0 -1
  529. package/dist/exceljs.bare.js +0 -57759
  530. package/dist/exceljs.bare.js.map +0 -777
  531. package/dist/exceljs.bare.min.js +0 -45
  532. package/dist/exceljs.bare.min.js.map +0 -1
  533. package/dist/exceljs.js +0 -62398
  534. package/dist/exceljs.js.map +0 -1095
  535. package/dist/exceljs.min.js +0 -45
  536. package/dist/exceljs.min.js.map +0 -1
package/lib/xlsx/xlsx.js CHANGED
@@ -1,774 +1,774 @@
1
- const fs = require('fs');
2
- const JSZip = require('jszip');
3
- const {PassThrough} = require('readable-stream');
4
- const ZipStream = require('../utils/zip-stream');
5
- const StreamBuf = require('../utils/stream-buf');
6
-
7
- const utils = require('../utils/utils');
8
- const XmlStream = require('../utils/xml-stream');
9
- const {bufferToString} = require('../utils/browser-buffer-decode');
10
-
11
- const StylesXform = require('./xform/style/styles-xform');
12
-
13
- const CoreXform = require('./xform/core/core-xform');
14
- const SharedStringsXform = require('./xform/strings/shared-strings-xform');
15
- const RelationshipsXform = require('./xform/core/relationships-xform');
16
- const ContentTypesXform = require('./xform/core/content-types-xform');
17
- const AppXform = require('./xform/core/app-xform');
18
- const WorkbookXform = require('./xform/book/workbook-xform');
19
- const WorksheetXform = require('./xform/sheet/worksheet-xform');
20
- const DrawingXform = require('./xform/drawing/drawing-xform');
21
- const TableXform = require('./xform/table/table-xform');
22
- const PivotCacheRecordsXform = require('./xform/pivot-table/pivot-cache-records-xform');
23
- const PivotCacheDefinitionXform = require('./xform/pivot-table/pivot-cache-definition-xform');
24
- const PivotTableXform = require('./xform/pivot-table/pivot-table-xform');
25
- const CommentsXform = require('./xform/comment/comments-xform');
26
- const VmlNotesXform = require('./xform/comment/vml-notes-xform');
27
-
28
- const theme1Xml = require('./xml/theme1');
29
-
30
- function fsReadFileAsync(filename, options) {
31
- return new Promise((resolve, reject) => {
32
- fs.readFile(filename, options, (error, data) => {
33
- if (error) {
34
- reject(error);
35
- } else {
36
- resolve(data);
37
- }
38
- });
39
- });
40
- }
41
-
42
- class XLSX {
43
- constructor(workbook) {
44
- this.workbook = workbook;
45
- }
46
-
47
- // ===============================================================================
48
- // Workbook
49
- // =========================================================================
50
- // Read
51
-
52
- async readFile(filename, options) {
53
- if (!(await utils.fs.exists(filename))) {
54
- throw new Error(`File not found: ${filename}`);
55
- }
56
- const stream = fs.createReadStream(filename);
57
- try {
58
- const workbook = await this.read(stream, options);
59
- stream.close();
60
- return workbook;
61
- } catch (error) {
62
- stream.close();
63
- throw error;
64
- }
65
- }
66
-
67
- parseRels(stream) {
68
- const xform = new RelationshipsXform();
69
- return xform.parseStream(stream);
70
- }
71
-
72
- parseWorkbook(stream) {
73
- const xform = new WorkbookXform();
74
- return xform.parseStream(stream);
75
- }
76
-
77
- parseSharedStrings(stream) {
78
- const xform = new SharedStringsXform();
79
- return xform.parseStream(stream);
80
- }
81
-
82
- reconcile(model, options) {
83
- const workbookXform = new WorkbookXform();
84
- const worksheetXform = new WorksheetXform(options);
85
- const drawingXform = new DrawingXform();
86
- const tableXform = new TableXform();
87
-
88
- workbookXform.reconcile(model);
89
-
90
- // reconcile drawings with their rels
91
- const drawingOptions = {
92
- media: model.media,
93
- mediaIndex: model.mediaIndex,
94
- };
95
- Object.keys(model.drawings).forEach(name => {
96
- const drawing = model.drawings[name];
97
- const drawingRel = model.drawingRels[name];
98
- if (drawingRel) {
99
- drawingOptions.rels = drawingRel.reduce((o, rel) => {
100
- o[rel.Id] = rel;
101
- return o;
102
- }, {});
103
- (drawing.anchors || []).forEach(anchor => {
104
- const hyperlinks = anchor.picture && anchor.picture.hyperlinks;
105
- if (hyperlinks && drawingOptions.rels[hyperlinks.rId]) {
106
- hyperlinks.hyperlink = drawingOptions.rels[hyperlinks.rId].Target;
107
- delete hyperlinks.rId;
108
- }
109
- });
110
- drawingXform.reconcile(drawing, drawingOptions);
111
- }
112
- });
113
-
114
- // reconcile tables with the default styles
115
- const tableOptions = {
116
- styles: model.styles,
117
- };
118
- Object.values(model.tables).forEach(table => {
119
- tableXform.reconcile(table, tableOptions);
120
- });
121
-
122
- const sheetOptions = {
123
- styles: model.styles,
124
- sharedStrings: model.sharedStrings,
125
- media: model.media,
126
- mediaIndex: model.mediaIndex,
127
- date1904: model.properties && model.properties.date1904,
128
- drawings: model.drawings,
129
- comments: model.comments,
130
- tables: model.tables,
131
- vmlDrawings: model.vmlDrawings,
132
- };
133
- model.worksheets.forEach(worksheet => {
134
- worksheet.relationships = model.worksheetRels[worksheet.sheetNo];
135
- worksheetXform.reconcile(worksheet, sheetOptions);
136
- });
137
-
138
- // delete unnecessary parts
139
- delete model.worksheetHash;
140
- delete model.worksheetRels;
141
- delete model.globalRels;
142
- delete model.sharedStrings;
143
- delete model.workbookRels;
144
- delete model.sheetDefs;
145
- delete model.styles;
146
- delete model.mediaIndex;
147
- delete model.drawings;
148
- delete model.drawingRels;
149
- delete model.vmlDrawings;
150
- }
151
-
152
- async _processWorksheetEntry(stream, model, sheetNo, options, path) {
153
- const xform = new WorksheetXform(options);
154
- const worksheet = await xform.parseStream(stream);
155
- worksheet.sheetNo = sheetNo;
156
- model.worksheetHash[path] = worksheet;
157
- model.worksheets.push(worksheet);
158
- }
159
-
160
- async _processCommentEntry(stream, model, name) {
161
- const xform = new CommentsXform();
162
- const comments = await xform.parseStream(stream);
163
- model.comments[`../${name}.xml`] = comments;
164
- }
165
-
166
- async _processTableEntry(stream, model, name) {
167
- const xform = new TableXform();
168
- const table = await xform.parseStream(stream);
169
- model.tables[`../tables/${name}.xml`] = table;
170
- }
171
-
172
- async _processWorksheetRelsEntry(stream, model, sheetNo) {
173
- const xform = new RelationshipsXform();
174
- const relationships = await xform.parseStream(stream);
175
- model.worksheetRels[sheetNo] = relationships;
176
- }
177
-
178
- async _processMediaEntry(entry, model, filename) {
179
- const lastDot = filename.lastIndexOf('.');
180
- // if we can't determine extension, ignore it
181
- if (lastDot >= 1) {
182
- const extension = filename.substr(lastDot + 1);
183
- const name = filename.substr(0, lastDot);
184
- await new Promise((resolve, reject) => {
185
- const streamBuf = new StreamBuf();
186
- streamBuf.on('finish', () => {
187
- model.mediaIndex[filename] = model.media.length;
188
- model.mediaIndex[name] = model.media.length;
189
- const medium = {
190
- type: 'image',
191
- name,
192
- extension,
193
- buffer: streamBuf.toBuffer(),
194
- };
195
- model.media.push(medium);
196
- resolve();
197
- });
198
- entry.on('error', error => {
199
- reject(error);
200
- });
201
- entry.pipe(streamBuf);
202
- });
203
- }
204
- }
205
-
206
- async _processDrawingEntry(entry, model, name) {
207
- const xform = new DrawingXform();
208
- const drawing = await xform.parseStream(entry);
209
- model.drawings[name] = drawing;
210
- }
211
-
212
- async _processDrawingRelsEntry(entry, model, name) {
213
- const xform = new RelationshipsXform();
214
- const relationships = await xform.parseStream(entry);
215
- model.drawingRels[name] = relationships;
216
- }
217
-
218
- async _processVmlDrawingEntry(entry, model, name) {
219
- const xform = new VmlNotesXform();
220
- const vmlDrawing = await xform.parseStream(entry);
221
- model.vmlDrawings[`../drawings/${name}.vml`] = vmlDrawing;
222
- }
223
-
224
- async _processThemeEntry(entry, model, name) {
225
- await new Promise((resolve, reject) => {
226
- // TODO: stream entry into buffer and store the xml in the model.themes[]
227
- const stream = new StreamBuf();
228
- entry.on('error', reject);
229
- stream.on('error', reject);
230
- stream.on('finish', () => {
231
- model.themes[name] = stream.read().toString();
232
- resolve();
233
- });
234
- entry.pipe(stream);
235
- });
236
- }
237
-
238
- /**
239
- * @deprecated since version 4.0. You should use `#read` instead. Please follow upgrade instruction: https://github.com/exceljs/exceljs/blob/master/UPGRADE-4.0.md
240
- */
241
- createInputStream() {
242
- throw new Error(
243
- '`XLSX#createInputStream` is deprecated. You should use `XLSX#read` instead. This method will be removed in version 5.0. Please follow upgrade instruction: https://github.com/exceljs/exceljs/blob/master/UPGRADE-4.0.md'
244
- );
245
- }
246
-
247
- async read(stream, options) {
248
- // TODO: Remove once node v8 is deprecated
249
- // Detect and upgrade old streams
250
- if (!stream[Symbol.asyncIterator] && stream.pipe) {
251
- stream = stream.pipe(new PassThrough());
252
- }
253
- const chunks = [];
254
- for await (const chunk of stream) {
255
- chunks.push(chunk);
256
- }
257
- return this.load(Buffer.concat(chunks), options);
258
- }
259
-
260
- async load(data, options) {
261
- let buffer;
262
- if (options && options.base64) {
263
- buffer = Buffer.from(data.toString(), 'base64');
264
- } else {
265
- buffer = data;
266
- }
267
-
268
- const model = {
269
- worksheets: [],
270
- worksheetHash: {},
271
- worksheetRels: [],
272
- themes: {},
273
- media: [],
274
- mediaIndex: {},
275
- drawings: {},
276
- drawingRels: {},
277
- comments: {},
278
- tables: {},
279
- vmlDrawings: {},
280
- };
281
-
282
- const zip = await JSZip.loadAsync(buffer);
283
- for (const entry of Object.values(zip.files)) {
284
- /* eslint-disable no-await-in-loop */
285
- if (!entry.dir) {
286
- let entryName = entry.name;
287
- if (entryName[0] === '/') {
288
- entryName = entryName.substr(1);
289
- }
290
- let stream;
291
- if (
292
- entryName.match(/xl\/media\//) ||
293
- // themes are not parsed as stream
294
- entryName.match(/xl\/theme\/([a-zA-Z0-9]+)[.]xml/)
295
- ) {
296
- stream = new PassThrough();
297
- stream.write(await entry.async('nodebuffer'));
298
- } else {
299
- // use object mode to avoid buffer-string convention
300
- stream = new PassThrough({
301
- writableObjectMode: true,
302
- readableObjectMode: true,
303
- });
304
- let content;
305
- // https://www.npmjs.com/package/process
306
- if (process.browser) {
307
- // running in browser, use TextDecoder if possible
308
- content = bufferToString(await entry.async('nodebuffer'));
309
- } else {
310
- // running in node.js
311
- content = await entry.async('string');
312
- }
313
- const chunkSize = 16 * 1024;
314
- for (let i = 0; i < content.length; i += chunkSize) {
315
- stream.write(content.substring(i, i + chunkSize));
316
- }
317
- }
318
- stream.end();
319
- switch (entryName) {
320
- case '_rels/.rels':
321
- model.globalRels = await this.parseRels(stream);
322
- break;
323
-
324
- case 'xl/workbook.xml': {
325
- const workbook = await this.parseWorkbook(stream);
326
- model.sheets = workbook.sheets;
327
- model.definedNames = workbook.definedNames;
328
- model.views = workbook.views;
329
- model.properties = workbook.properties;
330
- model.calcProperties = workbook.calcProperties;
331
- break;
332
- }
333
-
334
- case 'xl/_rels/workbook.xml.rels':
335
- model.workbookRels = await this.parseRels(stream);
336
- break;
337
-
338
- case 'xl/sharedStrings.xml':
339
- model.sharedStrings = new SharedStringsXform();
340
- await model.sharedStrings.parseStream(stream);
341
- break;
342
-
343
- case 'xl/styles.xml':
344
- model.styles = new StylesXform();
345
- await model.styles.parseStream(stream);
346
- break;
347
-
348
- case 'docProps/app.xml': {
349
- const appXform = new AppXform();
350
- const appProperties = await appXform.parseStream(stream);
351
- model.company = appProperties.company;
352
- model.manager = appProperties.manager;
353
- break;
354
- }
355
-
356
- case 'docProps/core.xml': {
357
- const coreXform = new CoreXform();
358
- const coreProperties = await coreXform.parseStream(stream);
359
- Object.assign(model, coreProperties);
360
- break;
361
- }
362
-
363
- default: {
364
- let match = entryName.match(/xl\/worksheets\/sheet(\d+)[.]xml/);
365
- if (match) {
366
- await this._processWorksheetEntry(stream, model, match[1], options, entryName);
367
- break;
368
- }
369
- match = entryName.match(/xl\/worksheets\/_rels\/sheet(\d+)[.]xml.rels/);
370
- if (match) {
371
- await this._processWorksheetRelsEntry(stream, model, match[1]);
372
- break;
373
- }
374
- match = entryName.match(/xl\/theme\/([a-zA-Z0-9]+)[.]xml/);
375
- if (match) {
376
- await this._processThemeEntry(stream, model, match[1]);
377
- break;
378
- }
379
- match = entryName.match(/xl\/media\/([a-zA-Z0-9]+[.][a-zA-Z0-9]{3,4})$/);
380
- if (match) {
381
- await this._processMediaEntry(stream, model, match[1]);
382
- break;
383
- }
384
- match = entryName.match(/xl\/drawings\/([a-zA-Z0-9]+)[.]xml/);
385
- if (match) {
386
- await this._processDrawingEntry(stream, model, match[1]);
387
- break;
388
- }
389
- match = entryName.match(/xl\/(comments\d+)[.]xml/);
390
- if (match) {
391
- await this._processCommentEntry(stream, model, match[1]);
392
- break;
393
- }
394
- match = entryName.match(/xl\/tables\/(table\d+)[.]xml/);
395
- if (match) {
396
- await this._processTableEntry(stream, model, match[1]);
397
- break;
398
- }
399
- match = entryName.match(/xl\/drawings\/_rels\/([a-zA-Z0-9]+)[.]xml[.]rels/);
400
- if (match) {
401
- await this._processDrawingRelsEntry(stream, model, match[1]);
402
- break;
403
- }
404
- match = entryName.match(/xl\/drawings\/(vmlDrawing\d+)[.]vml/);
405
- if (match) {
406
- await this._processVmlDrawingEntry(stream, model, match[1]);
407
- break;
408
- }
409
- }
410
- }
411
- }
412
- }
413
-
414
- this.reconcile(model, options);
415
-
416
- // apply model
417
- this.workbook.model = model;
418
- return this.workbook;
419
- }
420
-
421
- // =========================================================================
422
- // Write
423
-
424
- async addMedia(zip, model) {
425
- await Promise.all(
426
- model.media.map(async medium => {
427
- if (medium.type === 'image') {
428
- const filename = `xl/media/${medium.name}.${medium.extension}`;
429
- if (medium.filename) {
430
- const data = await fsReadFileAsync(medium.filename);
431
- return zip.append(data, {name: filename});
432
- }
433
- if (medium.buffer) {
434
- return zip.append(medium.buffer, {name: filename});
435
- }
436
- if (medium.base64) {
437
- const dataimg64 = medium.base64;
438
- const content = dataimg64.substring(dataimg64.indexOf(',') + 1);
439
- return zip.append(content, {name: filename, base64: true});
440
- }
441
- }
442
- throw new Error('Unsupported media');
443
- })
444
- );
445
- }
446
-
447
- addDrawings(zip, model) {
448
- const drawingXform = new DrawingXform();
449
- const relsXform = new RelationshipsXform();
450
-
451
- model.worksheets.forEach(worksheet => {
452
- const {drawing} = worksheet;
453
- if (drawing) {
454
- drawingXform.prepare(drawing, {});
455
- let xml = drawingXform.toXml(drawing);
456
- zip.append(xml, {name: `xl/drawings/${drawing.name}.xml`});
457
-
458
- xml = relsXform.toXml(drawing.rels);
459
- zip.append(xml, {name: `xl/drawings/_rels/${drawing.name}.xml.rels`});
460
- }
461
- });
462
- }
463
-
464
- addTables(zip, model) {
465
- const tableXform = new TableXform();
466
-
467
- model.worksheets.forEach(worksheet => {
468
- const {tables} = worksheet;
469
- tables.forEach(table => {
470
- tableXform.prepare(table, {});
471
- const tableXml = tableXform.toXml(table);
472
- zip.append(tableXml, {name: `xl/tables/${table.target}`});
473
- });
474
- });
475
- }
476
-
477
- addPivotTables(zip, model) {
478
- if (!model.pivotTables.length) return;
479
-
480
- const pivotTable = model.pivotTables[0];
481
-
482
- const pivotCacheRecordsXform = new PivotCacheRecordsXform();
483
- const pivotCacheDefinitionXform = new PivotCacheDefinitionXform();
484
- const pivotTableXform = new PivotTableXform();
485
- const relsXform = new RelationshipsXform();
486
-
487
- // pivot cache records
488
- // --------------------------------------------------
489
- // copy of the source data.
490
- //
491
- // Note: cells in the columns of the source data which are part
492
- // of the "rows" or "columns" of the pivot table configuration are
493
- // replaced by references to their __cache field__ identifiers.
494
- // See "pivot cache definition" below.
495
-
496
- let xml = pivotCacheRecordsXform.toXml(pivotTable);
497
- zip.append(xml, {name: 'xl/pivotCache/pivotCacheRecords1.xml'});
498
-
499
- // pivot cache definition
500
- // --------------------------------------------------
501
- // cache source (source data):
502
- // ref="A1:E7" on sheet="Sheet1"
503
- // cache fields:
504
- // - 0: "A" (a1, a2, a3)
505
- // - 1: "B" (b1, b2)
506
- // - ...
507
-
508
- xml = pivotCacheDefinitionXform.toXml(pivotTable);
509
- zip.append(xml, {name: 'xl/pivotCache/pivotCacheDefinition1.xml'});
510
-
511
- xml = relsXform.toXml([
512
- {
513
- Id: 'rId1',
514
- Type: XLSX.RelType.PivotCacheRecords,
515
- Target: 'pivotCacheRecords1.xml',
516
- },
517
- ]);
518
- zip.append(xml, {name: 'xl/pivotCache/_rels/pivotCacheDefinition1.xml.rels'});
519
-
520
- // pivot tables (on destination worksheet)
521
- // --------------------------------------------------
522
- // location: ref="A3:E15"
523
- // pivotFields
524
- // rowFields and rowItems
525
- // colFields and colItems
526
- // dataFields
527
- // pivotTableStyleInfo
528
-
529
- xml = pivotTableXform.toXml(pivotTable);
530
- zip.append(xml, {name: 'xl/pivotTables/pivotTable1.xml'});
531
-
532
- xml = relsXform.toXml([
533
- {
534
- Id: 'rId1',
535
- Type: XLSX.RelType.PivotCacheDefinition,
536
- Target: '../pivotCache/pivotCacheDefinition1.xml',
537
- },
538
- ]);
539
- zip.append(xml, {name: 'xl/pivotTables/_rels/pivotTable1.xml.rels'});
540
- }
541
-
542
- async addContentTypes(zip, model) {
543
- const xform = new ContentTypesXform();
544
- const xml = xform.toXml(model);
545
- zip.append(xml, {name: '[Content_Types].xml'});
546
- }
547
-
548
- async addApp(zip, model) {
549
- const xform = new AppXform();
550
- const xml = xform.toXml(model);
551
- zip.append(xml, {name: 'docProps/app.xml'});
552
- }
553
-
554
- async addCore(zip, model) {
555
- const coreXform = new CoreXform();
556
- zip.append(coreXform.toXml(model), {name: 'docProps/core.xml'});
557
- }
558
-
559
- async addThemes(zip, model) {
560
- const themes = model.themes || {theme1: theme1Xml};
561
- Object.keys(themes).forEach(name => {
562
- const xml = themes[name];
563
- const path = `xl/theme/${name}.xml`;
564
- zip.append(xml, {name: path});
565
- });
566
- }
567
-
568
- async addOfficeRels(zip) {
569
- const xform = new RelationshipsXform();
570
- const xml = xform.toXml([
571
- {Id: 'rId1', Type: XLSX.RelType.OfficeDocument, Target: 'xl/workbook.xml'},
572
- {Id: 'rId2', Type: XLSX.RelType.CoreProperties, Target: 'docProps/core.xml'},
573
- {Id: 'rId3', Type: XLSX.RelType.ExtenderProperties, Target: 'docProps/app.xml'},
574
- ]);
575
- zip.append(xml, {name: '_rels/.rels'});
576
- }
577
-
578
- async addWorkbookRels(zip, model) {
579
- let count = 1;
580
- const relationships = [
581
- {Id: `rId${count++}`, Type: XLSX.RelType.Styles, Target: 'styles.xml'},
582
- {Id: `rId${count++}`, Type: XLSX.RelType.Theme, Target: 'theme/theme1.xml'},
583
- ];
584
- if (model.sharedStrings.count) {
585
- relationships.push({
586
- Id: `rId${count++}`,
587
- Type: XLSX.RelType.SharedStrings,
588
- Target: 'sharedStrings.xml',
589
- });
590
- }
591
- if ((model.pivotTables || []).length) {
592
- const pivotTable = model.pivotTables[0];
593
- pivotTable.rId = `rId${count++}`;
594
- relationships.push({
595
- Id: pivotTable.rId,
596
- Type: XLSX.RelType.PivotCacheDefinition,
597
- Target: 'pivotCache/pivotCacheDefinition1.xml',
598
- });
599
- }
600
- model.worksheets.forEach(worksheet => {
601
- worksheet.rId = `rId${count++}`;
602
- relationships.push({
603
- Id: worksheet.rId,
604
- Type: XLSX.RelType.Worksheet,
605
- Target: `worksheets/sheet${worksheet.id}.xml`,
606
- });
607
- });
608
- const xform = new RelationshipsXform();
609
- const xml = xform.toXml(relationships);
610
- zip.append(xml, {name: 'xl/_rels/workbook.xml.rels'});
611
- }
612
-
613
- async addSharedStrings(zip, model) {
614
- if (model.sharedStrings && model.sharedStrings.count) {
615
- zip.append(model.sharedStrings.xml, {name: 'xl/sharedStrings.xml'});
616
- }
617
- }
618
-
619
- async addStyles(zip, model) {
620
- const {xml} = model.styles;
621
- if (xml) {
622
- zip.append(xml, {name: 'xl/styles.xml'});
623
- }
624
- }
625
-
626
- async addWorkbook(zip, model) {
627
- const xform = new WorkbookXform();
628
- zip.append(xform.toXml(model), {name: 'xl/workbook.xml'});
629
- }
630
-
631
- async addWorksheets(zip, model) {
632
- // preparation phase
633
- const worksheetXform = new WorksheetXform();
634
- const relationshipsXform = new RelationshipsXform();
635
- const commentsXform = new CommentsXform();
636
- const vmlNotesXform = new VmlNotesXform();
637
-
638
- // write sheets
639
- model.worksheets.forEach(worksheet => {
640
- let xmlStream = new XmlStream();
641
- worksheetXform.render(xmlStream, worksheet);
642
- zip.append(xmlStream.xml, {name: `xl/worksheets/sheet${worksheet.id}.xml`});
643
-
644
- if (worksheet.rels && worksheet.rels.length) {
645
- xmlStream = new XmlStream();
646
- relationshipsXform.render(xmlStream, worksheet.rels);
647
- zip.append(xmlStream.xml, {name: `xl/worksheets/_rels/sheet${worksheet.id}.xml.rels`});
648
- }
649
-
650
- if (worksheet.comments.length > 0) {
651
- xmlStream = new XmlStream();
652
- commentsXform.render(xmlStream, worksheet);
653
- zip.append(xmlStream.xml, {name: `xl/comments${worksheet.id}.xml`});
654
-
655
- xmlStream = new XmlStream();
656
- vmlNotesXform.render(xmlStream, worksheet);
657
- zip.append(xmlStream.xml, {name: `xl/drawings/vmlDrawing${worksheet.id}.vml`});
658
- }
659
- });
660
- }
661
-
662
- _finalize(zip) {
663
- return new Promise((resolve, reject) => {
664
- zip.on('finish', () => {
665
- resolve(this);
666
- });
667
- zip.on('error', reject);
668
- zip.finalize();
669
- });
670
- }
671
-
672
- prepareModel(model, options) {
673
- // ensure following properties have sane values
674
- model.creator = model.creator || 'ExcelJS';
675
- model.lastModifiedBy = model.lastModifiedBy || 'ExcelJS';
676
- model.created = model.created || new Date();
677
- model.modified = model.modified || new Date();
678
-
679
- model.useSharedStrings = options.useSharedStrings !== undefined ? options.useSharedStrings : true;
680
- model.useStyles = options.useStyles !== undefined ? options.useStyles : true;
681
-
682
- // Manage the shared strings
683
- model.sharedStrings = new SharedStringsXform();
684
-
685
- // add a style manager to handle cell formats, fonts, etc.
686
- model.styles = model.useStyles ? new StylesXform(true) : new StylesXform.Mock();
687
-
688
- // prepare all of the things before the render
689
- const workbookXform = new WorkbookXform();
690
- const worksheetXform = new WorksheetXform();
691
-
692
- workbookXform.prepare(model);
693
-
694
- const worksheetOptions = {
695
- sharedStrings: model.sharedStrings,
696
- styles: model.styles,
697
- date1904: model.properties.date1904,
698
- drawingsCount: 0,
699
- media: model.media,
700
- };
701
- worksheetOptions.drawings = model.drawings = [];
702
- worksheetOptions.commentRefs = model.commentRefs = [];
703
- let tableCount = 0;
704
- model.tables = [];
705
- model.worksheets.forEach(worksheet => {
706
- // assign unique filenames to tables
707
- worksheet.tables.forEach(table => {
708
- tableCount++;
709
- table.target = `table${tableCount}.xml`;
710
- table.id = tableCount;
711
- model.tables.push(table);
712
- });
713
-
714
- worksheetXform.prepare(worksheet, worksheetOptions);
715
- });
716
-
717
- // TODO: workbook drawing list
718
- }
719
-
720
- async write(stream, options) {
721
- options = options || {};
722
- const {model} = this.workbook;
723
- const zip = new ZipStream.ZipWriter(options.zip);
724
- zip.pipe(stream);
725
-
726
- this.prepareModel(model, options);
727
-
728
- // render
729
- await this.addContentTypes(zip, model);
730
- await this.addOfficeRels(zip, model);
731
- await this.addWorkbookRels(zip, model);
732
- await this.addWorksheets(zip, model);
733
- await this.addSharedStrings(zip, model); // always after worksheets
734
- await this.addDrawings(zip, model);
735
- await this.addTables(zip, model);
736
- await this.addPivotTables(zip, model);
737
- await Promise.all([this.addThemes(zip, model), this.addStyles(zip, model)]);
738
- await this.addMedia(zip, model);
739
- await Promise.all([this.addApp(zip, model), this.addCore(zip, model)]);
740
- await this.addWorkbook(zip, model);
741
- return this._finalize(zip);
742
- }
743
-
744
- writeFile(filename, options) {
745
- const stream = fs.createWriteStream(filename);
746
-
747
- return new Promise((resolve, reject) => {
748
- stream.on('finish', () => {
749
- resolve();
750
- });
751
- stream.on('error', error => {
752
- reject(error);
753
- });
754
-
755
- this.write(stream, options)
756
- .then(() => {
757
- stream.end();
758
- })
759
- .catch(err => {
760
- reject(err);
761
- });
762
- });
763
- }
764
-
765
- async writeBuffer(options) {
766
- const stream = new StreamBuf();
767
- await this.write(stream, options);
768
- return stream.read();
769
- }
770
- }
771
-
772
- XLSX.RelType = require('./rel-type');
773
-
774
- module.exports = XLSX;
1
+ const fs = require('fs');
2
+ const JSZip = require('jszip');
3
+ const {PassThrough} = require('readable-stream');
4
+ const ZipStream = require('../utils/zip-stream');
5
+ const StreamBuf = require('../utils/stream-buf');
6
+
7
+ const utils = require('../utils/utils');
8
+ const XmlStream = require('../utils/xml-stream');
9
+ const {bufferToString} = require('../utils/browser-buffer-decode');
10
+
11
+ const StylesXform = require('./xform/style/styles-xform');
12
+
13
+ const CoreXform = require('./xform/core/core-xform');
14
+ const SharedStringsXform = require('./xform/strings/shared-strings-xform');
15
+ const RelationshipsXform = require('./xform/core/relationships-xform');
16
+ const ContentTypesXform = require('./xform/core/content-types-xform');
17
+ const AppXform = require('./xform/core/app-xform');
18
+ const WorkbookXform = require('./xform/book/workbook-xform');
19
+ const WorksheetXform = require('./xform/sheet/worksheet-xform');
20
+ const DrawingXform = require('./xform/drawing/drawing-xform');
21
+ const TableXform = require('./xform/table/table-xform');
22
+ const PivotCacheRecordsXform = require('./xform/pivot-table/pivot-cache-records-xform');
23
+ const PivotCacheDefinitionXform = require('./xform/pivot-table/pivot-cache-definition-xform');
24
+ const PivotTableXform = require('./xform/pivot-table/pivot-table-xform');
25
+ const CommentsXform = require('./xform/comment/comments-xform');
26
+ const VmlNotesXform = require('./xform/comment/vml-notes-xform');
27
+
28
+ const theme1Xml = require('./xml/theme1');
29
+
30
+ function fsReadFileAsync(filename, options) {
31
+ return new Promise((resolve, reject) => {
32
+ fs.readFile(filename, options, (error, data) => {
33
+ if (error) {
34
+ reject(error);
35
+ } else {
36
+ resolve(data);
37
+ }
38
+ });
39
+ });
40
+ }
41
+
42
+ class XLSX {
43
+ constructor(workbook) {
44
+ this.workbook = workbook;
45
+ }
46
+
47
+ // ===============================================================================
48
+ // Workbook
49
+ // =========================================================================
50
+ // Read
51
+
52
+ async readFile(filename, options) {
53
+ if (!(await utils.fs.exists(filename))) {
54
+ throw new Error(`File not found: ${filename}`);
55
+ }
56
+ const stream = fs.createReadStream(filename);
57
+ try {
58
+ const workbook = await this.read(stream, options);
59
+ stream.close();
60
+ return workbook;
61
+ } catch (error) {
62
+ stream.close();
63
+ throw error;
64
+ }
65
+ }
66
+
67
+ parseRels(stream) {
68
+ const xform = new RelationshipsXform();
69
+ return xform.parseStream(stream);
70
+ }
71
+
72
+ parseWorkbook(stream) {
73
+ const xform = new WorkbookXform();
74
+ return xform.parseStream(stream);
75
+ }
76
+
77
+ parseSharedStrings(stream) {
78
+ const xform = new SharedStringsXform();
79
+ return xform.parseStream(stream);
80
+ }
81
+
82
+ reconcile(model, options) {
83
+ const workbookXform = new WorkbookXform();
84
+ const worksheetXform = new WorksheetXform(options);
85
+ const drawingXform = new DrawingXform();
86
+ const tableXform = new TableXform();
87
+
88
+ workbookXform.reconcile(model);
89
+
90
+ // reconcile drawings with their rels
91
+ const drawingOptions = {
92
+ media: model.media,
93
+ mediaIndex: model.mediaIndex,
94
+ };
95
+ Object.keys(model.drawings).forEach(name => {
96
+ const drawing = model.drawings[name];
97
+ const drawingRel = model.drawingRels[name];
98
+ if (drawingRel) {
99
+ drawingOptions.rels = drawingRel.reduce((o, rel) => {
100
+ o[rel.Id] = rel;
101
+ return o;
102
+ }, {});
103
+ (drawing.anchors || []).forEach(anchor => {
104
+ const hyperlinks = anchor.picture && anchor.picture.hyperlinks;
105
+ if (hyperlinks && drawingOptions.rels[hyperlinks.rId]) {
106
+ hyperlinks.hyperlink = drawingOptions.rels[hyperlinks.rId].Target;
107
+ delete hyperlinks.rId;
108
+ }
109
+ });
110
+ drawingXform.reconcile(drawing, drawingOptions);
111
+ }
112
+ });
113
+
114
+ // reconcile tables with the default styles
115
+ const tableOptions = {
116
+ styles: model.styles,
117
+ };
118
+ Object.values(model.tables).forEach(table => {
119
+ tableXform.reconcile(table, tableOptions);
120
+ });
121
+
122
+ const sheetOptions = {
123
+ styles: model.styles,
124
+ sharedStrings: model.sharedStrings,
125
+ media: model.media,
126
+ mediaIndex: model.mediaIndex,
127
+ date1904: model.properties && model.properties.date1904,
128
+ drawings: model.drawings,
129
+ comments: model.comments,
130
+ tables: model.tables,
131
+ vmlDrawings: model.vmlDrawings,
132
+ };
133
+ model.worksheets.forEach(worksheet => {
134
+ worksheet.relationships = model.worksheetRels[worksheet.sheetNo];
135
+ worksheetXform.reconcile(worksheet, sheetOptions);
136
+ });
137
+
138
+ // delete unnecessary parts
139
+ delete model.worksheetHash;
140
+ delete model.worksheetRels;
141
+ delete model.globalRels;
142
+ delete model.sharedStrings;
143
+ delete model.workbookRels;
144
+ delete model.sheetDefs;
145
+ delete model.styles;
146
+ delete model.mediaIndex;
147
+ delete model.drawings;
148
+ delete model.drawingRels;
149
+ delete model.vmlDrawings;
150
+ }
151
+
152
+ async _processWorksheetEntry(stream, model, sheetNo, options, path) {
153
+ const xform = new WorksheetXform(options);
154
+ const worksheet = await xform.parseStream(stream);
155
+ worksheet.sheetNo = sheetNo;
156
+ model.worksheetHash[path] = worksheet;
157
+ model.worksheets.push(worksheet);
158
+ }
159
+
160
+ async _processCommentEntry(stream, model, name) {
161
+ const xform = new CommentsXform();
162
+ const comments = await xform.parseStream(stream);
163
+ model.comments[`../${name}.xml`] = comments;
164
+ }
165
+
166
+ async _processTableEntry(stream, model, name) {
167
+ const xform = new TableXform();
168
+ const table = await xform.parseStream(stream);
169
+ model.tables[`../tables/${name}.xml`] = table;
170
+ }
171
+
172
+ async _processWorksheetRelsEntry(stream, model, sheetNo) {
173
+ const xform = new RelationshipsXform();
174
+ const relationships = await xform.parseStream(stream);
175
+ model.worksheetRels[sheetNo] = relationships;
176
+ }
177
+
178
+ async _processMediaEntry(entry, model, filename) {
179
+ const lastDot = filename.lastIndexOf('.');
180
+ // if we can't determine extension, ignore it
181
+ if (lastDot >= 1) {
182
+ const extension = filename.substr(lastDot + 1);
183
+ const name = filename.substr(0, lastDot);
184
+ await new Promise((resolve, reject) => {
185
+ const streamBuf = new StreamBuf();
186
+ streamBuf.on('finish', () => {
187
+ model.mediaIndex[filename] = model.media.length;
188
+ model.mediaIndex[name] = model.media.length;
189
+ const medium = {
190
+ type: 'image',
191
+ name,
192
+ extension,
193
+ buffer: streamBuf.toBuffer(),
194
+ };
195
+ model.media.push(medium);
196
+ resolve();
197
+ });
198
+ entry.on('error', error => {
199
+ reject(error);
200
+ });
201
+ entry.pipe(streamBuf);
202
+ });
203
+ }
204
+ }
205
+
206
+ async _processDrawingEntry(entry, model, name) {
207
+ const xform = new DrawingXform();
208
+ const drawing = await xform.parseStream(entry);
209
+ model.drawings[name] = drawing;
210
+ }
211
+
212
+ async _processDrawingRelsEntry(entry, model, name) {
213
+ const xform = new RelationshipsXform();
214
+ const relationships = await xform.parseStream(entry);
215
+ model.drawingRels[name] = relationships;
216
+ }
217
+
218
+ async _processVmlDrawingEntry(entry, model, name) {
219
+ const xform = new VmlNotesXform();
220
+ const vmlDrawing = await xform.parseStream(entry);
221
+ model.vmlDrawings[`../drawings/${name}.vml`] = vmlDrawing;
222
+ }
223
+
224
+ async _processThemeEntry(entry, model, name) {
225
+ await new Promise((resolve, reject) => {
226
+ // TODO: stream entry into buffer and store the xml in the model.themes[]
227
+ const stream = new StreamBuf();
228
+ entry.on('error', reject);
229
+ stream.on('error', reject);
230
+ stream.on('finish', () => {
231
+ model.themes[name] = stream.read().toString();
232
+ resolve();
233
+ });
234
+ entry.pipe(stream);
235
+ });
236
+ }
237
+
238
+ /**
239
+ * @deprecated since version 4.0. You should use `#read` instead. Please follow upgrade instruction: https://github.com/exceljs/exceljs/blob/master/UPGRADE-4.0.md
240
+ */
241
+ createInputStream() {
242
+ throw new Error(
243
+ '`XLSX#createInputStream` is deprecated. You should use `XLSX#read` instead. This method will be removed in version 5.0. Please follow upgrade instruction: https://github.com/exceljs/exceljs/blob/master/UPGRADE-4.0.md'
244
+ );
245
+ }
246
+
247
+ async read(stream, options) {
248
+ // TODO: Remove once node v8 is deprecated
249
+ // Detect and upgrade old streams
250
+ if (!stream[Symbol.asyncIterator] && stream.pipe) {
251
+ stream = stream.pipe(new PassThrough());
252
+ }
253
+ const chunks = [];
254
+ for await (const chunk of stream) {
255
+ chunks.push(chunk);
256
+ }
257
+ return this.load(Buffer.concat(chunks), options);
258
+ }
259
+
260
+ async load(data, options) {
261
+ let buffer;
262
+ if (options && options.base64) {
263
+ buffer = Buffer.from(data.toString(), 'base64');
264
+ } else {
265
+ buffer = data;
266
+ }
267
+
268
+ const model = {
269
+ worksheets: [],
270
+ worksheetHash: {},
271
+ worksheetRels: [],
272
+ themes: {},
273
+ media: [],
274
+ mediaIndex: {},
275
+ drawings: {},
276
+ drawingRels: {},
277
+ comments: {},
278
+ tables: {},
279
+ vmlDrawings: {},
280
+ };
281
+
282
+ const zip = await JSZip.loadAsync(buffer);
283
+ for (const entry of Object.values(zip.files)) {
284
+ /* eslint-disable no-await-in-loop */
285
+ if (!entry.dir) {
286
+ let entryName = entry.name;
287
+ if (entryName[0] === '/') {
288
+ entryName = entryName.substr(1);
289
+ }
290
+ let stream;
291
+ if (
292
+ entryName.match(/xl\/media\//) ||
293
+ // themes are not parsed as stream
294
+ entryName.match(/xl\/theme\/([a-zA-Z0-9]+)[.]xml/)
295
+ ) {
296
+ stream = new PassThrough();
297
+ stream.write(await entry.async('nodebuffer'));
298
+ } else {
299
+ // use object mode to avoid buffer-string convention
300
+ stream = new PassThrough({
301
+ writableObjectMode: true,
302
+ readableObjectMode: true,
303
+ });
304
+ let content;
305
+ // https://www.npmjs.com/package/process
306
+ if (process.browser) {
307
+ // running in browser, use TextDecoder if possible
308
+ content = bufferToString(await entry.async('nodebuffer'));
309
+ } else {
310
+ // running in node.js
311
+ content = await entry.async('string');
312
+ }
313
+ const chunkSize = 16 * 1024;
314
+ for (let i = 0; i < content.length; i += chunkSize) {
315
+ stream.write(content.substring(i, i + chunkSize));
316
+ }
317
+ }
318
+ stream.end();
319
+ switch (entryName) {
320
+ case '_rels/.rels':
321
+ model.globalRels = await this.parseRels(stream);
322
+ break;
323
+
324
+ case 'xl/workbook.xml': {
325
+ const workbook = await this.parseWorkbook(stream);
326
+ model.sheets = workbook.sheets;
327
+ model.definedNames = workbook.definedNames;
328
+ model.views = workbook.views;
329
+ model.properties = workbook.properties;
330
+ model.calcProperties = workbook.calcProperties;
331
+ break;
332
+ }
333
+
334
+ case 'xl/_rels/workbook.xml.rels':
335
+ model.workbookRels = await this.parseRels(stream);
336
+ break;
337
+
338
+ case 'xl/sharedStrings.xml':
339
+ model.sharedStrings = new SharedStringsXform();
340
+ await model.sharedStrings.parseStream(stream);
341
+ break;
342
+
343
+ case 'xl/styles.xml':
344
+ model.styles = new StylesXform();
345
+ await model.styles.parseStream(stream);
346
+ break;
347
+
348
+ case 'docProps/app.xml': {
349
+ const appXform = new AppXform();
350
+ const appProperties = await appXform.parseStream(stream);
351
+ model.company = appProperties.company;
352
+ model.manager = appProperties.manager;
353
+ break;
354
+ }
355
+
356
+ case 'docProps/core.xml': {
357
+ const coreXform = new CoreXform();
358
+ const coreProperties = await coreXform.parseStream(stream);
359
+ Object.assign(model, coreProperties);
360
+ break;
361
+ }
362
+
363
+ default: {
364
+ let match = entryName.match(/xl\/worksheets\/sheet(\d+)[.]xml/);
365
+ if (match) {
366
+ await this._processWorksheetEntry(stream, model, match[1], options, entryName);
367
+ break;
368
+ }
369
+ match = entryName.match(/xl\/worksheets\/_rels\/sheet(\d+)[.]xml.rels/);
370
+ if (match) {
371
+ await this._processWorksheetRelsEntry(stream, model, match[1]);
372
+ break;
373
+ }
374
+ match = entryName.match(/xl\/theme\/([a-zA-Z0-9]+)[.]xml/);
375
+ if (match) {
376
+ await this._processThemeEntry(stream, model, match[1]);
377
+ break;
378
+ }
379
+ match = entryName.match(/xl\/media\/([a-zA-Z0-9]+[.][a-zA-Z0-9]{3,4})$/);
380
+ if (match) {
381
+ await this._processMediaEntry(stream, model, match[1]);
382
+ break;
383
+ }
384
+ match = entryName.match(/xl\/drawings\/([a-zA-Z0-9]+)[.]xml/);
385
+ if (match) {
386
+ await this._processDrawingEntry(stream, model, match[1]);
387
+ break;
388
+ }
389
+ match = entryName.match(/xl\/(comments\d+)[.]xml/);
390
+ if (match) {
391
+ await this._processCommentEntry(stream, model, match[1]);
392
+ break;
393
+ }
394
+ match = entryName.match(/xl\/tables\/(table\d+)[.]xml/);
395
+ if (match) {
396
+ await this._processTableEntry(stream, model, match[1]);
397
+ break;
398
+ }
399
+ match = entryName.match(/xl\/drawings\/_rels\/([a-zA-Z0-9]+)[.]xml[.]rels/);
400
+ if (match) {
401
+ await this._processDrawingRelsEntry(stream, model, match[1]);
402
+ break;
403
+ }
404
+ match = entryName.match(/xl\/drawings\/(vmlDrawing\d+)[.]vml/);
405
+ if (match) {
406
+ await this._processVmlDrawingEntry(stream, model, match[1]);
407
+ break;
408
+ }
409
+ }
410
+ }
411
+ }
412
+ }
413
+
414
+ this.reconcile(model, options);
415
+
416
+ // apply model
417
+ this.workbook.model = model;
418
+ return this.workbook;
419
+ }
420
+
421
+ // =========================================================================
422
+ // Write
423
+
424
+ async addMedia(zip, model) {
425
+ await Promise.all(
426
+ model.media.map(async medium => {
427
+ if (medium.type === 'image') {
428
+ const filename = `xl/media/${medium.name}.${medium.extension}`;
429
+ if (medium.filename) {
430
+ const data = await fsReadFileAsync(medium.filename);
431
+ return zip.append(data, {name: filename});
432
+ }
433
+ if (medium.buffer) {
434
+ return zip.append(medium.buffer, {name: filename});
435
+ }
436
+ if (medium.base64) {
437
+ const dataimg64 = medium.base64;
438
+ const content = dataimg64.substring(dataimg64.indexOf(',') + 1);
439
+ return zip.append(content, {name: filename, base64: true});
440
+ }
441
+ }
442
+ throw new Error('Unsupported media');
443
+ })
444
+ );
445
+ }
446
+
447
+ addDrawings(zip, model) {
448
+ const drawingXform = new DrawingXform();
449
+ const relsXform = new RelationshipsXform();
450
+
451
+ model.worksheets.forEach(worksheet => {
452
+ const {drawing} = worksheet;
453
+ if (drawing) {
454
+ drawingXform.prepare(drawing, {});
455
+ let xml = drawingXform.toXml(drawing);
456
+ zip.append(xml, {name: `xl/drawings/${drawing.name}.xml`});
457
+
458
+ xml = relsXform.toXml(drawing.rels);
459
+ zip.append(xml, {name: `xl/drawings/_rels/${drawing.name}.xml.rels`});
460
+ }
461
+ });
462
+ }
463
+
464
+ addTables(zip, model) {
465
+ const tableXform = new TableXform();
466
+
467
+ model.worksheets.forEach(worksheet => {
468
+ const {tables} = worksheet;
469
+ tables.forEach(table => {
470
+ tableXform.prepare(table, {});
471
+ const tableXml = tableXform.toXml(table);
472
+ zip.append(tableXml, {name: `xl/tables/${table.target}`});
473
+ });
474
+ });
475
+ }
476
+
477
+ addPivotTables(zip, model) {
478
+ if (!model.pivotTables.length) return;
479
+
480
+ const pivotTable = model.pivotTables[0];
481
+
482
+ const pivotCacheRecordsXform = new PivotCacheRecordsXform();
483
+ const pivotCacheDefinitionXform = new PivotCacheDefinitionXform();
484
+ const pivotTableXform = new PivotTableXform();
485
+ const relsXform = new RelationshipsXform();
486
+
487
+ // pivot cache records
488
+ // --------------------------------------------------
489
+ // copy of the source data.
490
+ //
491
+ // Note: cells in the columns of the source data which are part
492
+ // of the "rows" or "columns" of the pivot table configuration are
493
+ // replaced by references to their __cache field__ identifiers.
494
+ // See "pivot cache definition" below.
495
+
496
+ let xml = pivotCacheRecordsXform.toXml(pivotTable);
497
+ zip.append(xml, {name: 'xl/pivotCache/pivotCacheRecords1.xml'});
498
+
499
+ // pivot cache definition
500
+ // --------------------------------------------------
501
+ // cache source (source data):
502
+ // ref="A1:E7" on sheet="Sheet1"
503
+ // cache fields:
504
+ // - 0: "A" (a1, a2, a3)
505
+ // - 1: "B" (b1, b2)
506
+ // - ...
507
+
508
+ xml = pivotCacheDefinitionXform.toXml(pivotTable);
509
+ zip.append(xml, {name: 'xl/pivotCache/pivotCacheDefinition1.xml'});
510
+
511
+ xml = relsXform.toXml([
512
+ {
513
+ Id: 'rId1',
514
+ Type: XLSX.RelType.PivotCacheRecords,
515
+ Target: 'pivotCacheRecords1.xml',
516
+ },
517
+ ]);
518
+ zip.append(xml, {name: 'xl/pivotCache/_rels/pivotCacheDefinition1.xml.rels'});
519
+
520
+ // pivot tables (on destination worksheet)
521
+ // --------------------------------------------------
522
+ // location: ref="A3:E15"
523
+ // pivotFields
524
+ // rowFields and rowItems
525
+ // colFields and colItems
526
+ // dataFields
527
+ // pivotTableStyleInfo
528
+
529
+ xml = pivotTableXform.toXml(pivotTable);
530
+ zip.append(xml, {name: 'xl/pivotTables/pivotTable1.xml'});
531
+
532
+ xml = relsXform.toXml([
533
+ {
534
+ Id: 'rId1',
535
+ Type: XLSX.RelType.PivotCacheDefinition,
536
+ Target: '../pivotCache/pivotCacheDefinition1.xml',
537
+ },
538
+ ]);
539
+ zip.append(xml, {name: 'xl/pivotTables/_rels/pivotTable1.xml.rels'});
540
+ }
541
+
542
+ async addContentTypes(zip, model) {
543
+ const xform = new ContentTypesXform();
544
+ const xml = xform.toXml(model);
545
+ zip.append(xml, {name: '[Content_Types].xml'});
546
+ }
547
+
548
+ async addApp(zip, model) {
549
+ const xform = new AppXform();
550
+ const xml = xform.toXml(model);
551
+ zip.append(xml, {name: 'docProps/app.xml'});
552
+ }
553
+
554
+ async addCore(zip, model) {
555
+ const coreXform = new CoreXform();
556
+ zip.append(coreXform.toXml(model), {name: 'docProps/core.xml'});
557
+ }
558
+
559
+ async addThemes(zip, model) {
560
+ const themes = model.themes || {theme1: theme1Xml};
561
+ Object.keys(themes).forEach(name => {
562
+ const xml = themes[name];
563
+ const path = `xl/theme/${name}.xml`;
564
+ zip.append(xml, {name: path});
565
+ });
566
+ }
567
+
568
+ async addOfficeRels(zip) {
569
+ const xform = new RelationshipsXform();
570
+ const xml = xform.toXml([
571
+ {Id: 'rId1', Type: XLSX.RelType.OfficeDocument, Target: 'xl/workbook.xml'},
572
+ {Id: 'rId2', Type: XLSX.RelType.CoreProperties, Target: 'docProps/core.xml'},
573
+ {Id: 'rId3', Type: XLSX.RelType.ExtenderProperties, Target: 'docProps/app.xml'},
574
+ ]);
575
+ zip.append(xml, {name: '_rels/.rels'});
576
+ }
577
+
578
+ async addWorkbookRels(zip, model) {
579
+ let count = 1;
580
+ const relationships = [
581
+ {Id: `rId${count++}`, Type: XLSX.RelType.Styles, Target: 'styles.xml'},
582
+ {Id: `rId${count++}`, Type: XLSX.RelType.Theme, Target: 'theme/theme1.xml'},
583
+ ];
584
+ if (model.sharedStrings.count) {
585
+ relationships.push({
586
+ Id: `rId${count++}`,
587
+ Type: XLSX.RelType.SharedStrings,
588
+ Target: 'sharedStrings.xml',
589
+ });
590
+ }
591
+ if ((model.pivotTables || []).length) {
592
+ const pivotTable = model.pivotTables[0];
593
+ pivotTable.rId = `rId${count++}`;
594
+ relationships.push({
595
+ Id: pivotTable.rId,
596
+ Type: XLSX.RelType.PivotCacheDefinition,
597
+ Target: 'pivotCache/pivotCacheDefinition1.xml',
598
+ });
599
+ }
600
+ model.worksheets.forEach(worksheet => {
601
+ worksheet.rId = `rId${count++}`;
602
+ relationships.push({
603
+ Id: worksheet.rId,
604
+ Type: XLSX.RelType.Worksheet,
605
+ Target: `worksheets/sheet${worksheet.id}.xml`,
606
+ });
607
+ });
608
+ const xform = new RelationshipsXform();
609
+ const xml = xform.toXml(relationships);
610
+ zip.append(xml, {name: 'xl/_rels/workbook.xml.rels'});
611
+ }
612
+
613
+ async addSharedStrings(zip, model) {
614
+ if (model.sharedStrings && model.sharedStrings.count) {
615
+ zip.append(model.sharedStrings.xml, {name: 'xl/sharedStrings.xml'});
616
+ }
617
+ }
618
+
619
+ async addStyles(zip, model) {
620
+ const {xml} = model.styles;
621
+ if (xml) {
622
+ zip.append(xml, {name: 'xl/styles.xml'});
623
+ }
624
+ }
625
+
626
+ async addWorkbook(zip, model) {
627
+ const xform = new WorkbookXform();
628
+ zip.append(xform.toXml(model), {name: 'xl/workbook.xml'});
629
+ }
630
+
631
+ async addWorksheets(zip, model) {
632
+ // preparation phase
633
+ const worksheetXform = new WorksheetXform();
634
+ const relationshipsXform = new RelationshipsXform();
635
+ const commentsXform = new CommentsXform();
636
+ const vmlNotesXform = new VmlNotesXform();
637
+
638
+ // write sheets
639
+ model.worksheets.forEach(worksheet => {
640
+ let xmlStream = new XmlStream();
641
+ worksheetXform.render(xmlStream, worksheet);
642
+ zip.append(xmlStream.xml, {name: `xl/worksheets/sheet${worksheet.id}.xml`});
643
+
644
+ if (worksheet.rels && worksheet.rels.length) {
645
+ xmlStream = new XmlStream();
646
+ relationshipsXform.render(xmlStream, worksheet.rels);
647
+ zip.append(xmlStream.xml, {name: `xl/worksheets/_rels/sheet${worksheet.id}.xml.rels`});
648
+ }
649
+
650
+ if (worksheet.comments.length > 0) {
651
+ xmlStream = new XmlStream();
652
+ commentsXform.render(xmlStream, worksheet);
653
+ zip.append(xmlStream.xml, {name: `xl/comments${worksheet.id}.xml`});
654
+
655
+ xmlStream = new XmlStream();
656
+ vmlNotesXform.render(xmlStream, worksheet);
657
+ zip.append(xmlStream.xml, {name: `xl/drawings/vmlDrawing${worksheet.id}.vml`});
658
+ }
659
+ });
660
+ }
661
+
662
+ _finalize(zip) {
663
+ return new Promise((resolve, reject) => {
664
+ zip.on('finish', () => {
665
+ resolve(this);
666
+ });
667
+ zip.on('error', reject);
668
+ zip.finalize();
669
+ });
670
+ }
671
+
672
+ prepareModel(model, options) {
673
+ // ensure following properties have sane values
674
+ model.creator = model.creator || 'ExcelJS';
675
+ model.lastModifiedBy = model.lastModifiedBy || 'ExcelJS';
676
+ model.created = model.created || new Date();
677
+ model.modified = model.modified || new Date();
678
+
679
+ model.useSharedStrings = options.useSharedStrings !== undefined ? options.useSharedStrings : true;
680
+ model.useStyles = options.useStyles !== undefined ? options.useStyles : true;
681
+
682
+ // Manage the shared strings
683
+ model.sharedStrings = new SharedStringsXform();
684
+
685
+ // add a style manager to handle cell formats, fonts, etc.
686
+ model.styles = model.useStyles ? new StylesXform(true) : new StylesXform.Mock();
687
+
688
+ // prepare all of the things before the render
689
+ const workbookXform = new WorkbookXform();
690
+ const worksheetXform = new WorksheetXform();
691
+
692
+ workbookXform.prepare(model);
693
+
694
+ const worksheetOptions = {
695
+ sharedStrings: model.sharedStrings,
696
+ styles: model.styles,
697
+ date1904: model.properties.date1904,
698
+ drawingsCount: 0,
699
+ media: model.media,
700
+ };
701
+ worksheetOptions.drawings = model.drawings = [];
702
+ worksheetOptions.commentRefs = model.commentRefs = [];
703
+ let tableCount = 0;
704
+ model.tables = [];
705
+ model.worksheets.forEach(worksheet => {
706
+ // assign unique filenames to tables
707
+ worksheet.tables.forEach(table => {
708
+ tableCount++;
709
+ table.target = `table${tableCount}.xml`;
710
+ table.id = tableCount;
711
+ model.tables.push(table);
712
+ });
713
+
714
+ worksheetXform.prepare(worksheet, worksheetOptions);
715
+ });
716
+
717
+ // TODO: workbook drawing list
718
+ }
719
+
720
+ async write(stream, options) {
721
+ options = options || {};
722
+ const {model} = this.workbook;
723
+ const zip = new ZipStream.ZipWriter(options.zip);
724
+ zip.pipe(stream);
725
+
726
+ this.prepareModel(model, options);
727
+
728
+ // render
729
+ await this.addContentTypes(zip, model);
730
+ await this.addOfficeRels(zip, model);
731
+ await this.addWorkbookRels(zip, model);
732
+ await this.addWorksheets(zip, model);
733
+ await this.addSharedStrings(zip, model); // always after worksheets
734
+ await this.addDrawings(zip, model);
735
+ await this.addTables(zip, model);
736
+ await this.addPivotTables(zip, model);
737
+ await Promise.all([this.addThemes(zip, model), this.addStyles(zip, model)]);
738
+ await this.addMedia(zip, model);
739
+ await Promise.all([this.addApp(zip, model), this.addCore(zip, model)]);
740
+ await this.addWorkbook(zip, model);
741
+ return this._finalize(zip);
742
+ }
743
+
744
+ writeFile(filename, options) {
745
+ const stream = fs.createWriteStream(filename);
746
+
747
+ return new Promise((resolve, reject) => {
748
+ stream.on('finish', () => {
749
+ resolve();
750
+ });
751
+ stream.on('error', error => {
752
+ reject(error);
753
+ });
754
+
755
+ this.write(stream, options)
756
+ .then(() => {
757
+ stream.end();
758
+ })
759
+ .catch(err => {
760
+ reject(err);
761
+ });
762
+ });
763
+ }
764
+
765
+ async writeBuffer(options) {
766
+ const stream = new StreamBuf();
767
+ await this.write(stream, options);
768
+ return stream.read();
769
+ }
770
+ }
771
+
772
+ XLSX.RelType = require('./rel-type');
773
+
774
+ module.exports = XLSX;