@lyit/exceljs 4.4.1

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 (543) hide show
  1. package/LICENSE +22 -0
  2. package/README.md +3398 -0
  3. package/README_zh.md +2878 -0
  4. package/dist/LICENSE +22 -0
  5. package/dist/es5/csv/csv.js +182 -0
  6. package/dist/es5/csv/csv.js.map +1 -0
  7. package/dist/es5/csv/line-buffer.js +68 -0
  8. package/dist/es5/csv/line-buffer.js.map +1 -0
  9. package/dist/es5/csv/stream-converter.js +110 -0
  10. package/dist/es5/csv/stream-converter.js.map +1 -0
  11. package/dist/es5/doc/anchor.js +73 -0
  12. package/dist/es5/doc/anchor.js.map +1 -0
  13. package/dist/es5/doc/cell.js +960 -0
  14. package/dist/es5/doc/cell.js.map +1 -0
  15. package/dist/es5/doc/column.js +274 -0
  16. package/dist/es5/doc/column.js.map +1 -0
  17. package/dist/es5/doc/data-validations.js +18 -0
  18. package/dist/es5/doc/data-validations.js.map +1 -0
  19. package/dist/es5/doc/defined-names.js +173 -0
  20. package/dist/es5/doc/defined-names.js.map +1 -0
  21. package/dist/es5/doc/enums.js +49 -0
  22. package/dist/es5/doc/enums.js.map +1 -0
  23. package/dist/es5/doc/form-checkbox.js +342 -0
  24. package/dist/es5/doc/form-checkbox.js.map +1 -0
  25. package/dist/es5/doc/image.js +69 -0
  26. package/dist/es5/doc/image.js.map +1 -0
  27. package/dist/es5/doc/modelcontainer.js +16 -0
  28. package/dist/es5/doc/modelcontainer.js.map +1 -0
  29. package/dist/es5/doc/note.js +64 -0
  30. package/dist/es5/doc/note.js.map +1 -0
  31. package/dist/es5/doc/pivot-table.js +247 -0
  32. package/dist/es5/doc/pivot-table.js.map +1 -0
  33. package/dist/es5/doc/range.js +229 -0
  34. package/dist/es5/doc/range.js.map +1 -0
  35. package/dist/es5/doc/row.js +391 -0
  36. package/dist/es5/doc/row.js.map +1 -0
  37. package/dist/es5/doc/table.js +542 -0
  38. package/dist/es5/doc/table.js.map +1 -0
  39. package/dist/es5/doc/workbook.js +221 -0
  40. package/dist/es5/doc/workbook.js.map +1 -0
  41. package/dist/es5/doc/worksheet.js +996 -0
  42. package/dist/es5/doc/worksheet.js.map +1 -0
  43. package/dist/es5/exceljs.bare.js +14 -0
  44. package/dist/es5/exceljs.bare.js.map +1 -0
  45. package/dist/es5/exceljs.browser.js +36 -0
  46. package/dist/es5/exceljs.browser.js.map +1 -0
  47. package/dist/es5/exceljs.nodejs.js +15 -0
  48. package/dist/es5/exceljs.nodejs.js.map +1 -0
  49. package/dist/es5/index.js +15 -0
  50. package/dist/es5/stream/xlsx/hyperlink-reader.js +90 -0
  51. package/dist/es5/stream/xlsx/hyperlink-reader.js.map +1 -0
  52. package/dist/es5/stream/xlsx/sheet-comments-writer.js +94 -0
  53. package/dist/es5/stream/xlsx/sheet-comments-writer.js.map +1 -0
  54. package/dist/es5/stream/xlsx/sheet-rels-writer.js +94 -0
  55. package/dist/es5/stream/xlsx/sheet-rels-writer.js.map +1 -0
  56. package/dist/es5/stream/xlsx/workbook-reader.js +361 -0
  57. package/dist/es5/stream/xlsx/workbook-reader.js.map +1 -0
  58. package/dist/es5/stream/xlsx/workbook-writer.js +347 -0
  59. package/dist/es5/stream/xlsx/workbook-writer.js.map +1 -0
  60. package/dist/es5/stream/xlsx/worksheet-reader.js +392 -0
  61. package/dist/es5/stream/xlsx/worksheet-reader.js.map +1 -0
  62. package/dist/es5/stream/xlsx/worksheet-writer.js +652 -0
  63. package/dist/es5/stream/xlsx/worksheet-writer.js.map +1 -0
  64. package/dist/es5/utils/auto-drain.js +18 -0
  65. package/dist/es5/utils/auto-drain.js.map +1 -0
  66. package/dist/es5/utils/browser-buffer-decode.js +15 -0
  67. package/dist/es5/utils/browser-buffer-decode.js.map +1 -0
  68. package/dist/es5/utils/browser-buffer-encode.js +18 -0
  69. package/dist/es5/utils/browser-buffer-encode.js.map +1 -0
  70. package/dist/es5/utils/cell-matrix.js +149 -0
  71. package/dist/es5/utils/cell-matrix.js.map +1 -0
  72. package/dist/es5/utils/col-cache.js +258 -0
  73. package/dist/es5/utils/col-cache.js.map +1 -0
  74. package/dist/es5/utils/copy-style.js +43 -0
  75. package/dist/es5/utils/copy-style.js.map +1 -0
  76. package/dist/es5/utils/encryptor.js +58 -0
  77. package/dist/es5/utils/encryptor.js.map +1 -0
  78. package/dist/es5/utils/iterate-stream.js +46 -0
  79. package/dist/es5/utils/iterate-stream.js.map +1 -0
  80. package/dist/es5/utils/parse-sax.js +66 -0
  81. package/dist/es5/utils/parse-sax.js.map +1 -0
  82. package/dist/es5/utils/shared-formula.js +42 -0
  83. package/dist/es5/utils/shared-formula.js.map +1 -0
  84. package/dist/es5/utils/shared-strings.js +37 -0
  85. package/dist/es5/utils/shared-strings.js.map +1 -0
  86. package/dist/es5/utils/stream-base64.js +66 -0
  87. package/dist/es5/utils/stream-base64.js.map +1 -0
  88. package/dist/es5/utils/stream-buf.js +365 -0
  89. package/dist/es5/utils/stream-buf.js.map +1 -0
  90. package/dist/es5/utils/string-buf.js +73 -0
  91. package/dist/es5/utils/string-buf.js.map +1 -0
  92. package/dist/es5/utils/string-builder.js +32 -0
  93. package/dist/es5/utils/string-builder.js.map +1 -0
  94. package/dist/es5/utils/stuttered-pipe.js +61 -0
  95. package/dist/es5/utils/stuttered-pipe.js.map +1 -0
  96. package/dist/es5/utils/typed-stack.js +23 -0
  97. package/dist/es5/utils/typed-stack.js.map +1 -0
  98. package/dist/es5/utils/under-dash.js +168 -0
  99. package/dist/es5/utils/under-dash.js.map +1 -0
  100. package/dist/es5/utils/utils.js +205 -0
  101. package/dist/es5/utils/utils.js.map +1 -0
  102. package/dist/es5/utils/xml-stream.js +151 -0
  103. package/dist/es5/utils/xml-stream.js.map +1 -0
  104. package/dist/es5/utils/zip-stream.js +79 -0
  105. package/dist/es5/utils/zip-stream.js.map +1 -0
  106. package/dist/es5/xlsx/defaultnumformats.js +230 -0
  107. package/dist/es5/xlsx/defaultnumformats.js.map +1 -0
  108. package/dist/es5/xlsx/rel-type.js +22 -0
  109. package/dist/es5/xlsx/rel-type.js.map +1 -0
  110. package/dist/es5/xlsx/xform/base-xform.js +139 -0
  111. package/dist/es5/xlsx/xform/base-xform.js.map +1 -0
  112. package/dist/es5/xlsx/xform/book/defined-name-xform.js +85 -0
  113. package/dist/es5/xlsx/xform/book/defined-name-xform.js.map +1 -0
  114. package/dist/es5/xlsx/xform/book/sheet-xform.js +32 -0
  115. package/dist/es5/xlsx/xform/book/sheet-xform.js.map +1 -0
  116. package/dist/es5/xlsx/xform/book/workbook-calc-properties-xform.js +24 -0
  117. package/dist/es5/xlsx/xform/book/workbook-calc-properties-xform.js.map +1 -0
  118. package/dist/es5/xlsx/xform/book/workbook-pivot-cache-xform.js +27 -0
  119. package/dist/es5/xlsx/xform/book/workbook-pivot-cache-xform.js.map +1 -0
  120. package/dist/es5/xlsx/xform/book/workbook-properties-xform.js +27 -0
  121. package/dist/es5/xlsx/xform/book/workbook-properties-xform.js.map +1 -0
  122. package/dist/es5/xlsx/xform/book/workbook-view-xform.js +51 -0
  123. package/dist/es5/xlsx/xform/book/workbook-view-xform.js.map +1 -0
  124. package/dist/es5/xlsx/xform/book/workbook-xform.js +244 -0
  125. package/dist/es5/xlsx/xform/book/workbook-xform.js.map +1 -0
  126. package/dist/es5/xlsx/xform/comment/comment-xform.js +103 -0
  127. package/dist/es5/xlsx/xform/comment/comment-xform.js.map +1 -0
  128. package/dist/es5/xlsx/xform/comment/comments-xform.js +76 -0
  129. package/dist/es5/xlsx/xform/comment/comments-xform.js.map +1 -0
  130. package/dist/es5/xlsx/xform/comment/style/vml-position-xform.js +35 -0
  131. package/dist/es5/xlsx/xform/comment/style/vml-position-xform.js.map +1 -0
  132. package/dist/es5/xlsx/xform/comment/style/vml-protection-xform.js +32 -0
  133. package/dist/es5/xlsx/xform/comment/style/vml-protection-xform.js.map +1 -0
  134. package/dist/es5/xlsx/xform/comment/vml-anchor-xform.js +53 -0
  135. package/dist/es5/xlsx/xform/comment/vml-anchor-xform.js.map +1 -0
  136. package/dist/es5/xlsx/xform/comment/vml-client-data-xform.js +98 -0
  137. package/dist/es5/xlsx/xform/comment/vml-client-data-xform.js.map +1 -0
  138. package/dist/es5/xlsx/xform/comment/vml-notes-xform.js +235 -0
  139. package/dist/es5/xlsx/xform/comment/vml-notes-xform.js.map +1 -0
  140. package/dist/es5/xlsx/xform/comment/vml-shape-xform.js +93 -0
  141. package/dist/es5/xlsx/xform/comment/vml-shape-xform.js.map +1 -0
  142. package/dist/es5/xlsx/xform/comment/vml-textbox-xform.js +61 -0
  143. package/dist/es5/xlsx/xform/comment/vml-textbox-xform.js.map +1 -0
  144. package/dist/es5/xlsx/xform/composite-xform.js +51 -0
  145. package/dist/es5/xlsx/xform/composite-xform.js.map +1 -0
  146. package/dist/es5/xlsx/xform/core/app-heading-pairs-xform.js +30 -0
  147. package/dist/es5/xlsx/xform/core/app-heading-pairs-xform.js.map +1 -0
  148. package/dist/es5/xlsx/xform/core/app-titles-of-parts-xform.js +27 -0
  149. package/dist/es5/xlsx/xform/core/app-titles-of-parts-xform.js.map +1 -0
  150. package/dist/es5/xlsx/xform/core/app-xform.js +93 -0
  151. package/dist/es5/xlsx/xform/core/app-xform.js.map +1 -0
  152. package/dist/es5/xlsx/xform/core/content-types-xform.js +198 -0
  153. package/dist/es5/xlsx/xform/core/content-types-xform.js.map +1 -0
  154. package/dist/es5/xlsx/xform/core/core-xform.js +160 -0
  155. package/dist/es5/xlsx/xform/core/core-xform.js.map +1 -0
  156. package/dist/es5/xlsx/xform/core/relationship-xform.js +23 -0
  157. package/dist/es5/xlsx/xform/core/relationship-xform.js.map +1 -0
  158. package/dist/es5/xlsx/xform/core/relationships-xform.js +65 -0
  159. package/dist/es5/xlsx/xform/core/relationships-xform.js.map +1 -0
  160. package/dist/es5/xlsx/xform/drawing/base-cell-anchor-xform.js +47 -0
  161. package/dist/es5/xlsx/xform/drawing/base-cell-anchor-xform.js.map +1 -0
  162. package/dist/es5/xlsx/xform/drawing/blip-fill-xform.js +61 -0
  163. package/dist/es5/xlsx/xform/drawing/blip-fill-xform.js.map +1 -0
  164. package/dist/es5/xlsx/xform/drawing/blip-xform.js +39 -0
  165. package/dist/es5/xlsx/xform/drawing/blip-xform.js.map +1 -0
  166. package/dist/es5/xlsx/xform/drawing/c-nv-pic-pr-xform.js +35 -0
  167. package/dist/es5/xlsx/xform/drawing/c-nv-pic-pr-xform.js.map +1 -0
  168. package/dist/es5/xlsx/xform/drawing/c-nv-pr-xform.js +62 -0
  169. package/dist/es5/xlsx/xform/drawing/c-nv-pr-xform.js.map +1 -0
  170. package/dist/es5/xlsx/xform/drawing/cell-position-xform.js +82 -0
  171. package/dist/es5/xlsx/xform/drawing/cell-position-xform.js.map +1 -0
  172. package/dist/es5/xlsx/xform/drawing/ctrl-prop-xform.js +75 -0
  173. package/dist/es5/xlsx/xform/drawing/ctrl-prop-xform.js.map +1 -0
  174. package/dist/es5/xlsx/xform/drawing/drawing-xform.js +98 -0
  175. package/dist/es5/xlsx/xform/drawing/drawing-xform.js.map +1 -0
  176. package/dist/es5/xlsx/xform/drawing/ext-lst-xform.js +40 -0
  177. package/dist/es5/xlsx/xform/drawing/ext-lst-xform.js.map +1 -0
  178. package/dist/es5/xlsx/xform/drawing/ext-xform.js +38 -0
  179. package/dist/es5/xlsx/xform/drawing/ext-xform.js.map +1 -0
  180. package/dist/es5/xlsx/xform/drawing/hlink-click-xform.js +38 -0
  181. package/dist/es5/xlsx/xform/drawing/hlink-click-xform.js.map +1 -0
  182. package/dist/es5/xlsx/xform/drawing/nv-pic-pr-xform.js +59 -0
  183. package/dist/es5/xlsx/xform/drawing/nv-pic-pr-xform.js.map +1 -0
  184. package/dist/es5/xlsx/xform/drawing/one-cell-anchor-xform.js +63 -0
  185. package/dist/es5/xlsx/xform/drawing/one-cell-anchor-xform.js.map +1 -0
  186. package/dist/es5/xlsx/xform/drawing/pic-xform.js +67 -0
  187. package/dist/es5/xlsx/xform/drawing/pic-xform.js.map +1 -0
  188. package/dist/es5/xlsx/xform/drawing/sp-pr.js +30 -0
  189. package/dist/es5/xlsx/xform/drawing/sp-pr.js.map +1 -0
  190. package/dist/es5/xlsx/xform/drawing/two-cell-anchor-xform.js +62 -0
  191. package/dist/es5/xlsx/xform/drawing/two-cell-anchor-xform.js.map +1 -0
  192. package/dist/es5/xlsx/xform/list-xform.js +91 -0
  193. package/dist/es5/xlsx/xform/list-xform.js.map +1 -0
  194. package/dist/es5/xlsx/xform/pivot-table/cache-field.js +72 -0
  195. package/dist/es5/xlsx/xform/pivot-table/cache-field.js.map +1 -0
  196. package/dist/es5/xlsx/xform/pivot-table/pivot-cache-definition-xform.js +74 -0
  197. package/dist/es5/xlsx/xform/pivot-table/pivot-cache-definition-xform.js.map +1 -0
  198. package/dist/es5/xlsx/xform/pivot-table/pivot-cache-records-xform.js +100 -0
  199. package/dist/es5/xlsx/xform/pivot-table/pivot-cache-records-xform.js.map +1 -0
  200. package/dist/es5/xlsx/xform/pivot-table/pivot-table-xform.js +229 -0
  201. package/dist/es5/xlsx/xform/pivot-table/pivot-table-xform.js.map +1 -0
  202. package/dist/es5/xlsx/xform/sheet/auto-filter-xform.js +40 -0
  203. package/dist/es5/xlsx/xform/sheet/auto-filter-xform.js.map +1 -0
  204. package/dist/es5/xlsx/xform/sheet/cell-xform.js +450 -0
  205. package/dist/es5/xlsx/xform/sheet/cell-xform.js.map +1 -0
  206. package/dist/es5/xlsx/xform/sheet/cf/cf-rule-xform.js +282 -0
  207. package/dist/es5/xlsx/xform/sheet/cf/cf-rule-xform.js.map +1 -0
  208. package/dist/es5/xlsx/xform/sheet/cf/cfvo-xform.js +25 -0
  209. package/dist/es5/xlsx/xform/sheet/cf/cfvo-xform.js.map +1 -0
  210. package/dist/es5/xlsx/xform/sheet/cf/color-scale-xform.js +38 -0
  211. package/dist/es5/xlsx/xform/sheet/cf/color-scale-xform.js.map +1 -0
  212. package/dist/es5/xlsx/xform/sheet/cf/conditional-formatting-xform.js +45 -0
  213. package/dist/es5/xlsx/xform/sheet/cf/conditional-formatting-xform.js.map +1 -0
  214. package/dist/es5/xlsx/xform/sheet/cf/conditional-formattings-xform.js +77 -0
  215. package/dist/es5/xlsx/xform/sheet/cf/conditional-formattings-xform.js.map +1 -0
  216. package/dist/es5/xlsx/xform/sheet/cf/databar-xform.js +54 -0
  217. package/dist/es5/xlsx/xform/sheet/cf/databar-xform.js.map +1 -0
  218. package/dist/es5/xlsx/xform/sheet/cf/ext-lst-ref-xform.js +71 -0
  219. package/dist/es5/xlsx/xform/sheet/cf/ext-lst-ref-xform.js.map +1 -0
  220. package/dist/es5/xlsx/xform/sheet/cf/formula-xform.js +22 -0
  221. package/dist/es5/xlsx/xform/sheet/cf/formula-xform.js.map +1 -0
  222. package/dist/es5/xlsx/xform/sheet/cf/icon-set-xform.js +43 -0
  223. package/dist/es5/xlsx/xform/sheet/cf/icon-set-xform.js.map +1 -0
  224. package/dist/es5/xlsx/xform/sheet/cf-ext/cf-icon-ext-xform.js +28 -0
  225. package/dist/es5/xlsx/xform/sheet/cf-ext/cf-icon-ext-xform.js.map +1 -0
  226. package/dist/es5/xlsx/xform/sheet/cf-ext/cf-rule-ext-xform.js +88 -0
  227. package/dist/es5/xlsx/xform/sheet/cf-ext/cf-rule-ext-xform.js.map +1 -0
  228. package/dist/es5/xlsx/xform/sheet/cf-ext/cfvo-ext-xform.js +38 -0
  229. package/dist/es5/xlsx/xform/sheet/cf-ext/cfvo-ext-xform.js.map +1 -0
  230. package/dist/es5/xlsx/xform/sheet/cf-ext/conditional-formatting-ext-xform.js +52 -0
  231. package/dist/es5/xlsx/xform/sheet/cf-ext/conditional-formatting-ext-xform.js.map +1 -0
  232. package/dist/es5/xlsx/xform/sheet/cf-ext/conditional-formattings-ext-xform.js +43 -0
  233. package/dist/es5/xlsx/xform/sheet/cf-ext/conditional-formattings-ext-xform.js.map +1 -0
  234. package/dist/es5/xlsx/xform/sheet/cf-ext/databar-ext-xform.js +82 -0
  235. package/dist/es5/xlsx/xform/sheet/cf-ext/databar-ext-xform.js.map +1 -0
  236. package/dist/es5/xlsx/xform/sheet/cf-ext/f-ext-xform.js +22 -0
  237. package/dist/es5/xlsx/xform/sheet/cf-ext/f-ext-xform.js.map +1 -0
  238. package/dist/es5/xlsx/xform/sheet/cf-ext/icon-set-ext-xform.js +66 -0
  239. package/dist/es5/xlsx/xform/sheet/cf-ext/icon-set-ext-xform.js.map +1 -0
  240. package/dist/es5/xlsx/xform/sheet/cf-ext/sqref-ext-xform.js +22 -0
  241. package/dist/es5/xlsx/xform/sheet/cf-ext/sqref-ext-xform.js.map +1 -0
  242. package/dist/es5/xlsx/xform/sheet/col-xform.js +78 -0
  243. package/dist/es5/xlsx/xform/sheet/col-xform.js.map +1 -0
  244. package/dist/es5/xlsx/xform/sheet/data-validations-xform.js +247 -0
  245. package/dist/es5/xlsx/xform/sheet/data-validations-xform.js.map +1 -0
  246. package/dist/es5/xlsx/xform/sheet/dimension-xform.js +28 -0
  247. package/dist/es5/xlsx/xform/sheet/dimension-xform.js.map +1 -0
  248. package/dist/es5/xlsx/xform/sheet/drawing-xform.js +32 -0
  249. package/dist/es5/xlsx/xform/sheet/drawing-xform.js.map +1 -0
  250. package/dist/es5/xlsx/xform/sheet/ext-lst-xform.js +69 -0
  251. package/dist/es5/xlsx/xform/sheet/ext-lst-xform.js.map +1 -0
  252. package/dist/es5/xlsx/xform/sheet/header-footer-xform.js +126 -0
  253. package/dist/es5/xlsx/xform/sheet/header-footer-xform.js.map +1 -0
  254. package/dist/es5/xlsx/xform/sheet/hyperlink-xform.js +50 -0
  255. package/dist/es5/xlsx/xform/sheet/hyperlink-xform.js.map +1 -0
  256. package/dist/es5/xlsx/xform/sheet/merge-cell-xform.js +26 -0
  257. package/dist/es5/xlsx/xform/sheet/merge-cell-xform.js.map +1 -0
  258. package/dist/es5/xlsx/xform/sheet/merges.js +52 -0
  259. package/dist/es5/xlsx/xform/sheet/merges.js.map +1 -0
  260. package/dist/es5/xlsx/xform/sheet/outline-properties-xform.js +35 -0
  261. package/dist/es5/xlsx/xform/sheet/outline-properties-xform.js.map +1 -0
  262. package/dist/es5/xlsx/xform/sheet/page-breaks-xform.js +24 -0
  263. package/dist/es5/xlsx/xform/sheet/page-breaks-xform.js.map +1 -0
  264. package/dist/es5/xlsx/xform/sheet/page-margins-xform.js +46 -0
  265. package/dist/es5/xlsx/xform/sheet/page-margins-xform.js.map +1 -0
  266. package/dist/es5/xlsx/xform/sheet/page-setup-properties-xform.js +32 -0
  267. package/dist/es5/xlsx/xform/sheet/page-setup-properties-xform.js.map +1 -0
  268. package/dist/es5/xlsx/xform/sheet/page-setup-xform.js +99 -0
  269. package/dist/es5/xlsx/xform/sheet/page-setup-xform.js.map +1 -0
  270. package/dist/es5/xlsx/xform/sheet/picture-xform.js +32 -0
  271. package/dist/es5/xlsx/xform/sheet/picture-xform.js.map +1 -0
  272. package/dist/es5/xlsx/xform/sheet/print-options-xform.js +45 -0
  273. package/dist/es5/xlsx/xform/sheet/print-options-xform.js.map +1 -0
  274. package/dist/es5/xlsx/xform/sheet/row-breaks-xform.js +37 -0
  275. package/dist/es5/xlsx/xform/sheet/row-breaks-xform.js.map +1 -0
  276. package/dist/es5/xlsx/xform/sheet/row-xform.js +131 -0
  277. package/dist/es5/xlsx/xform/sheet/row-xform.js.map +1 -0
  278. package/dist/es5/xlsx/xform/sheet/sheet-format-properties-xform.js +63 -0
  279. package/dist/es5/xlsx/xform/sheet/sheet-format-properties-xform.js.map +1 -0
  280. package/dist/es5/xlsx/xform/sheet/sheet-properties-xform.js +83 -0
  281. package/dist/es5/xlsx/xform/sheet/sheet-properties-xform.js.map +1 -0
  282. package/dist/es5/xlsx/xform/sheet/sheet-protection-xform.js +84 -0
  283. package/dist/es5/xlsx/xform/sheet/sheet-protection-xform.js.map +1 -0
  284. package/dist/es5/xlsx/xform/sheet/sheet-view-xform.js +190 -0
  285. package/dist/es5/xlsx/xform/sheet/sheet-view-xform.js.map +1 -0
  286. package/dist/es5/xlsx/xform/sheet/table-part-xform.js +32 -0
  287. package/dist/es5/xlsx/xform/sheet/table-part-xform.js.map +1 -0
  288. package/dist/es5/xlsx/xform/sheet/worksheet-xform.js +622 -0
  289. package/dist/es5/xlsx/xform/sheet/worksheet-xform.js.map +1 -0
  290. package/dist/es5/xlsx/xform/simple/boolean-xform.js +27 -0
  291. package/dist/es5/xlsx/xform/simple/boolean-xform.js.map +1 -0
  292. package/dist/es5/xlsx/xform/simple/date-xform.js +58 -0
  293. package/dist/es5/xlsx/xform/simple/date-xform.js.map +1 -0
  294. package/dist/es5/xlsx/xform/simple/float-xform.js +47 -0
  295. package/dist/es5/xlsx/xform/simple/float-xform.js.map +1 -0
  296. package/dist/es5/xlsx/xform/simple/integer-xform.js +53 -0
  297. package/dist/es5/xlsx/xform/simple/integer-xform.js.map +1 -0
  298. package/dist/es5/xlsx/xform/simple/string-xform.js +47 -0
  299. package/dist/es5/xlsx/xform/simple/string-xform.js.map +1 -0
  300. package/dist/es5/xlsx/xform/static-xform.js +61 -0
  301. package/dist/es5/xlsx/xform/static-xform.js.map +1 -0
  302. package/dist/es5/xlsx/xform/strings/phonetic-text-xform.js +98 -0
  303. package/dist/es5/xlsx/xform/strings/phonetic-text-xform.js.map +1 -0
  304. package/dist/es5/xlsx/xform/strings/rich-text-xform.js +92 -0
  305. package/dist/es5/xlsx/xform/strings/rich-text-xform.js.map +1 -0
  306. package/dist/es5/xlsx/xform/strings/shared-string-xform.js +99 -0
  307. package/dist/es5/xlsx/xform/strings/shared-string-xform.js.map +1 -0
  308. package/dist/es5/xlsx/xform/strings/shared-strings-xform.js +116 -0
  309. package/dist/es5/xlsx/xform/strings/shared-strings-xform.js.map +1 -0
  310. package/dist/es5/xlsx/xform/strings/text-xform.js +39 -0
  311. package/dist/es5/xlsx/xform/strings/text-xform.js.map +1 -0
  312. package/dist/es5/xlsx/xform/style/alignment-xform.js +139 -0
  313. package/dist/es5/xlsx/xform/style/alignment-xform.js.map +1 -0
  314. package/dist/es5/xlsx/xform/style/border-xform.js +185 -0
  315. package/dist/es5/xlsx/xform/style/border-xform.js.map +1 -0
  316. package/dist/es5/xlsx/xform/style/color-xform.js +66 -0
  317. package/dist/es5/xlsx/xform/style/color-xform.js.map +1 -0
  318. package/dist/es5/xlsx/xform/style/dxf-xform.js +106 -0
  319. package/dist/es5/xlsx/xform/style/dxf-xform.js.map +1 -0
  320. package/dist/es5/xlsx/xform/style/fill-xform.js +307 -0
  321. package/dist/es5/xlsx/xform/style/fill-xform.js.map +1 -0
  322. package/dist/es5/xlsx/xform/style/font-xform.js +175 -0
  323. package/dist/es5/xlsx/xform/style/font-xform.js.map +1 -0
  324. package/dist/es5/xlsx/xform/style/numfmt-xform.js +58 -0
  325. package/dist/es5/xlsx/xform/style/numfmt-xform.js.map +1 -0
  326. package/dist/es5/xlsx/xform/style/protection-xform.js +53 -0
  327. package/dist/es5/xlsx/xform/style/protection-xform.js.map +1 -0
  328. package/dist/es5/xlsx/xform/style/style-xform.js +118 -0
  329. package/dist/es5/xlsx/xform/style/style-xform.js.map +1 -0
  330. package/dist/es5/xlsx/xform/style/styles-xform.js +611 -0
  331. package/dist/es5/xlsx/xform/style/styles-xform.js.map +1 -0
  332. package/dist/es5/xlsx/xform/style/underline-xform.js +46 -0
  333. package/dist/es5/xlsx/xform/style/underline-xform.js.map +1 -0
  334. package/dist/es5/xlsx/xform/table/auto-filter-xform.js +75 -0
  335. package/dist/es5/xlsx/xform/table/auto-filter-xform.js.map +1 -0
  336. package/dist/es5/xlsx/xform/table/custom-filter-xform.js +30 -0
  337. package/dist/es5/xlsx/xform/table/custom-filter-xform.js.map +1 -0
  338. package/dist/es5/xlsx/xform/table/filter-column-xform.js +92 -0
  339. package/dist/es5/xlsx/xform/table/filter-column-xform.js.map +1 -0
  340. package/dist/es5/xlsx/xform/table/filter-xform.js +28 -0
  341. package/dist/es5/xlsx/xform/table/filter-xform.js.map +1 -0
  342. package/dist/es5/xlsx/xform/table/table-column-xform.js +42 -0
  343. package/dist/es5/xlsx/xform/table/table-column-xform.js.map +1 -0
  344. package/dist/es5/xlsx/xform/table/table-style-info-xform.js +40 -0
  345. package/dist/es5/xlsx/xform/table/table-style-info-xform.js.map +1 -0
  346. package/dist/es5/xlsx/xform/table/table-xform.js +125 -0
  347. package/dist/es5/xlsx/xform/table/table-xform.js.map +1 -0
  348. package/dist/es5/xlsx/xlsx.js +1109 -0
  349. package/dist/es5/xlsx/xlsx.js.map +1 -0
  350. package/dist/es5/xlsx/xml/theme1.js +5 -0
  351. package/dist/es5/xlsx/xml/theme1.js.map +1 -0
  352. package/dist/exceljs.bare.js +65234 -0
  353. package/dist/exceljs.bare.js.map +889 -0
  354. package/dist/exceljs.bare.min.js +45 -0
  355. package/dist/exceljs.bare.min.js.map +1 -0
  356. package/dist/exceljs.js +69987 -0
  357. package/dist/exceljs.js.map +1211 -0
  358. package/dist/exceljs.min.js +45 -0
  359. package/dist/exceljs.min.js.map +1 -0
  360. package/excel.js +13 -0
  361. package/index.d.ts +2041 -0
  362. package/index.ts +2 -0
  363. package/lib/csv/csv.js +191 -0
  364. package/lib/csv/line-buffer.js +74 -0
  365. package/lib/csv/stream-converter.js +135 -0
  366. package/lib/doc/anchor.js +91 -0
  367. package/lib/doc/cell.js +1124 -0
  368. package/lib/doc/column.js +320 -0
  369. package/lib/doc/data/theme1.json +234 -0
  370. package/lib/doc/data-validations.js +19 -0
  371. package/lib/doc/defined-names.js +196 -0
  372. package/lib/doc/enums.js +48 -0
  373. package/lib/doc/form-checkbox.js +336 -0
  374. package/lib/doc/image.js +59 -0
  375. package/lib/doc/modelcontainer.js +18 -0
  376. package/lib/doc/note.js +65 -0
  377. package/lib/doc/pivot-table.js +239 -0
  378. package/lib/doc/range.js +257 -0
  379. package/lib/doc/row.js +424 -0
  380. package/lib/doc/table.js +559 -0
  381. package/lib/doc/workbook.js +240 -0
  382. package/lib/doc/worksheet.js +1041 -0
  383. package/lib/exceljs.bare.js +13 -0
  384. package/lib/exceljs.browser.js +36 -0
  385. package/lib/exceljs.nodejs.js +14 -0
  386. package/lib/stream/xlsx/hyperlink-reader.js +83 -0
  387. package/lib/stream/xlsx/sheet-comments-writer.js +121 -0
  388. package/lib/stream/xlsx/sheet-rels-writer.js +119 -0
  389. package/lib/stream/xlsx/workbook-reader.js +336 -0
  390. package/lib/stream/xlsx/workbook-writer.js +347 -0
  391. package/lib/stream/xlsx/worksheet-reader.js +374 -0
  392. package/lib/stream/xlsx/worksheet-writer.js +717 -0
  393. package/lib/utils/auto-drain.js +15 -0
  394. package/lib/utils/browser-buffer-decode.js +14 -0
  395. package/lib/utils/browser-buffer-encode.js +15 -0
  396. package/lib/utils/cell-matrix.js +165 -0
  397. package/lib/utils/col-cache.js +287 -0
  398. package/lib/utils/copy-style.js +43 -0
  399. package/lib/utils/encryptor.js +55 -0
  400. package/lib/utils/iterate-stream.js +48 -0
  401. package/lib/utils/parse-sax.js +43 -0
  402. package/lib/utils/shared-formula.js +44 -0
  403. package/lib/utils/shared-strings.js +42 -0
  404. package/lib/utils/stream-base64.js +72 -0
  405. package/lib/utils/stream-buf.js +387 -0
  406. package/lib/utils/string-buf.js +82 -0
  407. package/lib/utils/string-builder.js +35 -0
  408. package/lib/utils/stuttered-pipe.js +67 -0
  409. package/lib/utils/typed-stack.js +24 -0
  410. package/lib/utils/under-dash.js +184 -0
  411. package/lib/utils/utils.js +206 -0
  412. package/lib/utils/xml-stream.js +169 -0
  413. package/lib/utils/zip-stream.js +87 -0
  414. package/lib/xlsx/.rels +11 -0
  415. package/lib/xlsx/calcChain.xml +6 -0
  416. package/lib/xlsx/core.xml +7 -0
  417. package/lib/xlsx/defaultnumformats.js +153 -0
  418. package/lib/xlsx/rel-type.js +27 -0
  419. package/lib/xlsx/styles.xml +41 -0
  420. package/lib/xlsx/workbook.xml +16 -0
  421. package/lib/xlsx/xform/base-xform.js +145 -0
  422. package/lib/xlsx/xform/book/defined-name-xform.js +91 -0
  423. package/lib/xlsx/xform/book/sheet-xform.js +34 -0
  424. package/lib/xlsx/xform/book/workbook-calc-properties-xform.js +26 -0
  425. package/lib/xlsx/xform/book/workbook-pivot-cache-xform.js +29 -0
  426. package/lib/xlsx/xform/book/workbook-properties-xform.js +29 -0
  427. package/lib/xlsx/xform/book/workbook-view-xform.js +53 -0
  428. package/lib/xlsx/xform/book/workbook-xform.js +265 -0
  429. package/lib/xlsx/xform/comment/comment-xform.js +105 -0
  430. package/lib/xlsx/xform/comment/comments-xform.js +82 -0
  431. package/lib/xlsx/xform/comment/style/vml-position-xform.js +39 -0
  432. package/lib/xlsx/xform/comment/style/vml-protection-xform.js +36 -0
  433. package/lib/xlsx/xform/comment/vml-anchor-xform.js +60 -0
  434. package/lib/xlsx/xform/comment/vml-client-data-xform.js +92 -0
  435. package/lib/xlsx/xform/comment/vml-notes-xform.js +217 -0
  436. package/lib/xlsx/xform/comment/vml-shape-xform.js +95 -0
  437. package/lib/xlsx/xform/comment/vml-textbox-xform.js +64 -0
  438. package/lib/xlsx/xform/composite-xform.js +56 -0
  439. package/lib/xlsx/xform/core/app-heading-pairs-xform.js +32 -0
  440. package/lib/xlsx/xform/core/app-titles-of-parts-xform.js +28 -0
  441. package/lib/xlsx/xform/core/app-xform.js +100 -0
  442. package/lib/xlsx/xform/core/content-types-xform.js +211 -0
  443. package/lib/xlsx/xform/core/core-xform.js +142 -0
  444. package/lib/xlsx/xform/core/relationship-xform.js +25 -0
  445. package/lib/xlsx/xform/core/relationships-xform.js +73 -0
  446. package/lib/xlsx/xform/drawing/base-cell-anchor-xform.js +48 -0
  447. package/lib/xlsx/xform/drawing/blip-fill-xform.js +71 -0
  448. package/lib/xlsx/xform/drawing/blip-xform.js +42 -0
  449. package/lib/xlsx/xform/drawing/c-nv-pic-pr-xform.js +38 -0
  450. package/lib/xlsx/xform/drawing/c-nv-pr-xform.js +68 -0
  451. package/lib/xlsx/xform/drawing/cell-position-xform.js +77 -0
  452. package/lib/xlsx/xform/drawing/ctrl-prop-xform.js +74 -0
  453. package/lib/xlsx/xform/drawing/drawing-xform.js +109 -0
  454. package/lib/xlsx/xform/drawing/ext-lst-xform.js +43 -0
  455. package/lib/xlsx/xform/drawing/ext-xform.js +44 -0
  456. package/lib/xlsx/xform/drawing/hlink-click-xform.js +41 -0
  457. package/lib/xlsx/xform/drawing/nv-pic-pr-xform.js +65 -0
  458. package/lib/xlsx/xform/drawing/one-cell-anchor-xform.js +63 -0
  459. package/lib/xlsx/xform/drawing/pic-xform.js +77 -0
  460. package/lib/xlsx/xform/drawing/sp-pr.js +17 -0
  461. package/lib/xlsx/xform/drawing/two-cell-anchor-xform.js +62 -0
  462. package/lib/xlsx/xform/list-xform.js +95 -0
  463. package/lib/xlsx/xform/pivot-table/cache-field.js +74 -0
  464. package/lib/xlsx/xform/pivot-table/pivot-cache-definition-xform.js +77 -0
  465. package/lib/xlsx/xform/pivot-table/pivot-cache-records-xform.js +107 -0
  466. package/lib/xlsx/xform/pivot-table/pivot-table-xform.js +265 -0
  467. package/lib/xlsx/xform/sheet/auto-filter-xform.js +38 -0
  468. package/lib/xlsx/xform/sheet/cell-xform.js +498 -0
  469. package/lib/xlsx/xform/sheet/cf/cf-rule-xform.js +308 -0
  470. package/lib/xlsx/xform/sheet/cf/cfvo-xform.js +27 -0
  471. package/lib/xlsx/xform/sheet/cf/color-scale-xform.js +45 -0
  472. package/lib/xlsx/xform/sheet/cf/conditional-formatting-xform.js +48 -0
  473. package/lib/xlsx/xform/sheet/cf/conditional-formattings-xform.js +92 -0
  474. package/lib/xlsx/xform/sheet/cf/databar-xform.js +56 -0
  475. package/lib/xlsx/xform/sheet/cf/ext-lst-ref-xform.js +87 -0
  476. package/lib/xlsx/xform/sheet/cf/formula-xform.js +25 -0
  477. package/lib/xlsx/xform/sheet/cf/icon-set-xform.js +47 -0
  478. package/lib/xlsx/xform/sheet/cf-ext/cf-icon-ext-xform.js +27 -0
  479. package/lib/xlsx/xform/sheet/cf-ext/cf-rule-ext-xform.js +98 -0
  480. package/lib/xlsx/xform/sheet/cf-ext/cfvo-ext-xform.js +43 -0
  481. package/lib/xlsx/xform/sheet/cf-ext/conditional-formatting-ext-xform.js +62 -0
  482. package/lib/xlsx/xform/sheet/cf-ext/conditional-formattings-ext-xform.js +50 -0
  483. package/lib/xlsx/xform/sheet/cf-ext/databar-ext-xform.js +102 -0
  484. package/lib/xlsx/xform/sheet/cf-ext/f-ext-xform.js +25 -0
  485. package/lib/xlsx/xform/sheet/cf-ext/icon-set-ext-xform.js +73 -0
  486. package/lib/xlsx/xform/sheet/cf-ext/sqref-ext-xform.js +25 -0
  487. package/lib/xlsx/xform/sheet/col-xform.js +86 -0
  488. package/lib/xlsx/xform/sheet/data-validations-xform.js +257 -0
  489. package/lib/xlsx/xform/sheet/dimension-xform.js +29 -0
  490. package/lib/xlsx/xform/sheet/drawing-xform.js +33 -0
  491. package/lib/xlsx/xform/sheet/ext-lst-xform.js +86 -0
  492. package/lib/xlsx/xform/sheet/header-footer-xform.js +146 -0
  493. package/lib/xlsx/xform/sheet/hyperlink-xform.js +54 -0
  494. package/lib/xlsx/xform/sheet/merge-cell-xform.js +27 -0
  495. package/lib/xlsx/xform/sheet/merges.js +56 -0
  496. package/lib/xlsx/xform/sheet/outline-properties-xform.js +43 -0
  497. package/lib/xlsx/xform/sheet/page-breaks-xform.js +27 -0
  498. package/lib/xlsx/xform/sheet/page-margins-xform.js +49 -0
  499. package/lib/xlsx/xform/sheet/page-setup-properties-xform.js +35 -0
  500. package/lib/xlsx/xform/sheet/page-setup-xform.js +103 -0
  501. package/lib/xlsx/xform/sheet/picture-xform.js +33 -0
  502. package/lib/xlsx/xform/sheet/print-options-xform.js +49 -0
  503. package/lib/xlsx/xform/sheet/row-breaks-xform.js +39 -0
  504. package/lib/xlsx/xform/sheet/row-xform.js +145 -0
  505. package/lib/xlsx/xform/sheet/sheet-format-properties-xform.js +67 -0
  506. package/lib/xlsx/xform/sheet/sheet-properties-xform.js +90 -0
  507. package/lib/xlsx/xform/sheet/sheet-protection-xform.js +89 -0
  508. package/lib/xlsx/xform/sheet/sheet-view-xform.js +202 -0
  509. package/lib/xlsx/xform/sheet/table-part-xform.js +33 -0
  510. package/lib/xlsx/xform/sheet/worksheet-xform.js +657 -0
  511. package/lib/xlsx/xform/simple/boolean-xform.js +31 -0
  512. package/lib/xlsx/xform/simple/date-xform.js +66 -0
  513. package/lib/xlsx/xform/simple/float-xform.js +51 -0
  514. package/lib/xlsx/xform/simple/integer-xform.js +57 -0
  515. package/lib/xlsx/xform/simple/string-xform.js +51 -0
  516. package/lib/xlsx/xform/static-xform.js +64 -0
  517. package/lib/xlsx/xform/strings/phonetic-text-xform.js +98 -0
  518. package/lib/xlsx/xform/strings/rich-text-xform.js +101 -0
  519. package/lib/xlsx/xform/strings/shared-string-xform.js +102 -0
  520. package/lib/xlsx/xform/strings/shared-strings-xform.js +132 -0
  521. package/lib/xlsx/xform/strings/text-xform.js +44 -0
  522. package/lib/xlsx/xform/style/alignment-xform.js +172 -0
  523. package/lib/xlsx/xform/style/border-xform.js +207 -0
  524. package/lib/xlsx/xform/style/color-xform.js +63 -0
  525. package/lib/xlsx/xform/style/dxf-xform.js +111 -0
  526. package/lib/xlsx/xform/style/fill-xform.js +364 -0
  527. package/lib/xlsx/xform/style/font-xform.js +102 -0
  528. package/lib/xlsx/xform/style/numfmt-xform.js +63 -0
  529. package/lib/xlsx/xform/style/protection-xform.js +60 -0
  530. package/lib/xlsx/xform/style/style-xform.js +125 -0
  531. package/lib/xlsx/xform/style/styles-xform.js +527 -0
  532. package/lib/xlsx/xform/style/underline-xform.js +47 -0
  533. package/lib/xlsx/xform/table/auto-filter-xform.js +81 -0
  534. package/lib/xlsx/xform/table/custom-filter-xform.js +33 -0
  535. package/lib/xlsx/xform/table/filter-column-xform.js +99 -0
  536. package/lib/xlsx/xform/table/filter-xform.js +31 -0
  537. package/lib/xlsx/xform/table/table-column-xform.js +44 -0
  538. package/lib/xlsx/xform/table/table-style-info-xform.js +41 -0
  539. package/lib/xlsx/xform/table/table-xform.js +134 -0
  540. package/lib/xlsx/xlsx.js +1160 -0
  541. package/lib/xlsx/xml/theme1.js +3 -0
  542. package/lib/xlsx/xml/theme1.xml +318 -0
  543. package/package.json +159 -0
@@ -0,0 +1,1109 @@
1
+ "use strict";
2
+
3
+ const fs = require('fs');
4
+ const JSZip = require('jszip');
5
+ const {
6
+ PassThrough
7
+ } = require('readable-stream');
8
+ const ZipStream = require('../utils/zip-stream');
9
+ const StreamBuf = require('../utils/stream-buf');
10
+ const utils = require('../utils/utils');
11
+ const XmlStream = require('../utils/xml-stream');
12
+ const {
13
+ bufferToString
14
+ } = require('../utils/browser-buffer-decode');
15
+ const StylesXform = require('./xform/style/styles-xform');
16
+ const CoreXform = require('./xform/core/core-xform');
17
+ const SharedStringsXform = require('./xform/strings/shared-strings-xform');
18
+ const RelationshipsXform = require('./xform/core/relationships-xform');
19
+ const ContentTypesXform = require('./xform/core/content-types-xform');
20
+ const AppXform = require('./xform/core/app-xform');
21
+ const WorkbookXform = require('./xform/book/workbook-xform');
22
+ const WorksheetXform = require('./xform/sheet/worksheet-xform');
23
+ const DrawingXform = require('./xform/drawing/drawing-xform');
24
+ const TableXform = require('./xform/table/table-xform');
25
+ const PivotCacheRecordsXform = require('./xform/pivot-table/pivot-cache-records-xform');
26
+ const PivotCacheDefinitionXform = require('./xform/pivot-table/pivot-cache-definition-xform');
27
+ const PivotTableXform = require('./xform/pivot-table/pivot-table-xform');
28
+ const CommentsXform = require('./xform/comment/comments-xform');
29
+ const VmlNotesXform = require('./xform/comment/vml-notes-xform');
30
+ const CtrlPropXform = require('./xform/drawing/ctrl-prop-xform');
31
+ const theme1Xml = require('./xml/theme1');
32
+ const RelType = require('./rel-type');
33
+ function fsReadFileAsync(filename, options) {
34
+ return new Promise((resolve, reject) => {
35
+ fs.readFile(filename, options, (error, data) => {
36
+ if (error) {
37
+ reject(error);
38
+ } else {
39
+ resolve(data);
40
+ }
41
+ });
42
+ });
43
+ }
44
+ class XLSX {
45
+ constructor(workbook) {
46
+ this.workbook = workbook;
47
+ }
48
+
49
+ // ===============================================================================
50
+ // Workbook
51
+ // =========================================================================
52
+ // Read
53
+
54
+ async readFile(filename, options) {
55
+ if (!(await utils.fs.exists(filename))) {
56
+ throw new Error(`File not found: ${filename}`);
57
+ }
58
+ const stream = fs.createReadStream(filename);
59
+ try {
60
+ const workbook = await this.read(stream, options);
61
+ stream.close();
62
+ return workbook;
63
+ } catch (error) {
64
+ stream.close();
65
+ throw error;
66
+ }
67
+ }
68
+ parseRels(stream) {
69
+ const xform = new RelationshipsXform();
70
+ return xform.parseStream(stream);
71
+ }
72
+ parseWorkbook(stream) {
73
+ const xform = new WorkbookXform();
74
+ return xform.parseStream(stream);
75
+ }
76
+ parseSharedStrings(stream) {
77
+ const xform = new SharedStringsXform();
78
+ return xform.parseStream(stream);
79
+ }
80
+ reconcile(model, options) {
81
+ const workbookXform = new WorkbookXform();
82
+ const worksheetXform = new WorksheetXform(options);
83
+ const drawingXform = new DrawingXform();
84
+ const tableXform = new TableXform();
85
+ workbookXform.reconcile(model);
86
+
87
+ // reconcile drawings with their rels
88
+ const drawingOptions = {
89
+ media: model.media,
90
+ mediaIndex: model.mediaIndex
91
+ };
92
+ Object.keys(model.drawings).forEach(name => {
93
+ const drawing = model.drawings[name];
94
+ const drawingRel = model.drawingRels[name];
95
+ if (drawingRel) {
96
+ drawingOptions.rels = drawingRel.reduce((o, rel) => {
97
+ o[rel.Id] = rel;
98
+ return o;
99
+ }, {});
100
+ (drawing.anchors || []).forEach(anchor => {
101
+ const hyperlinks = anchor.picture && anchor.picture.hyperlinks;
102
+ if (hyperlinks && drawingOptions.rels[hyperlinks.rId]) {
103
+ hyperlinks.hyperlink = drawingOptions.rels[hyperlinks.rId].Target;
104
+ delete hyperlinks.rId;
105
+ }
106
+ });
107
+ drawingXform.reconcile(drawing, drawingOptions);
108
+ }
109
+ });
110
+
111
+ // reconcile tables with the default styles
112
+ const tableOptions = {
113
+ styles: model.styles
114
+ };
115
+ Object.values(model.tables).forEach(table => {
116
+ tableXform.reconcile(table, tableOptions);
117
+ });
118
+ const sheetOptions = {
119
+ styles: model.styles,
120
+ sharedStrings: model.sharedStrings,
121
+ media: model.media,
122
+ mediaIndex: model.mediaIndex,
123
+ date1904: model.properties && model.properties.date1904,
124
+ drawings: model.drawings,
125
+ comments: model.comments,
126
+ tables: model.tables,
127
+ vmlDrawings: model.vmlDrawings,
128
+ preservedPivotTablesXml: model.preservedPivotTablesXml,
129
+ preservedPivotTablesRels: model.preservedPivotTablesRels,
130
+ preservedDrawingsXml: model.preservedDrawingsXml,
131
+ preservedDrawingsRels: model.preservedDrawingsRels
132
+ };
133
+ model.worksheets.forEach(worksheet => {
134
+ worksheet.relationships = model.worksheetRels[worksheet.sheetNo];
135
+ worksheetXform.reconcile(worksheet, sheetOptions);
136
+ });
137
+
138
+ // Collect preserved pivot tables for write
139
+ model.preservedPivotTables = {
140
+ pivotTables: model.preservedPivotTablesXml,
141
+ pivotCacheDefinitions: model.preservedPivotCacheDefinitionsXml,
142
+ pivotCacheRecords: model.preservedPivotCacheRecordsXml
143
+ };
144
+
145
+ // Extract cache IDs from preserved pivot tables and create pivot cache entries
146
+ // These will be used by workbook-xform to write the <pivotCaches> section
147
+ const preservedCaches = [];
148
+ const cacheIdToFilename = {}; // Map cacheId to actual filename
149
+
150
+ // First, build a map of cacheId to definition filename by checking the pivot table rels
151
+ model.worksheets.forEach(worksheet => {
152
+ if (worksheet.pivotTables && worksheet.pivotTables.length > 0) {
153
+ worksheet.pivotTables.forEach(pivotTable => {
154
+ if (pivotTable.xml && pivotTable.rels) {
155
+ // Extract cacheId from the pivot table XML
156
+ const cacheIdMatch = pivotTable.xml.match(/cacheId="(\d+)"/);
157
+ if (cacheIdMatch) {
158
+ const cacheId = cacheIdMatch[1];
159
+ // Find the pivot cache definition relationship
160
+ // pivotTable.rels should have a relationship to the cache definition
161
+ const cacheDefRel = pivotTable.rels.find(rel => rel.Type === RelType.PivotCacheDefinition);
162
+ if (cacheDefRel) {
163
+ // Extract filename from Target like "../pivotCache/pivotCacheDefinition1.xml"
164
+ const targetMatch = cacheDefRel.Target.match(/pivotCacheDefinition\d+\.xml/);
165
+ if (targetMatch) {
166
+ cacheIdToFilename[cacheId] = targetMatch[0];
167
+ }
168
+ }
169
+ }
170
+ }
171
+ });
172
+ }
173
+ });
174
+
175
+ // Now create the preserved cache entries with correct filenames
176
+ Object.keys(cacheIdToFilename).forEach(cacheId => {
177
+ preservedCaches.push({
178
+ cacheId,
179
+ definitionFilename: cacheIdToFilename[cacheId],
180
+ isPreserved: true
181
+ });
182
+ });
183
+ model.preservedPivotCaches = preservedCaches;
184
+
185
+ // delete unnecessary parts
186
+ delete model.worksheetHash;
187
+ delete model.worksheetRels;
188
+ delete model.globalRels;
189
+ delete model.sharedStrings;
190
+ delete model.workbookRels;
191
+ delete model.sheetDefs;
192
+ delete model.styles;
193
+ delete model.mediaIndex;
194
+ delete model.drawings;
195
+ delete model.drawingRels;
196
+ delete model.vmlDrawings;
197
+ delete model.preservedPivotTablesRels;
198
+ delete model.preservedPivotCacheDefinitionsRels;
199
+ // Keep the XML dictionaries through preservedPivotTables
200
+ }
201
+ async _processWorksheetEntry(stream, model, sheetNo, options, path) {
202
+ const xform = new WorksheetXform(options);
203
+ const worksheet = await xform.parseStream(stream);
204
+ worksheet.sheetNo = sheetNo;
205
+ model.worksheetHash[path] = worksheet;
206
+ model.worksheets.push(worksheet);
207
+ }
208
+ async _processCommentEntry(stream, model, name) {
209
+ const xform = new CommentsXform();
210
+ const comments = await xform.parseStream(stream);
211
+ model.comments[`../${name}.xml`] = comments;
212
+ }
213
+ async _processTableEntry(stream, model, name) {
214
+ const xform = new TableXform();
215
+ const table = await xform.parseStream(stream);
216
+ model.tables[`../tables/${name}.xml`] = table;
217
+ }
218
+ async _processWorksheetRelsEntry(stream, model, sheetNo) {
219
+ const xform = new RelationshipsXform();
220
+ const relationships = await xform.parseStream(stream);
221
+ model.worksheetRels[sheetNo] = relationships;
222
+ }
223
+ async _processMediaEntry(entry, model, filename) {
224
+ const lastDot = filename.lastIndexOf('.');
225
+ // if we can't determine extension, ignore it
226
+ if (lastDot >= 1) {
227
+ const extension = filename.substr(lastDot + 1);
228
+ const name = filename.substr(0, lastDot);
229
+ await new Promise((resolve, reject) => {
230
+ const streamBuf = new StreamBuf();
231
+ streamBuf.on('finish', () => {
232
+ model.mediaIndex[filename] = model.media.length;
233
+ model.mediaIndex[name] = model.media.length;
234
+ const medium = {
235
+ type: 'image',
236
+ name,
237
+ extension,
238
+ buffer: streamBuf.toBuffer()
239
+ };
240
+ model.media.push(medium);
241
+ resolve();
242
+ });
243
+ entry.on('error', error => {
244
+ reject(error);
245
+ });
246
+ entry.pipe(streamBuf);
247
+ });
248
+ }
249
+ }
250
+ async _processDrawingEntry(entry, model, name) {
251
+ // Check if drawing contains chart references
252
+ const xml = await entry.async('string');
253
+ const hasChart = xml.includes('drawingml/2006/chart');
254
+ if (hasChart) {
255
+ // Preserve as raw XML if it contains charts
256
+ model.preservedDrawingsXml[name] = xml;
257
+ } else {
258
+ // Parse normally for images and other content
259
+ // Re-create a stream from the XML we already read using StreamBuf
260
+ const stream = new StreamBuf();
261
+ stream.write(xml);
262
+ stream.end();
263
+ const xform = new DrawingXform();
264
+ const drawing = await xform.parseStream(stream);
265
+ model.drawings[name] = drawing;
266
+ }
267
+ }
268
+ async _processDrawingRelsEntry(entry, model, name) {
269
+ const xform = new RelationshipsXform();
270
+ const relationships = await xform.parseStream(entry);
271
+ model.drawingRels[name] = relationships;
272
+
273
+ // Also preserve raw relationships for preserved drawings
274
+ if (model.preservedDrawingsXml[name]) {
275
+ model.preservedDrawingsRels[name] = relationships;
276
+ }
277
+ }
278
+ async _processVmlDrawingEntry(entry, model, name) {
279
+ const xform = new VmlNotesXform();
280
+ const vmlDrawing = await xform.parseStream(entry);
281
+ model.vmlDrawings[`../drawings/${name}.vml`] = vmlDrawing;
282
+ }
283
+ async _processPivotTableEntry(zipEntry, model, name) {
284
+ // Read XML directly from zip entry
285
+ const xml = await zipEntry.async('string');
286
+ model.preservedPivotTablesXml[name] = xml;
287
+ }
288
+ async _processPivotTableRelsEntry(stream, model, name) {
289
+ const xform = new RelationshipsXform();
290
+ const relationships = await xform.parseStream(stream);
291
+ model.preservedPivotTablesRels[name] = relationships;
292
+ }
293
+ async _processPivotCacheDefinitionEntry(zipEntry, model, name) {
294
+ // Read XML directly from zip entry
295
+ const xml = await zipEntry.async('string');
296
+ model.preservedPivotCacheDefinitionsXml[name] = xml;
297
+ }
298
+ async _processPivotCacheDefinitionRelsEntry(stream, model, name) {
299
+ const xform = new RelationshipsXform();
300
+ const relationships = await xform.parseStream(stream);
301
+ model.preservedPivotCacheDefinitionsRels[name] = relationships;
302
+ }
303
+ async _processPivotCacheRecordsEntry(zipEntry, model, name) {
304
+ // Read XML directly from zip entry
305
+ const xml = await zipEntry.async('string');
306
+ model.preservedPivotCacheRecordsXml[name] = xml;
307
+ }
308
+ async _processChartEntry(zipEntry, model, name) {
309
+ // Read XML directly from zip entry
310
+ const xml = await zipEntry.async('string');
311
+ model.preservedChartsXml[name] = xml;
312
+ }
313
+ async _processChartRelsEntry(stream, model, name) {
314
+ const xform = new RelationshipsXform();
315
+ const relationships = await xform.parseStream(stream);
316
+ model.preservedChartsRels[name] = relationships;
317
+ }
318
+ async _processChartStyleEntry(zipEntry, model, name) {
319
+ // Read XML directly from zip entry
320
+ const xml = await zipEntry.async('string');
321
+ model.preservedChartStylesXml[name] = xml;
322
+ }
323
+ async _processChartColorsEntry(zipEntry, model, name) {
324
+ // Read XML directly from zip entry
325
+ const xml = await zipEntry.async('string');
326
+ model.preservedChartColorsXml[name] = xml;
327
+ }
328
+ async _processThemeEntry(entry, model, name) {
329
+ await new Promise((resolve, reject) => {
330
+ // TODO: stream entry into buffer and store the xml in the model.themes[]
331
+ const stream = new StreamBuf();
332
+ entry.on('error', reject);
333
+ stream.on('error', reject);
334
+ stream.on('finish', () => {
335
+ model.themes[name] = stream.read().toString();
336
+ resolve();
337
+ });
338
+ entry.pipe(stream);
339
+ });
340
+ }
341
+
342
+ /**
343
+ * @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
344
+ */
345
+ createInputStream() {
346
+ throw new Error('`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');
347
+ }
348
+ async read(stream, options) {
349
+ // TODO: Remove once node v8 is deprecated
350
+ // Detect and upgrade old streams
351
+ if (!stream[Symbol.asyncIterator] && stream.pipe) {
352
+ stream = stream.pipe(new PassThrough());
353
+ }
354
+ const chunks = [];
355
+ for await (const chunk of stream) {
356
+ chunks.push(chunk);
357
+ }
358
+ return this.load(Buffer.concat(chunks), options);
359
+ }
360
+ async load(data, options) {
361
+ let buffer;
362
+ if (options && options.base64) {
363
+ buffer = Buffer.from(data.toString(), 'base64');
364
+ } else {
365
+ buffer = data;
366
+ }
367
+ const model = {
368
+ worksheets: [],
369
+ worksheetHash: {},
370
+ worksheetRels: [],
371
+ themes: {},
372
+ media: [],
373
+ mediaIndex: {},
374
+ drawings: {},
375
+ drawingRels: {},
376
+ comments: {},
377
+ tables: {},
378
+ vmlDrawings: {},
379
+ pivotTables: [],
380
+ // Keep as array for programmatic pivots
381
+ preservedPivotTablesXml: {},
382
+ preservedPivotTablesRels: {},
383
+ preservedPivotCacheDefinitionsXml: {},
384
+ preservedPivotCacheDefinitionsRels: {},
385
+ preservedPivotCacheRecordsXml: {},
386
+ preservedChartsXml: {},
387
+ preservedChartsRels: {},
388
+ preservedChartStylesXml: {},
389
+ preservedChartColorsXml: {},
390
+ preservedDrawingsXml: {},
391
+ preservedDrawingsRels: {}
392
+ };
393
+ const zip = await JSZip.loadAsync(buffer);
394
+ for (const entry of Object.values(zip.files)) {
395
+ /* eslint-disable no-await-in-loop */
396
+ if (!entry.dir) {
397
+ let entryName = entry.name;
398
+ if (entryName[0] === '/') {
399
+ entryName = entryName.substr(1);
400
+ }
401
+ let stream;
402
+ if (entryName.match(/xl\/media\//) ||
403
+ // themes are not parsed as stream
404
+ entryName.match(/xl\/theme\/([a-zA-Z0-9]+)[.]xml/)) {
405
+ stream = new PassThrough();
406
+ stream.write(await entry.async('nodebuffer'));
407
+ } else {
408
+ // use object mode to avoid buffer-string convention
409
+ stream = new PassThrough({
410
+ writableObjectMode: true,
411
+ readableObjectMode: true
412
+ });
413
+ let content;
414
+ // https://www.npmjs.com/package/process
415
+ if (process.browser) {
416
+ // running in browser, use TextDecoder if possible
417
+ content = bufferToString(await entry.async('nodebuffer'));
418
+ } else {
419
+ // running in node.js
420
+ content = await entry.async('string');
421
+ }
422
+ const chunkSize = 16 * 1024;
423
+ for (let i = 0; i < content.length; i += chunkSize) {
424
+ stream.write(content.substring(i, i + chunkSize));
425
+ }
426
+ }
427
+ stream.end();
428
+ switch (entryName) {
429
+ case '_rels/.rels':
430
+ model.globalRels = await this.parseRels(stream);
431
+ break;
432
+ case 'xl/workbook.xml':
433
+ {
434
+ const workbook = await this.parseWorkbook(stream);
435
+ if (workbook) {
436
+ model.sheets = workbook.sheets;
437
+ model.definedNames = workbook.definedNames;
438
+ model.views = workbook.views;
439
+ model.properties = workbook.properties;
440
+ model.calcProperties = workbook.calcProperties;
441
+ }
442
+ break;
443
+ }
444
+ case 'xl/_rels/workbook.xml.rels':
445
+ model.workbookRels = await this.parseRels(stream);
446
+ break;
447
+ case 'xl/sharedStrings.xml':
448
+ model.sharedStrings = new SharedStringsXform();
449
+ await model.sharedStrings.parseStream(stream);
450
+ break;
451
+ case 'xl/styles.xml':
452
+ model.styles = new StylesXform();
453
+ await model.styles.parseStream(stream);
454
+ break;
455
+ case 'docProps/app.xml':
456
+ {
457
+ const appXform = new AppXform();
458
+ const appProperties = await appXform.parseStream(stream);
459
+ if (appProperties) {
460
+ model.company = appProperties.company;
461
+ model.manager = appProperties.manager;
462
+ }
463
+ break;
464
+ }
465
+ case 'docProps/core.xml':
466
+ {
467
+ const coreXform = new CoreXform();
468
+ const coreProperties = await coreXform.parseStream(stream);
469
+ if (coreProperties) {
470
+ Object.assign(model, coreProperties);
471
+ }
472
+ break;
473
+ }
474
+ default:
475
+ {
476
+ let match = entryName.match(/xl\/worksheets\/sheet(\d+)[.]xml/);
477
+ if (match) {
478
+ await this._processWorksheetEntry(stream, model, match[1], options, entryName);
479
+ break;
480
+ }
481
+ match = entryName.match(/xl\/worksheets\/_rels\/sheet(\d+)[.]xml.rels/);
482
+ if (match) {
483
+ await this._processWorksheetRelsEntry(stream, model, match[1]);
484
+ break;
485
+ }
486
+ match = entryName.match(/xl\/theme\/([a-zA-Z0-9]+)[.]xml/);
487
+ if (match) {
488
+ await this._processThemeEntry(stream, model, match[1]);
489
+ break;
490
+ }
491
+ match = entryName.match(/xl\/media\/([a-zA-Z0-9]+[.][a-zA-Z0-9]{3,4})$/);
492
+ if (match) {
493
+ await this._processMediaEntry(stream, model, match[1]);
494
+ break;
495
+ }
496
+ match = entryName.match(/xl\/drawings\/([a-zA-Z0-9]+)[.]xml/);
497
+ if (match) {
498
+ await this._processDrawingEntry(entry, model, match[1]);
499
+ break;
500
+ }
501
+ match = entryName.match(/xl\/(comments\d+)[.]xml/);
502
+ if (match) {
503
+ await this._processCommentEntry(stream, model, match[1]);
504
+ break;
505
+ }
506
+ match = entryName.match(/xl\/tables\/(table\d+)[.]xml/);
507
+ if (match) {
508
+ await this._processTableEntry(stream, model, match[1]);
509
+ break;
510
+ }
511
+ match = entryName.match(/xl\/drawings\/_rels\/([a-zA-Z0-9]+)[.]xml[.]rels/);
512
+ if (match) {
513
+ await this._processDrawingRelsEntry(stream, model, match[1]);
514
+ break;
515
+ }
516
+ match = entryName.match(/xl\/drawings\/(vmlDrawing\d+)[.]vml/);
517
+ if (match) {
518
+ await this._processVmlDrawingEntry(stream, model, match[1]);
519
+ break;
520
+ }
521
+ match = entryName.match(/xl\/pivotTables\/(pivotTable\d+)[.]xml/);
522
+ if (match) {
523
+ await this._processPivotTableEntry(entry, model, match[1]);
524
+ break;
525
+ }
526
+ match = entryName.match(/xl\/pivotTables\/_rels\/(pivotTable\d+)[.]xml[.]rels/);
527
+ if (match) {
528
+ await this._processPivotTableRelsEntry(stream, model, match[1]);
529
+ break;
530
+ }
531
+ match = entryName.match(/xl\/pivotCache\/(pivotCacheDefinition\d+)[.]xml/);
532
+ if (match) {
533
+ await this._processPivotCacheDefinitionEntry(entry, model, match[1]);
534
+ break;
535
+ }
536
+ match = entryName.match(/xl\/pivotCache\/_rels\/(pivotCacheDefinition\d+)[.]xml[.]rels/);
537
+ if (match) {
538
+ await this._processPivotCacheDefinitionRelsEntry(stream, model, match[1]);
539
+ break;
540
+ }
541
+ match = entryName.match(/xl\/pivotCache\/(pivotCacheRecords\d+)[.]xml/);
542
+ if (match) {
543
+ await this._processPivotCacheRecordsEntry(entry, model, match[1]);
544
+ break;
545
+ }
546
+ match = entryName.match(/xl\/charts\/(chart\d+)[.]xml/);
547
+ if (match) {
548
+ await this._processChartEntry(entry, model, match[1]);
549
+ break;
550
+ }
551
+ match = entryName.match(/xl\/charts\/_rels\/(chart\d+)[.]xml[.]rels/);
552
+ if (match) {
553
+ await this._processChartRelsEntry(stream, model, match[1]);
554
+ break;
555
+ }
556
+ match = entryName.match(/xl\/charts\/(style\d+)[.]xml/);
557
+ if (match) {
558
+ await this._processChartStyleEntry(entry, model, match[1]);
559
+ break;
560
+ }
561
+ match = entryName.match(/xl\/charts\/(colors\d+)[.]xml/);
562
+ if (match) {
563
+ await this._processChartColorsEntry(entry, model, match[1]);
564
+ break;
565
+ }
566
+ }
567
+ }
568
+ }
569
+ }
570
+ this.reconcile(model, options);
571
+
572
+ // apply model
573
+ this.workbook.model = model;
574
+ return this.workbook;
575
+ }
576
+
577
+ // =========================================================================
578
+ // Write
579
+
580
+ async addMedia(zip, model) {
581
+ await Promise.all(model.media.map(async medium => {
582
+ if (medium.type === 'image') {
583
+ const filename = `xl/media/${medium.name}.${medium.extension}`;
584
+ if (medium.filename) {
585
+ const data = await fsReadFileAsync(medium.filename);
586
+ return zip.append(data, {
587
+ name: filename
588
+ });
589
+ }
590
+ if (medium.buffer) {
591
+ return zip.append(medium.buffer, {
592
+ name: filename
593
+ });
594
+ }
595
+ if (medium.base64) {
596
+ const dataimg64 = medium.base64;
597
+ const content = dataimg64.substring(dataimg64.indexOf(',') + 1);
598
+ return zip.append(content, {
599
+ name: filename,
600
+ base64: true
601
+ });
602
+ }
603
+ }
604
+ throw new Error('Unsupported media');
605
+ }));
606
+ }
607
+ addDrawings(zip, model) {
608
+ const drawingXform = new DrawingXform();
609
+ const relsXform = new RelationshipsXform();
610
+
611
+ // First add preserved drawings (with charts)
612
+ if (model.preservedDrawingsXml) {
613
+ Object.keys(model.preservedDrawingsXml).forEach(name => {
614
+ zip.append(model.preservedDrawingsXml[name], {
615
+ name: `xl/drawings/${name}.xml`
616
+ });
617
+ });
618
+ }
619
+ if (model.preservedDrawingsRels) {
620
+ Object.keys(model.preservedDrawingsRels).forEach(name => {
621
+ const xml = relsXform.toXml(model.preservedDrawingsRels[name]);
622
+ zip.append(xml, {
623
+ name: `xl/drawings/_rels/${name}.xml.rels`
624
+ });
625
+ });
626
+ }
627
+
628
+ // Then add programmatic drawings
629
+ model.worksheets.forEach(worksheet => {
630
+ const {
631
+ drawing,
632
+ preservedDrawing
633
+ } = worksheet;
634
+ // Skip if this is a preserved drawing (already written above)
635
+ if (drawing && !preservedDrawing) {
636
+ drawingXform.prepare(drawing, {});
637
+ let xml = drawingXform.toXml(drawing);
638
+ zip.append(xml, {
639
+ name: `xl/drawings/${drawing.name}.xml`
640
+ });
641
+ xml = relsXform.toXml(drawing.rels);
642
+ zip.append(xml, {
643
+ name: `xl/drawings/_rels/${drawing.name}.xml.rels`
644
+ });
645
+ }
646
+ });
647
+ }
648
+ addTables(zip, model) {
649
+ const tableXform = new TableXform();
650
+ model.worksheets.forEach(worksheet => {
651
+ const {
652
+ tables
653
+ } = worksheet;
654
+ tables.forEach(table => {
655
+ tableXform.prepare(table, {});
656
+ const tableXml = tableXform.toXml(table);
657
+ zip.append(tableXml, {
658
+ name: `xl/tables/${table.target}`
659
+ });
660
+ });
661
+ });
662
+ }
663
+ addCtrlProps(zip, model) {
664
+ if (!model.formControlRefs || !model.formControlRefs.length) return;
665
+ const ctrlPropXform = new CtrlPropXform();
666
+ model.formControlRefs.forEach(ref => {
667
+ const ctrlPropXml = ctrlPropXform.toXml(ref.model);
668
+ zip.append(ctrlPropXml, {
669
+ name: `xl/ctrlProps/ctrlProp${ref.id}.xml`
670
+ });
671
+ });
672
+ }
673
+ addPivotTables(zip, model) {
674
+ const hasProgrammaticPivots = model.pivotTables && model.pivotTables.length > 0;
675
+ const hasPreservedPivots = model.preservedPivotTables && Object.keys(model.preservedPivotTables.pivotTables || {}).length > 0;
676
+ if (!hasProgrammaticPivots && !hasPreservedPivots) return;
677
+ const pivotCacheRecordsXform = new PivotCacheRecordsXform();
678
+ const pivotCacheDefinitionXform = new PivotCacheDefinitionXform();
679
+ const pivotTableXform = new PivotTableXform();
680
+ const relsXform = new RelationshipsXform();
681
+
682
+ // First, write preserved pivot tables (from round-trip)
683
+ if (hasPreservedPivots) {
684
+ const preserved = model.preservedPivotTables;
685
+
686
+ // Write pivot tables
687
+ Object.keys(preserved.pivotTables).forEach(name => {
688
+ zip.append(preserved.pivotTables[name], {
689
+ name: `xl/pivotTables/${name}.xml`
690
+ });
691
+ });
692
+
693
+ // Write pivot cache definitions
694
+ Object.keys(preserved.pivotCacheDefinitions).forEach(name => {
695
+ zip.append(preserved.pivotCacheDefinitions[name], {
696
+ name: `xl/pivotCache/${name}.xml`
697
+ });
698
+ });
699
+
700
+ // Write pivot cache records
701
+ Object.keys(preserved.pivotCacheRecords).forEach(name => {
702
+ zip.append(preserved.pivotCacheRecords[name], {
703
+ name: `xl/pivotCache/${name}.xml`
704
+ });
705
+ });
706
+
707
+ // Write rels for pivot tables
708
+ Object.keys(preserved.pivotTables).forEach(name => {
709
+ const tableNum = name.match(/\d+/)[0];
710
+ const xml = relsXform.toXml([{
711
+ Id: 'rId1',
712
+ Type: XLSX.RelType.PivotCacheDefinition,
713
+ Target: `../pivotCache/pivotCacheDefinition${tableNum}.xml`
714
+ }]);
715
+ zip.append(xml, {
716
+ name: `xl/pivotTables/_rels/${name}.xml.rels`
717
+ });
718
+ });
719
+
720
+ // Write rels for pivot cache definitions
721
+ Object.keys(preserved.pivotCacheDefinitions).forEach(name => {
722
+ const tableNum = name.match(/\d+/)[0];
723
+ const xml = relsXform.toXml([{
724
+ Id: 'rId1',
725
+ Type: XLSX.RelType.PivotCacheRecords,
726
+ Target: `pivotCacheRecords${tableNum}.xml`
727
+ }]);
728
+ zip.append(xml, {
729
+ name: `xl/pivotCache/_rels/${name}.xml.rels`
730
+ });
731
+ });
732
+ }
733
+
734
+ // Then, process programmatic pivot tables
735
+ if (!hasProgrammaticPivots) return;
736
+
737
+ // Process each pivot table
738
+ model.pivotTables.forEach((pivotTable, index) => {
739
+ const tableNum = index + 1;
740
+
741
+ // pivot cache records
742
+ // --------------------------------------------------
743
+ // copy of the source data.
744
+ //
745
+ // Note: cells in the columns of the source data which are part
746
+ // of the "rows" or "columns" of the pivot table configuration are
747
+ // replaced by references to their __cache field__ identifiers.
748
+ // See "pivot cache definition" below.
749
+
750
+ let xml = pivotCacheRecordsXform.toXml(pivotTable);
751
+ zip.append(xml, {
752
+ name: `xl/pivotCache/pivotCacheRecords${tableNum}.xml`
753
+ });
754
+
755
+ // pivot cache definition
756
+ // --------------------------------------------------
757
+ // cache source (source data):
758
+ // ref="A1:E7" on sheet="Sheet1"
759
+ // cache fields:
760
+ // - 0: "A" (a1, a2, a3)
761
+ // - 1: "B" (b1, b2)
762
+ // - ...
763
+
764
+ xml = pivotCacheDefinitionXform.toXml(pivotTable);
765
+ zip.append(xml, {
766
+ name: `xl/pivotCache/pivotCacheDefinition${tableNum}.xml`
767
+ });
768
+ xml = relsXform.toXml([{
769
+ Id: 'rId1',
770
+ Type: XLSX.RelType.PivotCacheRecords,
771
+ Target: `pivotCacheRecords${tableNum}.xml`
772
+ }]);
773
+ zip.append(xml, {
774
+ name: `xl/pivotCache/_rels/pivotCacheDefinition${tableNum}.xml.rels`
775
+ });
776
+
777
+ // pivot tables (on destination worksheet)
778
+ // --------------------------------------------------
779
+ // location: ref="A3:E15"
780
+ // pivotFields
781
+ // rowFields and rowItems
782
+ // colFields and colItems
783
+ // dataFields
784
+ // pivotTableStyleInfo
785
+
786
+ xml = pivotTableXform.toXml(pivotTable);
787
+ zip.append(xml, {
788
+ name: `xl/pivotTables/pivotTable${tableNum}.xml`
789
+ });
790
+ xml = relsXform.toXml([{
791
+ Id: 'rId1',
792
+ Type: XLSX.RelType.PivotCacheDefinition,
793
+ Target: `../pivotCache/pivotCacheDefinition${tableNum}.xml`
794
+ }]);
795
+ zip.append(xml, {
796
+ name: `xl/pivotTables/_rels/pivotTable${tableNum}.xml.rels`
797
+ });
798
+ });
799
+ }
800
+ addCharts(zip, model) {
801
+ const hasPreservedCharts = model.preservedChartsXml && Object.keys(model.preservedChartsXml).length > 0;
802
+ if (!hasPreservedCharts) return;
803
+ const relsXform = new RelationshipsXform();
804
+
805
+ // Write chart XML files
806
+ Object.keys(model.preservedChartsXml).forEach(name => {
807
+ zip.append(model.preservedChartsXml[name], {
808
+ name: `xl/charts/${name}.xml`
809
+ });
810
+ });
811
+
812
+ // Write chart relationship files
813
+ Object.keys(model.preservedChartsRels || {}).forEach(name => {
814
+ const xml = relsXform.toXml(model.preservedChartsRels[name]);
815
+ zip.append(xml, {
816
+ name: `xl/charts/_rels/${name}.xml.rels`
817
+ });
818
+ });
819
+
820
+ // Write chart style files
821
+ Object.keys(model.preservedChartStylesXml || {}).forEach(name => {
822
+ zip.append(model.preservedChartStylesXml[name], {
823
+ name: `xl/charts/${name}.xml`
824
+ });
825
+ });
826
+
827
+ // Write chart colors files
828
+ Object.keys(model.preservedChartColorsXml || {}).forEach(name => {
829
+ zip.append(model.preservedChartColorsXml[name], {
830
+ name: `xl/charts/${name}.xml`
831
+ });
832
+ });
833
+ }
834
+ async addContentTypes(zip, model) {
835
+ const xform = new ContentTypesXform();
836
+ const xml = xform.toXml(model);
837
+ zip.append(xml, {
838
+ name: '[Content_Types].xml'
839
+ });
840
+ }
841
+ async addApp(zip, model) {
842
+ const xform = new AppXform();
843
+ const xml = xform.toXml(model);
844
+ zip.append(xml, {
845
+ name: 'docProps/app.xml'
846
+ });
847
+ }
848
+ async addCore(zip, model) {
849
+ const coreXform = new CoreXform();
850
+ zip.append(coreXform.toXml(model), {
851
+ name: 'docProps/core.xml'
852
+ });
853
+ }
854
+ async addThemes(zip, model) {
855
+ const themes = model.themes || {
856
+ theme1: theme1Xml
857
+ };
858
+ Object.keys(themes).forEach(name => {
859
+ const xml = themes[name];
860
+ const path = `xl/theme/${name}.xml`;
861
+ zip.append(xml, {
862
+ name: path
863
+ });
864
+ });
865
+ }
866
+ async addOfficeRels(zip) {
867
+ const xform = new RelationshipsXform();
868
+ const xml = xform.toXml([{
869
+ Id: 'rId1',
870
+ Type: XLSX.RelType.OfficeDocument,
871
+ Target: 'xl/workbook.xml'
872
+ }, {
873
+ Id: 'rId2',
874
+ Type: XLSX.RelType.CoreProperties,
875
+ Target: 'docProps/core.xml'
876
+ }, {
877
+ Id: 'rId3',
878
+ Type: XLSX.RelType.ExtenderProperties,
879
+ Target: 'docProps/app.xml'
880
+ }]);
881
+ zip.append(xml, {
882
+ name: '_rels/.rels'
883
+ });
884
+ }
885
+ async addWorkbookRels(zip, model) {
886
+ let count = 1;
887
+ const relationships = [{
888
+ Id: `rId${count++}`,
889
+ Type: XLSX.RelType.Styles,
890
+ Target: 'styles.xml'
891
+ }, {
892
+ Id: `rId${count++}`,
893
+ Type: XLSX.RelType.Theme,
894
+ Target: 'theme/theme1.xml'
895
+ }];
896
+ if (model.sharedStrings.count) {
897
+ relationships.push({
898
+ Id: `rId${count++}`,
899
+ Type: XLSX.RelType.SharedStrings,
900
+ Target: 'sharedStrings.xml'
901
+ });
902
+ }
903
+ // Add relationships for programmatic pivot tables
904
+ if ((model.pivotTables || []).length) {
905
+ model.pivotTables.forEach((pivotTable, index) => {
906
+ const tableNum = index + 1;
907
+ pivotTable.rId = `rId${count++}`;
908
+ relationships.push({
909
+ Id: pivotTable.rId,
910
+ Type: XLSX.RelType.PivotCacheDefinition,
911
+ Target: `pivotCache/pivotCacheDefinition${tableNum}.xml`
912
+ });
913
+ });
914
+ }
915
+
916
+ // Add relationships for preserved pivot tables (from round-trip)
917
+ if (model.preservedPivotCaches && model.preservedPivotCaches.length) {
918
+ model.preservedPivotCaches.forEach(cache => {
919
+ cache.rId = `rId${count++}`;
920
+ relationships.push({
921
+ Id: cache.rId,
922
+ Type: XLSX.RelType.PivotCacheDefinition,
923
+ Target: `pivotCache/${cache.definitionFilename}`
924
+ });
925
+ });
926
+ }
927
+ model.worksheets.forEach(worksheet => {
928
+ worksheet.rId = `rId${count++}`;
929
+ relationships.push({
930
+ Id: worksheet.rId,
931
+ Type: XLSX.RelType.Worksheet,
932
+ Target: `worksheets/sheet${worksheet.id}.xml`
933
+ });
934
+ });
935
+ const xform = new RelationshipsXform();
936
+ const xml = xform.toXml(relationships);
937
+ zip.append(xml, {
938
+ name: 'xl/_rels/workbook.xml.rels'
939
+ });
940
+ }
941
+ async addSharedStrings(zip, model) {
942
+ if (model.sharedStrings && model.sharedStrings.count) {
943
+ zip.append(model.sharedStrings.xml, {
944
+ name: 'xl/sharedStrings.xml'
945
+ });
946
+ }
947
+ }
948
+ async addStyles(zip, model) {
949
+ const {
950
+ xml
951
+ } = model.styles;
952
+ if (xml) {
953
+ zip.append(xml, {
954
+ name: 'xl/styles.xml'
955
+ });
956
+ }
957
+ }
958
+ async addWorkbook(zip, model) {
959
+ const xform = new WorkbookXform();
960
+ zip.append(xform.toXml(model), {
961
+ name: 'xl/workbook.xml'
962
+ });
963
+ }
964
+ async addWorksheets(zip, model) {
965
+ // preparation phase
966
+ const worksheetXform = new WorksheetXform();
967
+ const relationshipsXform = new RelationshipsXform();
968
+ const commentsXform = new CommentsXform();
969
+ const vmlNotesXform = new VmlNotesXform();
970
+
971
+ // write sheets
972
+ model.worksheets.forEach(worksheet => {
973
+ let xmlStream = new XmlStream();
974
+ worksheetXform.render(xmlStream, worksheet);
975
+ zip.append(xmlStream.xml, {
976
+ name: `xl/worksheets/sheet${worksheet.id}.xml`
977
+ });
978
+ if (worksheet.rels && worksheet.rels.length) {
979
+ xmlStream = new XmlStream();
980
+ relationshipsXform.render(xmlStream, worksheet.rels);
981
+ zip.append(xmlStream.xml, {
982
+ name: `xl/worksheets/_rels/sheet${worksheet.id}.xml.rels`
983
+ });
984
+ }
985
+ if (worksheet.comments.length > 0) {
986
+ xmlStream = new XmlStream();
987
+ commentsXform.render(xmlStream, worksheet);
988
+ zip.append(xmlStream.xml, {
989
+ name: `xl/comments${worksheet.id}.xml`
990
+ });
991
+ xmlStream = new XmlStream();
992
+ vmlNotesXform.render(xmlStream, worksheet);
993
+ zip.append(xmlStream.xml, {
994
+ name: `xl/drawings/vmlDrawing${worksheet.id}.vml`
995
+ });
996
+ } else if (worksheet.formControls && worksheet.formControls.length > 0) {
997
+ // VML file for form controls (no comments)
998
+ xmlStream = new XmlStream();
999
+ vmlNotesXform.render(xmlStream, worksheet);
1000
+ zip.append(xmlStream.xml, {
1001
+ name: `xl/drawings/vmlDrawing${worksheet.id}.vml`
1002
+ });
1003
+ }
1004
+ });
1005
+ }
1006
+ _finalize(zip) {
1007
+ return new Promise((resolve, reject) => {
1008
+ zip.on('finish', () => {
1009
+ resolve(this);
1010
+ });
1011
+ zip.on('error', reject);
1012
+ zip.finalize();
1013
+ });
1014
+ }
1015
+ prepareModel(model, options) {
1016
+ // ensure following properties have sane values
1017
+ model.creator = model.creator || 'ExcelJS';
1018
+ model.lastModifiedBy = model.lastModifiedBy || 'ExcelJS';
1019
+ model.created = model.created || new Date();
1020
+ model.modified = model.modified || new Date();
1021
+ model.useSharedStrings = options.useSharedStrings !== undefined ? options.useSharedStrings : true;
1022
+ model.useStyles = options.useStyles !== undefined ? options.useStyles : true;
1023
+
1024
+ // Manage the shared strings
1025
+ model.sharedStrings = new SharedStringsXform();
1026
+
1027
+ // add a style manager to handle cell formats, fonts, etc.
1028
+ model.styles = model.useStyles ? new StylesXform(true) : new StylesXform.Mock();
1029
+
1030
+ // prepare all of the things before the render
1031
+ const workbookXform = new WorkbookXform();
1032
+ const worksheetXform = new WorksheetXform();
1033
+ workbookXform.prepare(model);
1034
+ const worksheetOptions = {
1035
+ sharedStrings: model.sharedStrings,
1036
+ styles: model.styles,
1037
+ date1904: model.properties.date1904,
1038
+ drawingsCount: 0,
1039
+ media: model.media
1040
+ };
1041
+ worksheetOptions.drawings = model.drawings = [];
1042
+ worksheetOptions.commentRefs = model.commentRefs = [];
1043
+ worksheetOptions.formControlRefs = model.formControlRefs = [];
1044
+ let tableCount = 0;
1045
+ model.tables = [];
1046
+ model.worksheets.forEach(worksheet => {
1047
+ // assign unique filenames to tables
1048
+ worksheet.tables.forEach(table => {
1049
+ tableCount++;
1050
+ table.target = `table${tableCount}.xml`;
1051
+ table.id = tableCount;
1052
+ model.tables.push(table);
1053
+ });
1054
+ worksheetXform.prepare(worksheet, worksheetOptions);
1055
+ });
1056
+
1057
+ // TODO: workbook drawing list
1058
+ }
1059
+ async write(stream, options) {
1060
+ options = options || {};
1061
+ const {
1062
+ model
1063
+ } = this.workbook;
1064
+ const zip = new ZipStream.ZipWriter(options.zip);
1065
+ zip.pipe(stream);
1066
+ this.prepareModel(model, options);
1067
+
1068
+ // render
1069
+ await this.addContentTypes(zip, model);
1070
+ await this.addOfficeRels(zip, model);
1071
+ await this.addWorkbookRels(zip, model);
1072
+ await this.addWorksheets(zip, model);
1073
+ await this.addSharedStrings(zip, model); // always after worksheets
1074
+ await this.addDrawings(zip, model);
1075
+ await this.addTables(zip, model);
1076
+ await this.addCtrlProps(zip, model);
1077
+ await this.addPivotTables(zip, model);
1078
+ await this.addCharts(zip, model);
1079
+ await Promise.all([this.addThemes(zip, model), this.addStyles(zip, model)]);
1080
+ await this.addMedia(zip, model);
1081
+ await Promise.all([this.addApp(zip, model), this.addCore(zip, model)]);
1082
+ await this.addWorkbook(zip, model);
1083
+ return this._finalize(zip);
1084
+ }
1085
+ writeFile(filename, options) {
1086
+ const stream = fs.createWriteStream(filename);
1087
+ return new Promise((resolve, reject) => {
1088
+ stream.on('finish', () => {
1089
+ resolve();
1090
+ });
1091
+ stream.on('error', error => {
1092
+ reject(error);
1093
+ });
1094
+ this.write(stream, options).then(() => {
1095
+ stream.end();
1096
+ }).catch(err => {
1097
+ reject(err);
1098
+ });
1099
+ });
1100
+ }
1101
+ async writeBuffer(options) {
1102
+ const stream = new StreamBuf();
1103
+ await this.write(stream, options);
1104
+ return stream.read();
1105
+ }
1106
+ }
1107
+ XLSX.RelType = require('./rel-type');
1108
+ module.exports = XLSX;
1109
+ //# sourceMappingURL=xlsx.js.map