@cj-tech-master/excelts 1.6.3 → 2.0.0

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 (400) hide show
  1. package/README.md +139 -24
  2. package/README_zh.md +140 -26
  3. package/dist/browser/excelts.esm.js +18468 -0
  4. package/dist/browser/excelts.esm.js.map +1 -0
  5. package/dist/browser/excelts.esm.min.js +125 -0
  6. package/dist/browser/excelts.iife.js +13107 -47146
  7. package/dist/browser/excelts.iife.js.map +1 -1
  8. package/dist/browser/excelts.iife.min.js +24 -106
  9. package/dist/cjs/csv/csv-core.js +701 -0
  10. package/dist/cjs/csv/csv-stream.js +646 -0
  11. package/dist/cjs/csv/csv.base.js +137 -0
  12. package/dist/cjs/csv/csv.browser.js +68 -0
  13. package/dist/cjs/csv/csv.js +218 -162
  14. package/dist/cjs/doc/anchor.js +2 -2
  15. package/dist/cjs/doc/cell.js +22 -22
  16. package/dist/cjs/doc/column.js +28 -7
  17. package/dist/cjs/doc/data-validations.js +3 -3
  18. package/dist/cjs/doc/defined-names.js +13 -13
  19. package/dist/cjs/doc/image.js +7 -7
  20. package/dist/cjs/doc/modelcontainer.js +2 -2
  21. package/dist/cjs/doc/note.js +2 -2
  22. package/dist/cjs/doc/pivot-table.js +5 -5
  23. package/dist/cjs/doc/range.js +11 -11
  24. package/dist/cjs/doc/row.js +16 -16
  25. package/dist/cjs/doc/table.js +5 -5
  26. package/dist/cjs/doc/workbook.base.js +211 -0
  27. package/dist/cjs/doc/workbook.browser.js +62 -0
  28. package/dist/cjs/doc/workbook.js +68 -179
  29. package/dist/cjs/doc/worksheet.js +45 -41
  30. package/dist/cjs/index.js +49 -32
  31. package/dist/cjs/stream/xlsx/hyperlink-reader.js +6 -6
  32. package/dist/cjs/stream/xlsx/sheet-comments-writer.js +12 -12
  33. package/dist/cjs/stream/xlsx/sheet-rels-writer.js +4 -4
  34. package/dist/cjs/stream/xlsx/workbook-reader.js +22 -22
  35. package/dist/cjs/stream/xlsx/workbook-writer.js +38 -38
  36. package/dist/cjs/stream/xlsx/worksheet-reader.js +17 -17
  37. package/dist/cjs/stream/xlsx/worksheet-writer.js +67 -60
  38. package/dist/cjs/utils/browser-buffer.js +75 -0
  39. package/dist/cjs/utils/cell-format.js +2 -2
  40. package/dist/cjs/utils/cell-matrix.js +5 -5
  41. package/dist/cjs/utils/datetime.js +648 -0
  42. package/dist/cjs/utils/encryptor.browser.js +240 -0
  43. package/dist/cjs/utils/parse-sax.js +1191 -13
  44. package/dist/cjs/utils/shared-formula.js +5 -5
  45. package/dist/cjs/utils/sheet-utils.js +13 -13
  46. package/dist/cjs/utils/stream-buf.browser.js +355 -0
  47. package/dist/cjs/utils/stream-buf.js +5 -5
  48. package/dist/cjs/utils/unzip/extract.js +11 -11
  49. package/dist/cjs/utils/unzip/index.js +21 -21
  50. package/dist/cjs/utils/unzip/parse-extra-field.js +3 -3
  51. package/dist/cjs/utils/unzip/parse.js +16 -16
  52. package/dist/cjs/utils/unzip/zip-parser.js +14 -3
  53. package/dist/cjs/utils/utils.base.js +161 -0
  54. package/dist/cjs/utils/utils.browser.js +89 -0
  55. package/dist/cjs/utils/utils.js +46 -154
  56. package/dist/cjs/utils/xml-stream.js +3 -3
  57. package/dist/cjs/utils/zip/compress.base.js +88 -0
  58. package/dist/cjs/utils/zip/compress.browser.js +127 -0
  59. package/dist/cjs/utils/zip/compress.js +18 -198
  60. package/dist/cjs/utils/zip/crc32.browser.js +88 -0
  61. package/dist/cjs/utils/zip/deflate-fallback.js +575 -0
  62. package/dist/cjs/utils/zip/index.js +17 -17
  63. package/dist/cjs/utils/zip/streaming-zip.js +264 -0
  64. package/dist/cjs/utils/zip/zip-builder.js +10 -10
  65. package/dist/cjs/utils/zip-stream.browser.js +135 -0
  66. package/dist/cjs/utils/zip-stream.js +4 -4
  67. package/dist/cjs/xlsx/xform/base-xform.js +4 -4
  68. package/dist/cjs/xlsx/xform/book/defined-name-xform.js +4 -4
  69. package/dist/cjs/xlsx/xform/book/sheet-xform.js +4 -4
  70. package/dist/cjs/xlsx/xform/book/workbook-calc-properties-xform.js +2 -2
  71. package/dist/cjs/xlsx/xform/book/workbook-pivot-cache-xform.js +2 -2
  72. package/dist/cjs/xlsx/xform/book/workbook-properties-xform.js +2 -2
  73. package/dist/cjs/xlsx/xform/book/workbook-view-xform.js +2 -2
  74. package/dist/cjs/xlsx/xform/book/workbook-xform.js +24 -24
  75. package/dist/cjs/xlsx/xform/comment/comment-xform.js +4 -4
  76. package/dist/cjs/xlsx/xform/comment/comments-xform.js +6 -6
  77. package/dist/cjs/xlsx/xform/comment/style/vml-position-xform.js +2 -2
  78. package/dist/cjs/xlsx/xform/comment/style/vml-protection-xform.js +2 -2
  79. package/dist/cjs/xlsx/xform/comment/vml-anchor-xform.js +2 -2
  80. package/dist/cjs/xlsx/xform/comment/vml-client-data-xform.js +10 -10
  81. package/dist/cjs/xlsx/xform/comment/vml-notes-xform.js +6 -6
  82. package/dist/cjs/xlsx/xform/comment/vml-shape-xform.js +6 -6
  83. package/dist/cjs/xlsx/xform/comment/vml-textbox-xform.js +2 -2
  84. package/dist/cjs/xlsx/xform/composite-xform.js +2 -2
  85. package/dist/cjs/xlsx/xform/core/app-heading-pairs-xform.js +2 -2
  86. package/dist/cjs/xlsx/xform/core/app-titles-of-parts-xform.js +2 -2
  87. package/dist/cjs/xlsx/xform/core/app-xform.js +11 -11
  88. package/dist/cjs/xlsx/xform/core/content-types-xform.js +4 -4
  89. package/dist/cjs/xlsx/xform/core/core-xform.js +23 -23
  90. package/dist/cjs/xlsx/xform/core/relationship-xform.js +2 -2
  91. package/dist/cjs/xlsx/xform/core/relationships-xform.js +6 -6
  92. package/dist/cjs/xlsx/xform/drawing/base-cell-anchor-xform.js +2 -2
  93. package/dist/cjs/xlsx/xform/drawing/blip-fill-xform.js +4 -4
  94. package/dist/cjs/xlsx/xform/drawing/blip-xform.js +2 -2
  95. package/dist/cjs/xlsx/xform/drawing/c-nv-pic-pr-xform.js +2 -2
  96. package/dist/cjs/xlsx/xform/drawing/c-nv-pr-xform.js +6 -6
  97. package/dist/cjs/xlsx/xform/drawing/cell-position-xform.js +7 -7
  98. package/dist/cjs/xlsx/xform/drawing/drawing-xform.js +10 -10
  99. package/dist/cjs/xlsx/xform/drawing/ext-lst-xform.js +2 -2
  100. package/dist/cjs/xlsx/xform/drawing/ext-xform.js +2 -2
  101. package/dist/cjs/xlsx/xform/drawing/hlink-click-xform.js +2 -2
  102. package/dist/cjs/xlsx/xform/drawing/nv-pic-pr-xform.js +6 -6
  103. package/dist/cjs/xlsx/xform/drawing/one-cell-anchor-xform.js +10 -10
  104. package/dist/cjs/xlsx/xform/drawing/pic-xform.js +9 -9
  105. package/dist/cjs/xlsx/xform/drawing/two-cell-anchor-xform.js +9 -9
  106. package/dist/cjs/xlsx/xform/list-xform.js +2 -2
  107. package/dist/cjs/xlsx/xform/pivot-table/cache-field-xform.js +5 -5
  108. package/dist/cjs/xlsx/xform/pivot-table/cache-field.js +3 -3
  109. package/dist/cjs/xlsx/xform/pivot-table/pivot-cache-definition-xform.js +10 -10
  110. package/dist/cjs/xlsx/xform/pivot-table/pivot-cache-records-xform.js +9 -9
  111. package/dist/cjs/xlsx/xform/pivot-table/pivot-table-xform.js +10 -11
  112. package/dist/cjs/xlsx/xform/sheet/auto-filter-xform.js +4 -4
  113. package/dist/cjs/xlsx/xform/sheet/cell-xform.js +65 -65
  114. package/dist/cjs/xlsx/xform/sheet/cf/cf-rule-xform.js +27 -27
  115. package/dist/cjs/xlsx/xform/sheet/cf/cfvo-xform.js +3 -3
  116. package/dist/cjs/xlsx/xform/sheet/cf/color-scale-xform.js +6 -6
  117. package/dist/cjs/xlsx/xform/sheet/cf/conditional-formatting-xform.js +6 -6
  118. package/dist/cjs/xlsx/xform/sheet/cf/conditional-formattings-xform.js +4 -4
  119. package/dist/cjs/xlsx/xform/sheet/cf/databar-xform.js +6 -6
  120. package/dist/cjs/xlsx/xform/sheet/cf/ext-lst-ref-xform.js +5 -5
  121. package/dist/cjs/xlsx/xform/sheet/cf/formula-xform.js +2 -2
  122. package/dist/cjs/xlsx/xform/sheet/cf/icon-set-xform.js +11 -11
  123. package/dist/cjs/xlsx/xform/sheet/cf-ext/cf-icon-ext-xform.js +3 -3
  124. package/dist/cjs/xlsx/xform/sheet/cf-ext/cf-rule-ext-xform.js +11 -12
  125. package/dist/cjs/xlsx/xform/sheet/cf-ext/cfvo-ext-xform.js +4 -4
  126. package/dist/cjs/xlsx/xform/sheet/cf-ext/conditional-formatting-ext-xform.js +8 -8
  127. package/dist/cjs/xlsx/xform/sheet/cf-ext/conditional-formattings-ext-xform.js +6 -6
  128. package/dist/cjs/xlsx/xform/sheet/cf-ext/databar-ext-xform.js +26 -26
  129. package/dist/cjs/xlsx/xform/sheet/cf-ext/f-ext-xform.js +2 -2
  130. package/dist/cjs/xlsx/xform/sheet/cf-ext/icon-set-ext-xform.js +14 -14
  131. package/dist/cjs/xlsx/xform/sheet/cf-ext/sqref-ext-xform.js +2 -2
  132. package/dist/cjs/xlsx/xform/sheet/col-breaks-xform.js +38 -0
  133. package/dist/cjs/xlsx/xform/sheet/col-xform.js +6 -6
  134. package/dist/cjs/xlsx/xform/sheet/data-validations-xform.js +18 -18
  135. package/dist/cjs/xlsx/xform/sheet/dimension-xform.js +2 -2
  136. package/dist/cjs/xlsx/xform/sheet/drawing-xform.js +2 -2
  137. package/dist/cjs/xlsx/xform/sheet/ext-lst-xform.js +5 -5
  138. package/dist/cjs/xlsx/xform/sheet/header-footer-xform.js +2 -2
  139. package/dist/cjs/xlsx/xform/sheet/hyperlink-xform.js +2 -2
  140. package/dist/cjs/xlsx/xform/sheet/merge-cell-xform.js +2 -2
  141. package/dist/cjs/xlsx/xform/sheet/merges.js +8 -8
  142. package/dist/cjs/xlsx/xform/sheet/outline-properties-xform.js +2 -2
  143. package/dist/cjs/xlsx/xform/sheet/page-breaks-xform.js +15 -3
  144. package/dist/cjs/xlsx/xform/sheet/page-margins-xform.js +2 -2
  145. package/dist/cjs/xlsx/xform/sheet/page-setup-properties-xform.js +2 -2
  146. package/dist/cjs/xlsx/xform/sheet/page-setup-xform.js +2 -2
  147. package/dist/cjs/xlsx/xform/sheet/picture-xform.js +2 -2
  148. package/dist/cjs/xlsx/xform/sheet/print-options-xform.js +2 -2
  149. package/dist/cjs/xlsx/xform/sheet/row-breaks-xform.js +15 -17
  150. package/dist/cjs/xlsx/xform/sheet/row-xform.js +11 -11
  151. package/dist/cjs/xlsx/xform/sheet/sheet-format-properties-xform.js +2 -2
  152. package/dist/cjs/xlsx/xform/sheet/sheet-properties-xform.js +8 -8
  153. package/dist/cjs/xlsx/xform/sheet/sheet-protection-xform.js +2 -2
  154. package/dist/cjs/xlsx/xform/sheet/sheet-view-xform.js +4 -4
  155. package/dist/cjs/xlsx/xform/sheet/table-part-xform.js +2 -2
  156. package/dist/cjs/xlsx/xform/sheet/worksheet-xform.js +75 -70
  157. package/dist/cjs/xlsx/xform/simple/boolean-xform.js +2 -2
  158. package/dist/cjs/xlsx/xform/simple/date-xform.js +2 -2
  159. package/dist/cjs/xlsx/xform/simple/float-xform.js +2 -2
  160. package/dist/cjs/xlsx/xform/simple/integer-xform.js +2 -2
  161. package/dist/cjs/xlsx/xform/simple/string-xform.js +2 -2
  162. package/dist/cjs/xlsx/xform/static-xform.js +4 -4
  163. package/dist/cjs/xlsx/xform/strings/phonetic-text-xform.js +6 -6
  164. package/dist/cjs/xlsx/xform/strings/rich-text-xform.js +6 -6
  165. package/dist/cjs/xlsx/xform/strings/shared-string-xform.js +8 -8
  166. package/dist/cjs/xlsx/xform/strings/shared-strings-xform.js +6 -6
  167. package/dist/cjs/xlsx/xform/strings/text-xform.js +2 -2
  168. package/dist/cjs/xlsx/xform/style/alignment-xform.js +8 -8
  169. package/dist/cjs/xlsx/xform/style/border-xform.js +8 -8
  170. package/dist/cjs/xlsx/xform/style/color-xform.js +2 -2
  171. package/dist/cjs/xlsx/xform/style/dxf-xform.js +14 -14
  172. package/dist/cjs/xlsx/xform/style/fill-xform.js +9 -9
  173. package/dist/cjs/xlsx/xform/style/font-xform.js +22 -22
  174. package/dist/cjs/xlsx/xform/style/numfmt-xform.js +5 -5
  175. package/dist/cjs/xlsx/xform/style/protection-xform.js +2 -2
  176. package/dist/cjs/xlsx/xform/style/style-xform.js +6 -6
  177. package/dist/cjs/xlsx/xform/style/styles-xform.js +39 -39
  178. package/dist/cjs/xlsx/xform/style/underline-xform.js +2 -2
  179. package/dist/cjs/xlsx/xform/table/auto-filter-xform.js +4 -4
  180. package/dist/cjs/xlsx/xform/table/custom-filter-xform.js +2 -2
  181. package/dist/cjs/xlsx/xform/table/filter-column-xform.js +9 -9
  182. package/dist/cjs/xlsx/xform/table/filter-xform.js +2 -2
  183. package/dist/cjs/xlsx/xform/table/table-column-xform.js +2 -2
  184. package/dist/cjs/xlsx/xform/table/table-style-info-xform.js +2 -2
  185. package/dist/cjs/xlsx/xform/table/table-xform.js +12 -12
  186. package/dist/cjs/xlsx/xlsx.base.js +742 -0
  187. package/dist/cjs/xlsx/xlsx.browser.js +162 -0
  188. package/dist/cjs/xlsx/xlsx.js +118 -892
  189. package/dist/esm/csv/csv-core.js +694 -0
  190. package/dist/esm/csv/csv-stream.js +638 -0
  191. package/dist/esm/csv/csv.base.js +127 -0
  192. package/dist/esm/csv/csv.browser.js +65 -0
  193. package/dist/esm/csv/csv.js +181 -159
  194. package/dist/esm/doc/column.js +21 -0
  195. package/dist/esm/doc/workbook.base.js +207 -0
  196. package/dist/esm/doc/workbook.browser.js +59 -0
  197. package/dist/esm/doc/workbook.js +64 -175
  198. package/dist/esm/doc/worksheet.js +4 -0
  199. package/dist/esm/index.browser.js +33 -1
  200. package/dist/esm/index.js +23 -8
  201. package/dist/esm/local.js +0 -1
  202. package/dist/esm/stream/xlsx/workbook-writer.js +1 -1
  203. package/dist/esm/stream/xlsx/worksheet-writer.js +8 -1
  204. package/dist/esm/utils/browser-buffer.js +67 -0
  205. package/dist/esm/utils/datetime.js +639 -0
  206. package/dist/esm/utils/encryptor.browser.js +237 -0
  207. package/dist/esm/utils/parse-sax.js +1188 -12
  208. package/dist/esm/utils/stream-buf.browser.js +352 -0
  209. package/dist/esm/utils/unzip/zip-parser.js +11 -0
  210. package/dist/esm/utils/utils.base.js +142 -0
  211. package/dist/esm/utils/utils.browser.js +68 -0
  212. package/dist/esm/utils/utils.js +15 -123
  213. package/dist/esm/utils/zip/compress.base.js +83 -0
  214. package/dist/esm/utils/zip/compress.browser.js +121 -0
  215. package/dist/esm/utils/zip/compress.js +16 -164
  216. package/dist/esm/utils/zip/crc32.browser.js +82 -0
  217. package/dist/esm/utils/zip/deflate-fallback.js +570 -0
  218. package/dist/esm/utils/zip/streaming-zip.js +259 -0
  219. package/dist/esm/utils/zip-stream.browser.js +132 -0
  220. package/dist/esm/xlsx/xform/pivot-table/pivot-table-xform.js +2 -3
  221. package/dist/esm/xlsx/xform/sheet/cf-ext/cf-rule-ext-xform.js +2 -3
  222. package/dist/esm/xlsx/xform/sheet/col-breaks-xform.js +35 -0
  223. package/dist/esm/xlsx/xform/sheet/page-breaks-xform.js +13 -1
  224. package/dist/esm/xlsx/xform/sheet/row-breaks-xform.js +11 -13
  225. package/dist/esm/xlsx/xform/sheet/worksheet-xform.js +7 -2
  226. package/dist/esm/xlsx/xlsx.base.js +739 -0
  227. package/dist/esm/xlsx/xlsx.browser.js +159 -0
  228. package/dist/esm/xlsx/xlsx.js +114 -888
  229. package/dist/types/csv/csv-core.d.ts +207 -0
  230. package/dist/types/csv/csv-stream.d.ts +114 -0
  231. package/dist/types/csv/csv.base.d.ts +62 -0
  232. package/dist/types/csv/csv.browser.d.ts +33 -0
  233. package/dist/types/csv/csv.d.ts +97 -71
  234. package/dist/types/doc/anchor.d.ts +1 -1
  235. package/dist/types/doc/cell.d.ts +7 -7
  236. package/dist/types/doc/column.d.ts +9 -3
  237. package/dist/types/doc/defined-names.d.ts +4 -4
  238. package/dist/types/doc/image.d.ts +2 -2
  239. package/dist/types/doc/modelcontainer.d.ts +1 -1
  240. package/dist/types/doc/pivot-table.d.ts +1 -1
  241. package/dist/types/doc/range.d.ts +1 -1
  242. package/dist/types/doc/row.d.ts +3 -3
  243. package/dist/types/doc/table.d.ts +2 -2
  244. package/dist/types/doc/workbook.base.d.ts +111 -0
  245. package/dist/types/doc/workbook.browser.d.ts +38 -0
  246. package/dist/types/doc/workbook.d.ts +62 -92
  247. package/dist/types/doc/worksheet.d.ts +12 -10
  248. package/dist/types/index.browser.d.ts +19 -5
  249. package/dist/types/index.d.ts +24 -23
  250. package/dist/types/local.d.ts +0 -1
  251. package/dist/types/stream/xlsx/hyperlink-reader.d.ts +1 -1
  252. package/dist/types/stream/xlsx/workbook-reader.d.ts +4 -4
  253. package/dist/types/stream/xlsx/workbook-writer.d.ts +7 -7
  254. package/dist/types/stream/xlsx/worksheet-reader.d.ts +5 -5
  255. package/dist/types/stream/xlsx/worksheet-writer.d.ts +11 -9
  256. package/dist/types/types.d.ts +6 -0
  257. package/dist/types/utils/browser-buffer.d.ts +28 -0
  258. package/dist/types/utils/col-cache.d.ts +1 -1
  259. package/dist/types/utils/datetime.d.ts +85 -0
  260. package/dist/types/utils/encryptor.browser.d.ts +28 -0
  261. package/dist/types/utils/parse-sax.d.ts +108 -1
  262. package/dist/types/utils/sheet-utils.d.ts +3 -3
  263. package/dist/types/utils/stream-buf.browser.d.ts +41 -0
  264. package/dist/types/utils/unzip/extract.d.ts +6 -6
  265. package/dist/types/utils/unzip/index.d.ts +8 -8
  266. package/dist/types/utils/unzip/parse.d.ts +3 -3
  267. package/dist/types/utils/unzip/zip-parser.d.ts +5 -0
  268. package/dist/types/utils/utils.base.d.ts +29 -0
  269. package/dist/types/utils/utils.browser.d.ts +29 -0
  270. package/dist/types/utils/utils.d.ts +6 -25
  271. package/dist/types/utils/zip/compress.base.d.ts +45 -0
  272. package/dist/types/utils/zip/compress.browser.d.ts +63 -0
  273. package/dist/types/utils/zip/compress.d.ts +13 -45
  274. package/dist/types/utils/zip/crc32.browser.d.ts +52 -0
  275. package/dist/types/utils/zip/deflate-fallback.d.ts +39 -0
  276. package/dist/types/utils/zip/index.d.ts +5 -5
  277. package/dist/types/utils/zip/streaming-zip.d.ts +96 -0
  278. package/dist/types/utils/zip/zip-builder.d.ts +1 -1
  279. package/dist/types/utils/zip-stream.browser.d.ts +39 -0
  280. package/dist/types/xlsx/xform/base-xform.d.ts +1 -1
  281. package/dist/types/xlsx/xform/book/defined-name-xform.d.ts +1 -1
  282. package/dist/types/xlsx/xform/book/sheet-xform.d.ts +1 -1
  283. package/dist/types/xlsx/xform/book/workbook-calc-properties-xform.d.ts +1 -1
  284. package/dist/types/xlsx/xform/book/workbook-pivot-cache-xform.d.ts +1 -1
  285. package/dist/types/xlsx/xform/book/workbook-properties-xform.d.ts +1 -1
  286. package/dist/types/xlsx/xform/book/workbook-view-xform.d.ts +1 -1
  287. package/dist/types/xlsx/xform/book/workbook-xform.d.ts +2 -2
  288. package/dist/types/xlsx/xform/comment/comment-xform.d.ts +2 -2
  289. package/dist/types/xlsx/xform/comment/comments-xform.d.ts +2 -2
  290. package/dist/types/xlsx/xform/comment/style/vml-position-xform.d.ts +1 -1
  291. package/dist/types/xlsx/xform/comment/style/vml-protection-xform.d.ts +1 -1
  292. package/dist/types/xlsx/xform/comment/vml-anchor-xform.d.ts +1 -1
  293. package/dist/types/xlsx/xform/comment/vml-client-data-xform.d.ts +1 -1
  294. package/dist/types/xlsx/xform/comment/vml-notes-xform.d.ts +1 -1
  295. package/dist/types/xlsx/xform/comment/vml-shape-xform.d.ts +1 -1
  296. package/dist/types/xlsx/xform/comment/vml-textbox-xform.d.ts +1 -1
  297. package/dist/types/xlsx/xform/composite-xform.d.ts +1 -1
  298. package/dist/types/xlsx/xform/core/app-heading-pairs-xform.d.ts +1 -1
  299. package/dist/types/xlsx/xform/core/app-titles-of-parts-xform.d.ts +1 -1
  300. package/dist/types/xlsx/xform/core/app-xform.d.ts +1 -1
  301. package/dist/types/xlsx/xform/core/content-types-xform.d.ts +1 -1
  302. package/dist/types/xlsx/xform/core/core-xform.d.ts +1 -1
  303. package/dist/types/xlsx/xform/core/relationship-xform.d.ts +1 -1
  304. package/dist/types/xlsx/xform/core/relationships-xform.d.ts +1 -1
  305. package/dist/types/xlsx/xform/drawing/base-cell-anchor-xform.d.ts +1 -1
  306. package/dist/types/xlsx/xform/drawing/blip-fill-xform.d.ts +2 -2
  307. package/dist/types/xlsx/xform/drawing/blip-xform.d.ts +1 -1
  308. package/dist/types/xlsx/xform/drawing/c-nv-pic-pr-xform.d.ts +1 -1
  309. package/dist/types/xlsx/xform/drawing/c-nv-pr-xform.d.ts +1 -1
  310. package/dist/types/xlsx/xform/drawing/cell-position-xform.d.ts +2 -2
  311. package/dist/types/xlsx/xform/drawing/drawing-xform.d.ts +1 -1
  312. package/dist/types/xlsx/xform/drawing/ext-lst-xform.d.ts +1 -1
  313. package/dist/types/xlsx/xform/drawing/ext-xform.d.ts +1 -1
  314. package/dist/types/xlsx/xform/drawing/hlink-click-xform.d.ts +1 -1
  315. package/dist/types/xlsx/xform/drawing/nv-pic-pr-xform.d.ts +1 -1
  316. package/dist/types/xlsx/xform/drawing/one-cell-anchor-xform.d.ts +1 -1
  317. package/dist/types/xlsx/xform/drawing/pic-xform.d.ts +1 -1
  318. package/dist/types/xlsx/xform/drawing/two-cell-anchor-xform.d.ts +1 -1
  319. package/dist/types/xlsx/xform/list-xform.d.ts +1 -1
  320. package/dist/types/xlsx/xform/pivot-table/cache-field-xform.d.ts +1 -1
  321. package/dist/types/xlsx/xform/pivot-table/pivot-cache-definition-xform.d.ts +3 -3
  322. package/dist/types/xlsx/xform/pivot-table/pivot-cache-records-xform.d.ts +2 -2
  323. package/dist/types/xlsx/xform/pivot-table/pivot-table-xform.d.ts +1 -1
  324. package/dist/types/xlsx/xform/sheet/auto-filter-xform.d.ts +1 -1
  325. package/dist/types/xlsx/xform/sheet/cell-xform.d.ts +1 -1
  326. package/dist/types/xlsx/xform/sheet/cf/cf-rule-xform.d.ts +6 -6
  327. package/dist/types/xlsx/xform/sheet/cf/cfvo-xform.d.ts +1 -1
  328. package/dist/types/xlsx/xform/sheet/cf/color-scale-xform.d.ts +3 -3
  329. package/dist/types/xlsx/xform/sheet/cf/conditional-formatting-xform.d.ts +1 -1
  330. package/dist/types/xlsx/xform/sheet/cf/conditional-formattings-xform.d.ts +2 -2
  331. package/dist/types/xlsx/xform/sheet/cf/databar-xform.d.ts +3 -3
  332. package/dist/types/xlsx/xform/sheet/cf/ext-lst-ref-xform.d.ts +1 -1
  333. package/dist/types/xlsx/xform/sheet/cf/formula-xform.d.ts +1 -1
  334. package/dist/types/xlsx/xform/sheet/cf/icon-set-xform.d.ts +2 -2
  335. package/dist/types/xlsx/xform/sheet/cf-ext/cf-icon-ext-xform.d.ts +1 -1
  336. package/dist/types/xlsx/xform/sheet/cf-ext/cf-rule-ext-xform.d.ts +3 -3
  337. package/dist/types/xlsx/xform/sheet/cf-ext/cfvo-ext-xform.d.ts +2 -2
  338. package/dist/types/xlsx/xform/sheet/cf-ext/conditional-formatting-ext-xform.d.ts +3 -3
  339. package/dist/types/xlsx/xform/sheet/cf-ext/conditional-formattings-ext-xform.d.ts +2 -2
  340. package/dist/types/xlsx/xform/sheet/cf-ext/databar-ext-xform.d.ts +3 -3
  341. package/dist/types/xlsx/xform/sheet/cf-ext/f-ext-xform.d.ts +1 -1
  342. package/dist/types/xlsx/xform/sheet/cf-ext/icon-set-ext-xform.d.ts +3 -3
  343. package/dist/types/xlsx/xform/sheet/cf-ext/sqref-ext-xform.d.ts +1 -1
  344. package/dist/types/xlsx/xform/sheet/col-breaks-xform.d.ts +16 -0
  345. package/dist/types/xlsx/xform/sheet/col-xform.d.ts +1 -1
  346. package/dist/types/xlsx/xform/sheet/data-validations-xform.d.ts +1 -1
  347. package/dist/types/xlsx/xform/sheet/dimension-xform.d.ts +1 -1
  348. package/dist/types/xlsx/xform/sheet/drawing-xform.d.ts +1 -1
  349. package/dist/types/xlsx/xform/sheet/ext-lst-xform.d.ts +1 -1
  350. package/dist/types/xlsx/xform/sheet/header-footer-xform.d.ts +1 -1
  351. package/dist/types/xlsx/xform/sheet/hyperlink-xform.d.ts +1 -1
  352. package/dist/types/xlsx/xform/sheet/merge-cell-xform.d.ts +1 -1
  353. package/dist/types/xlsx/xform/sheet/outline-properties-xform.d.ts +1 -1
  354. package/dist/types/xlsx/xform/sheet/page-breaks-xform.d.ts +5 -1
  355. package/dist/types/xlsx/xform/sheet/page-margins-xform.d.ts +1 -1
  356. package/dist/types/xlsx/xform/sheet/page-setup-properties-xform.d.ts +1 -1
  357. package/dist/types/xlsx/xform/sheet/page-setup-xform.d.ts +1 -1
  358. package/dist/types/xlsx/xform/sheet/picture-xform.d.ts +1 -1
  359. package/dist/types/xlsx/xform/sheet/print-options-xform.d.ts +1 -1
  360. package/dist/types/xlsx/xform/sheet/row-breaks-xform.d.ts +5 -1
  361. package/dist/types/xlsx/xform/sheet/row-xform.d.ts +1 -1
  362. package/dist/types/xlsx/xform/sheet/sheet-format-properties-xform.d.ts +1 -1
  363. package/dist/types/xlsx/xform/sheet/sheet-properties-xform.d.ts +1 -1
  364. package/dist/types/xlsx/xform/sheet/sheet-protection-xform.d.ts +1 -1
  365. package/dist/types/xlsx/xform/sheet/sheet-view-xform.d.ts +1 -1
  366. package/dist/types/xlsx/xform/sheet/table-part-xform.d.ts +1 -1
  367. package/dist/types/xlsx/xform/sheet/worksheet-xform.d.ts +1 -1
  368. package/dist/types/xlsx/xform/simple/boolean-xform.d.ts +1 -1
  369. package/dist/types/xlsx/xform/simple/date-xform.d.ts +1 -1
  370. package/dist/types/xlsx/xform/simple/float-xform.d.ts +1 -1
  371. package/dist/types/xlsx/xform/simple/integer-xform.d.ts +1 -1
  372. package/dist/types/xlsx/xform/simple/string-xform.d.ts +1 -1
  373. package/dist/types/xlsx/xform/static-xform.d.ts +1 -1
  374. package/dist/types/xlsx/xform/strings/phonetic-text-xform.d.ts +1 -1
  375. package/dist/types/xlsx/xform/strings/rich-text-xform.d.ts +3 -3
  376. package/dist/types/xlsx/xform/strings/shared-string-xform.d.ts +1 -1
  377. package/dist/types/xlsx/xform/strings/shared-strings-xform.d.ts +2 -2
  378. package/dist/types/xlsx/xform/strings/text-xform.d.ts +1 -1
  379. package/dist/types/xlsx/xform/style/alignment-xform.d.ts +1 -1
  380. package/dist/types/xlsx/xform/style/border-xform.d.ts +2 -2
  381. package/dist/types/xlsx/xform/style/color-xform.d.ts +1 -1
  382. package/dist/types/xlsx/xform/style/dxf-xform.d.ts +1 -1
  383. package/dist/types/xlsx/xform/style/fill-xform.d.ts +2 -2
  384. package/dist/types/xlsx/xform/style/font-xform.d.ts +1 -1
  385. package/dist/types/xlsx/xform/style/numfmt-xform.d.ts +1 -1
  386. package/dist/types/xlsx/xform/style/protection-xform.d.ts +1 -1
  387. package/dist/types/xlsx/xform/style/style-xform.d.ts +3 -3
  388. package/dist/types/xlsx/xform/style/styles-xform.d.ts +2 -2
  389. package/dist/types/xlsx/xform/style/underline-xform.d.ts +1 -1
  390. package/dist/types/xlsx/xform/table/auto-filter-xform.d.ts +2 -2
  391. package/dist/types/xlsx/xform/table/custom-filter-xform.d.ts +1 -1
  392. package/dist/types/xlsx/xform/table/filter-column-xform.d.ts +2 -2
  393. package/dist/types/xlsx/xform/table/filter-xform.d.ts +1 -1
  394. package/dist/types/xlsx/xform/table/table-column-xform.d.ts +1 -1
  395. package/dist/types/xlsx/xform/table/table-style-info-xform.d.ts +1 -1
  396. package/dist/types/xlsx/xform/table/table-xform.d.ts +1 -1
  397. package/dist/types/xlsx/xlsx.base.d.ts +134 -0
  398. package/dist/types/xlsx/xlsx.browser.d.ts +31 -0
  399. package/dist/types/xlsx/xlsx.d.ts +20 -80
  400. package/package.json +16 -39
@@ -1,33 +1,27 @@
1
1
  "use strict";
2
+ /**
3
+ * XLSX - Node.js version with full functionality
4
+ *
5
+ * Extends XLSXBase with:
6
+ * - readFile: Read from file path
7
+ * - writeFile: Write to file path
8
+ * - read: Read from stream
9
+ * - write: Write to stream
10
+ * - load: Load from buffer
11
+ * - writeBuffer: Write to buffer
12
+ */
2
13
  var __importDefault = (this && this.__importDefault) || function (mod) {
3
14
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
15
  };
5
16
  Object.defineProperty(exports, "__esModule", { value: true });
6
17
  exports.XLSX = void 0;
7
18
  const fs_1 = __importDefault(require("fs"));
8
- const fflate_1 = require("fflate");
9
19
  const stream_1 = require("stream");
10
- const zip_stream_js_1 = require("../utils/zip-stream");
11
- const stream_buf_js_1 = require("../utils/stream-buf");
12
- const utils_js_1 = require("../utils/utils");
13
- const xml_stream_js_1 = require("../utils/xml-stream");
14
- const styles_xform_js_1 = require("./xform/style/styles-xform");
15
- const core_xform_js_1 = require("./xform/core/core-xform");
16
- const shared_strings_xform_js_1 = require("./xform/strings/shared-strings-xform");
17
- const relationships_xform_js_1 = require("./xform/core/relationships-xform");
18
- const content_types_xform_js_1 = require("./xform/core/content-types-xform");
19
- const app_xform_js_1 = require("./xform/core/app-xform");
20
- const workbook_xform_js_1 = require("./xform/book/workbook-xform");
21
- const worksheet_xform_js_1 = require("./xform/sheet/worksheet-xform");
22
- const drawing_xform_js_1 = require("./xform/drawing/drawing-xform");
23
- const table_xform_js_1 = require("./xform/table/table-xform");
24
- const pivot_cache_records_xform_js_1 = require("./xform/pivot-table/pivot-cache-records-xform");
25
- const pivot_cache_definition_xform_js_1 = require("./xform/pivot-table/pivot-cache-definition-xform");
26
- const pivot_table_xform_js_1 = require("./xform/pivot-table/pivot-table-xform");
27
- const comments_xform_js_1 = require("./xform/comment/comments-xform");
28
- const vml_notes_xform_js_1 = require("./xform/comment/vml-notes-xform");
29
- const theme1_js_1 = require("./xml/theme1");
30
- const rel_type_js_1 = require("./rel-type");
20
+ const zip_parser_1 = require("../utils/unzip/zip-parser");
21
+ const zip_stream_1 = require("../utils/zip-stream");
22
+ const stream_buf_1 = require("../utils/stream-buf");
23
+ const utils_1 = require("../utils/utils");
24
+ const xlsx_base_1 = require("./xlsx.base");
31
25
  function fsReadFileAsync(filename, options) {
32
26
  return new Promise((resolve, reject) => {
33
27
  fs_1.default.readFile(filename, options, (error, data) => {
@@ -40,16 +34,34 @@ function fsReadFileAsync(filename, options) {
40
34
  });
41
35
  });
42
36
  }
43
- class XLSX {
44
- constructor(workbook) {
45
- this.workbook = workbook;
46
- }
47
- // ===============================================================================
48
- // Workbook
49
- // =========================================================================
50
- // Read
37
+ class XLSX extends xlsx_base_1.XLSXBase {
38
+ // ===========================================================================
39
+ // Abstract method implementations
40
+ // ===========================================================================
41
+ createStreamBuf() {
42
+ return new stream_buf_1.StreamBuf();
43
+ }
44
+ createBinaryStream(data) {
45
+ const stream = new stream_1.PassThrough();
46
+ stream.end(Buffer.from(data));
47
+ return stream;
48
+ }
49
+ createTextStream(content) {
50
+ const stream = new stream_1.PassThrough({
51
+ readableObjectMode: true,
52
+ writableObjectMode: true
53
+ });
54
+ stream.end(content);
55
+ return stream;
56
+ }
57
+ bufferToString(data) {
58
+ return (0, utils_1.bufferToString)(data);
59
+ }
60
+ // ===========================================================================
61
+ // Node.js specific: File operations
62
+ // ===========================================================================
51
63
  async readFile(filename, options) {
52
- if (!(await (0, utils_js_1.fileExists)(filename))) {
64
+ if (!(await (0, utils_1.fileExists)(filename))) {
53
65
  throw new Error(`File not found: ${filename}`);
54
66
  }
55
67
  const stream = fs_1.default.createReadStream(filename);
@@ -63,425 +75,102 @@ class XLSX {
63
75
  throw error;
64
76
  }
65
77
  }
66
- parseRels(stream) {
67
- const xform = new relationships_xform_js_1.RelationshipsXform();
68
- return xform.parseStream(stream);
69
- }
70
- parseWorkbook(stream) {
71
- const xform = new workbook_xform_js_1.WorkbookXform();
72
- return xform.parseStream(stream);
73
- }
74
- parseSharedStrings(stream) {
75
- const xform = new shared_strings_xform_js_1.SharedStringsXform();
76
- return xform.parseStream(stream);
77
- }
78
- reconcile(model, options) {
79
- const workbookXform = new workbook_xform_js_1.WorkbookXform();
80
- const worksheetXform = new worksheet_xform_js_1.WorkSheetXform(options);
81
- const drawingXform = new drawing_xform_js_1.DrawingXform();
82
- const tableXform = new table_xform_js_1.TableXform();
83
- workbookXform.reconcile(model);
84
- // reconcile drawings with their rels
85
- const drawingOptions = {
86
- media: model.media,
87
- mediaIndex: model.mediaIndex
88
- };
89
- Object.keys(model.drawings).forEach(name => {
90
- const drawing = model.drawings[name];
91
- const drawingRel = model.drawingRels[name];
92
- if (drawingRel) {
93
- drawingOptions.rels = drawingRel.reduce((o, rel) => {
94
- o[rel.Id] = rel;
95
- return o;
96
- }, {});
97
- (drawing.anchors || []).forEach((anchor) => {
98
- const hyperlinks = anchor.picture && anchor.picture.hyperlinks;
99
- if (hyperlinks && drawingOptions.rels[hyperlinks.rId]) {
100
- hyperlinks.hyperlink = drawingOptions.rels[hyperlinks.rId].Target;
101
- delete hyperlinks.rId;
102
- }
103
- });
104
- drawingXform.reconcile(drawing, drawingOptions);
105
- }
106
- });
107
- // reconcile tables with the default styles
108
- const tableOptions = {
109
- styles: model.styles
110
- };
111
- Object.values(model.tables).forEach((table) => {
112
- tableXform.reconcile(table, tableOptions);
113
- });
114
- // Reconcile pivot tables - link pivot tables to worksheets and cache data
115
- this._reconcilePivotTables(model);
116
- const sheetOptions = {
117
- styles: model.styles,
118
- sharedStrings: model.sharedStrings,
119
- media: model.media,
120
- mediaIndex: model.mediaIndex,
121
- date1904: model.properties && model.properties.date1904,
122
- drawings: model.drawings,
123
- comments: model.comments,
124
- tables: model.tables,
125
- vmlDrawings: model.vmlDrawings,
126
- pivotTables: model.pivotTablesIndexed
127
- };
128
- model.worksheets.forEach((worksheet) => {
129
- worksheet.relationships = model.worksheetRels[worksheet.sheetNo];
130
- worksheetXform.reconcile(worksheet, sheetOptions);
131
- });
132
- // delete unnecessary parts
133
- delete model.worksheetHash;
134
- delete model.worksheetRels;
135
- delete model.globalRels;
136
- delete model.sharedStrings;
137
- delete model.workbookRels;
138
- delete model.sheetDefs;
139
- delete model.styles;
140
- delete model.mediaIndex;
141
- delete model.drawings;
142
- delete model.drawingRels;
143
- delete model.vmlDrawings;
144
- // Clean up raw pivot table data after reconciliation
145
- delete model.pivotTableRels;
146
- delete model.pivotCacheDefinitionRels;
147
- }
148
- /**
149
- * Reconcile pivot tables by linking them to worksheets and their cache data.
150
- * This builds a complete pivot table model ready for writing.
151
- */
152
- _reconcilePivotTables(model) {
153
- // Skip if no pivot tables were loaded (object is empty or undefined)
154
- const rawPivotTables = model.pivotTables || {};
155
- if (typeof rawPivotTables !== "object" || Object.keys(rawPivotTables).length === 0) {
156
- // Ensure pivotTables is an empty array (not an object)
157
- model.pivotTables = [];
158
- // Also create an empty indexed object for worksheet reconciliation
159
- model.pivotTablesIndexed = {};
160
- return;
161
- }
162
- // Build mapping from definition name to cacheId
163
- const definitionToCacheId = this._buildDefinitionToCacheIdMap(model);
164
- // Build a map of cache IDs to their definitions and records
165
- const cacheMap = new Map();
166
- // Process cache definitions
167
- Object.entries(model.pivotCacheDefinitions || {}).forEach(([name, definition]) => {
168
- // Get the cacheId from the mapping (derived from workbook.xml pivotCaches)
169
- const cacheId = definitionToCacheId.get(name);
170
- if (cacheId !== undefined) {
171
- const recordsName = name.replace("Definition", "Records");
172
- cacheMap.set(cacheId, {
173
- definition,
174
- records: model.pivotCacheRecords?.[recordsName],
175
- definitionName: name
176
- });
177
- }
178
- });
179
- // Process pivot tables and link to worksheets
180
- const loadedPivotTables = [];
181
- // Create indexed object for worksheet reconciliation (keyed by relative path)
182
- const pivotTablesIndexed = {};
183
- Object.entries(rawPivotTables).forEach(([pivotName, pivotTable]) => {
184
- const pt = pivotTable;
185
- const tableNumber = this._extractTableNumber(pivotName);
186
- // Get cache data for this pivot table
187
- const cacheData = cacheMap.get(pt.cacheId);
188
- // Build complete pivot table model
189
- const completePivotTable = {
190
- // Core model data
191
- ...pt,
192
- tableNumber,
193
- // Link to cache data
194
- cacheDefinition: cacheData?.definition,
195
- cacheRecords: cacheData?.records,
196
- // Reconstruct cacheFields from definition for compatibility
197
- cacheFields: cacheData?.definition?.cacheFields || [],
198
- // Determine rows, columns, values from parsed data
199
- rows: pt.rowFields.filter(f => f >= 0),
200
- columns: pt.colFields.filter(f => f >= 0 && f !== -2),
201
- values: pt.dataFields.map(df => df.fld),
202
- // Determine metric from dataFields
203
- metric: this._determineMetric(pt.dataFields),
204
- // Preserve formatting options
205
- applyWidthHeightFormats: pt.applyWidthHeightFormats || "0"
206
- };
207
- loadedPivotTables.push(completePivotTable);
208
- // Index by relative path for worksheet reconciliation
209
- pivotTablesIndexed[`../pivotTables/${pivotName}.xml`] = completePivotTable;
210
- });
211
- // Sort by table number to maintain order
212
- loadedPivotTables.sort((a, b) => a.tableNumber - b.tableNumber);
213
- // Replace pivotTables object with the processed array
214
- // This is what the Workbook model setter expects
215
- model.pivotTables = loadedPivotTables;
216
- // Also keep indexed version for worksheet reconciliation
217
- model.pivotTablesIndexed = pivotTablesIndexed;
218
- // Also keep as loadedPivotTables for backward compatibility
219
- model.loadedPivotTables = loadedPivotTables;
220
- }
221
- /**
222
- * Extract table number from pivot table name (e.g., "pivotTable1" -> 1)
223
- */
224
- _extractTableNumber(name) {
225
- const match = name.match(/pivotTable(\d+)/);
226
- return match ? parseInt(match[1], 10) : 1;
227
- }
228
- /**
229
- * Build a mapping from rId to cacheId using pivotCaches from workbook.xml
230
- * and workbookRels to determine which definition file corresponds to which cacheId
231
- */
232
- _buildCacheIdMap(model) {
233
- const rIdToCacheId = new Map();
234
- // pivotCaches from workbook.xml contains {cacheId, rId} mappings
235
- const pivotCaches = model.pivotCaches || [];
236
- for (const cache of pivotCaches) {
237
- if (cache.cacheId && cache.rId) {
238
- rIdToCacheId.set(cache.rId, parseInt(cache.cacheId, 10));
239
- }
240
- }
241
- return rIdToCacheId;
242
- }
243
- /**
244
- * Build a mapping from definition name to cacheId
245
- */
246
- _buildDefinitionToCacheIdMap(model) {
247
- const definitionToCacheId = new Map();
248
- const rIdToCacheId = this._buildCacheIdMap(model);
249
- const workbookRels = model.workbookRels || [];
250
- // Map workbook rels to get definitionNumber -> cacheId mapping
251
- for (const rel of workbookRels) {
252
- if (rel.Type === XLSX.RelType.PivotCacheDefinition && rel.Target) {
253
- // Extract definition number from target (e.g., "pivotCache/pivotCacheDefinition1.xml" -> 1)
254
- const match = rel.Target.match(/pivotCacheDefinition(\d+)\.xml/);
255
- if (match) {
256
- const defName = `pivotCacheDefinition${match[1]}`;
257
- const cacheId = rIdToCacheId.get(rel.Id);
258
- if (cacheId !== undefined) {
259
- definitionToCacheId.set(defName, cacheId);
260
- }
261
- }
262
- }
263
- }
264
- return definitionToCacheId;
265
- }
266
- /**
267
- * Determine the aggregation metric from dataFields
268
- */
269
- _determineMetric(dataFields) {
270
- if (dataFields.length > 0 && dataFields[0].subtotal === "count") {
271
- return "count";
272
- }
273
- return "sum";
274
- }
275
- async _processWorksheetEntry(stream, model, sheetNo, options, path) {
276
- const xform = new worksheet_xform_js_1.WorkSheetXform(options);
277
- const worksheet = await xform.parseStream(stream);
278
- if (!worksheet) {
279
- throw new Error(`Failed to parse worksheet ${path}`);
280
- }
281
- worksheet.sheetNo = sheetNo;
282
- model.worksheetHash[path] = worksheet;
283
- model.worksheets.push(worksheet);
284
- }
285
- async _processCommentEntry(stream, model, name) {
286
- const xform = new comments_xform_js_1.CommentsXform();
287
- const comments = await xform.parseStream(stream);
288
- model.comments[`../${name}.xml`] = comments;
289
- }
290
- async _processTableEntry(stream, model, name) {
291
- const xform = new table_xform_js_1.TableXform();
292
- const table = await xform.parseStream(stream);
293
- model.tables[`../tables/${name}.xml`] = table;
294
- }
295
- async _processWorksheetRelsEntry(stream, model, sheetNo) {
296
- const xform = new relationships_xform_js_1.RelationshipsXform();
297
- const relationships = await xform.parseStream(stream);
298
- model.worksheetRels[sheetNo] = relationships;
299
- }
300
- async _processMediaEntry(stream, model, filename) {
301
- const lastDot = filename.lastIndexOf(".");
302
- // if we can't determine extension, ignore it
303
- if (lastDot >= 1) {
304
- const extension = filename.substr(lastDot + 1);
305
- const name = filename.substr(0, lastDot);
306
- await new Promise((resolve, reject) => {
307
- const streamBuf = new stream_buf_js_1.StreamBuf();
308
- const cleanup = () => {
309
- stream.removeListener("error", onError);
310
- streamBuf.removeListener("error", onError);
311
- streamBuf.removeListener("finish", onFinish);
312
- };
313
- const onFinish = () => {
314
- cleanup();
315
- model.mediaIndex[filename] = model.media.length;
316
- model.mediaIndex[name] = model.media.length;
317
- const medium = {
318
- type: "image",
319
- name,
320
- extension,
321
- buffer: streamBuf.toBuffer()
322
- };
323
- model.media.push(medium);
324
- resolve();
325
- };
326
- const onError = (error) => {
327
- cleanup();
328
- reject(error);
329
- };
330
- streamBuf.once("finish", onFinish);
331
- stream.on("error", onError);
332
- streamBuf.on("error", onError);
333
- stream.pipe(streamBuf);
334
- });
335
- }
336
- }
337
- async _processDrawingEntry(entry, model, name) {
338
- const xform = new drawing_xform_js_1.DrawingXform();
339
- const drawing = await xform.parseStream(entry);
340
- model.drawings[name] = drawing;
341
- }
342
- async _processDrawingRelsEntry(entry, model, name) {
343
- const xform = new relationships_xform_js_1.RelationshipsXform();
344
- const relationships = await xform.parseStream(entry);
345
- model.drawingRels[name] = relationships;
346
- }
347
- async _processVmlDrawingEntry(entry, model, name) {
348
- const xform = new vml_notes_xform_js_1.VmlNotesXform();
349
- const vmlDrawing = await xform.parseStream(entry);
350
- model.vmlDrawings[`../drawings/${name}.vml`] = vmlDrawing;
351
- }
352
- async _processThemeEntry(stream, model, name) {
353
- await new Promise((resolve, reject) => {
354
- // TODO: stream entry into buffer and store the xml in the model.themes[]
355
- const streamBuf = new stream_buf_js_1.StreamBuf();
78
+ writeFile(filename, options) {
79
+ const stream = fs_1.default.createWriteStream(filename);
80
+ return new Promise((resolve, reject) => {
356
81
  const cleanup = () => {
82
+ stream.removeListener("finish", onFinish);
357
83
  stream.removeListener("error", onError);
358
- streamBuf.removeListener("error", onError);
359
- streamBuf.removeListener("finish", onFinish);
360
84
  };
361
85
  const onFinish = () => {
362
86
  cleanup();
363
- model.themes[name] = streamBuf.read().toString();
364
87
  resolve();
365
88
  };
366
- const onError = (err) => {
89
+ const onError = (error) => {
367
90
  cleanup();
368
- reject(err);
91
+ reject(error);
369
92
  };
370
- streamBuf.once("finish", onFinish);
93
+ stream.once("finish", onFinish);
371
94
  stream.on("error", onError);
372
- streamBuf.on("error", onError);
373
- stream.pipe(streamBuf);
95
+ this.write(stream, options)
96
+ .then(() => {
97
+ stream.end();
98
+ })
99
+ .catch(err => {
100
+ cleanup();
101
+ reject(err);
102
+ });
374
103
  });
375
104
  }
376
- async _processPivotTableEntry(stream, model, name) {
377
- const xform = new pivot_table_xform_js_1.PivotTableXform();
378
- const pivotTable = await xform.parseStream(stream);
379
- if (pivotTable) {
380
- model.pivotTables[name] = pivotTable;
381
- }
382
- }
383
- async _processPivotTableRelsEntry(stream, model, name) {
384
- const xform = new relationships_xform_js_1.RelationshipsXform();
385
- const relationships = await xform.parseStream(stream);
386
- model.pivotTableRels[name] = relationships;
387
- }
388
- async _processPivotCacheDefinitionEntry(stream, model, name) {
389
- const xform = new pivot_cache_definition_xform_js_1.PivotCacheDefinitionXform();
390
- const cacheDefinition = await xform.parseStream(stream);
391
- if (cacheDefinition) {
392
- model.pivotCacheDefinitions[name] = cacheDefinition;
393
- }
394
- }
395
- async _processPivotCacheDefinitionRelsEntry(stream, model, name) {
396
- const xform = new relationships_xform_js_1.RelationshipsXform();
397
- const relationships = await xform.parseStream(stream);
398
- model.pivotCacheDefinitionRels[name] = relationships;
399
- }
400
- async _processPivotCacheRecordsEntry(stream, model, name) {
401
- const xform = new pivot_cache_records_xform_js_1.PivotCacheRecordsXform();
402
- const cacheRecords = await xform.parseStream(stream);
403
- if (cacheRecords) {
404
- model.pivotCacheRecords[name] = cacheRecords;
405
- }
406
- }
105
+ // ===========================================================================
106
+ // Node.js specific: Stream operations
107
+ // ===========================================================================
407
108
  async read(stream, options) {
408
- // Use streaming unzip with fflate
409
- const allFiles = {};
109
+ // Collect all stream data into a single buffer
110
+ const chunks = [];
410
111
  await new Promise((resolve, reject) => {
411
- let filesProcessed = 0;
412
- let zipEnded = false;
413
- let filesStarted = 0;
414
- const cleanup = () => {
415
- stream.removeListener("data", onData);
416
- stream.removeListener("end", onEnd);
417
- stream.removeListener("error", onError);
418
- };
419
- const checkCompletion = () => {
420
- if (zipEnded && filesProcessed === filesStarted) {
421
- cleanup();
422
- resolve();
423
- }
424
- };
425
- const unzipper = new fflate_1.Unzip((file) => {
426
- filesStarted++;
427
- const fileChunks = [];
428
- let totalLength = 0;
429
- file.ondata = (err, data, final) => {
430
- if (err) {
431
- cleanup();
432
- reject(err);
433
- return;
434
- }
435
- if (data) {
436
- fileChunks.push(data);
437
- totalLength += data.length;
438
- }
439
- if (final) {
440
- // Optimize for single chunk case
441
- if (fileChunks.length === 1) {
442
- allFiles[file.name] = fileChunks[0];
443
- }
444
- else if (fileChunks.length > 1) {
445
- const fullData = new Uint8Array(totalLength);
446
- let offset = 0;
447
- for (const chunk of fileChunks) {
448
- fullData.set(chunk, offset);
449
- offset += chunk.length;
450
- }
451
- allFiles[file.name] = fullData;
452
- }
453
- else {
454
- allFiles[file.name] = new Uint8Array(0);
455
- }
456
- filesProcessed++;
457
- fileChunks.length = 0;
458
- checkCompletion();
459
- }
460
- };
461
- file.start();
462
- });
463
- unzipper.register(fflate_1.UnzipInflate);
464
112
  const onData = (chunk) => {
465
- unzipper.push(chunk);
113
+ chunks.push(chunk);
466
114
  };
467
115
  const onEnd = () => {
468
- unzipper.push(new Uint8Array(0), true);
469
- zipEnded = true;
470
- checkCompletion();
116
+ stream.removeListener("data", onData);
117
+ stream.removeListener("end", onEnd);
118
+ stream.removeListener("error", onError);
119
+ resolve();
471
120
  };
472
121
  const onError = (err) => {
473
- cleanup();
122
+ stream.removeListener("data", onData);
123
+ stream.removeListener("end", onEnd);
124
+ stream.removeListener("error", onError);
474
125
  reject(err);
475
126
  };
476
127
  stream.on("data", onData);
477
128
  stream.on("end", onEnd);
478
129
  stream.on("error", onError);
479
130
  });
131
+ // Combine chunks into a single buffer
132
+ const totalLength = chunks.reduce((sum, chunk) => sum + chunk.length, 0);
133
+ const buffer = new Uint8Array(totalLength);
134
+ let offset = 0;
135
+ for (const chunk of chunks) {
136
+ buffer.set(chunk, offset);
137
+ offset += chunk.length;
138
+ }
139
+ // Use native ZipParser for extraction
140
+ const parser = new zip_parser_1.ZipParser(buffer);
141
+ const filesMap = await parser.extractAll();
142
+ // Convert Map to Record for loadFromFiles
143
+ const allFiles = {};
144
+ for (const [path, content] of filesMap) {
145
+ allFiles[path] = content;
146
+ }
480
147
  return this.loadFromFiles(allFiles, options);
481
148
  }
149
+ async write(stream, options) {
150
+ options = options || {};
151
+ const { model } = this.workbook;
152
+ const zip = new zip_stream_1.ZipWriter(options.zip);
153
+ zip.pipe(stream);
154
+ this.prepareModel(model, options);
155
+ await this.addContentTypes(zip, model);
156
+ await this.addOfficeRels(zip, model);
157
+ await this.addWorkbookRels(zip, model);
158
+ await this.addWorksheets(zip, model);
159
+ await this.addSharedStrings(zip, model);
160
+ this.addDrawings(zip, model);
161
+ this.addTables(zip, model);
162
+ this.addPivotTables(zip, model);
163
+ await Promise.all([this.addThemes(zip, model), this.addStyles(zip, model)]);
164
+ await this.addMedia(zip, model);
165
+ await Promise.all([this.addApp(zip, model), this.addCore(zip, model)]);
166
+ await this.addWorkbook(zip, model);
167
+ return this._finalize(zip);
168
+ }
169
+ // ===========================================================================
170
+ // Node.js specific: Buffer operations
171
+ // ===========================================================================
482
172
  async load(data, options) {
483
173
  let buffer;
484
- // Validate input type
485
174
  if (!data ||
486
175
  (typeof data === "object" &&
487
176
  !Buffer.isBuffer(data) &&
@@ -495,299 +184,18 @@ class XLSX {
495
184
  else {
496
185
  buffer = data;
497
186
  }
498
- // Create a fake stream from buffer for consistency
499
- const PassThroughStream = stream_1.PassThrough;
500
- const stream = new PassThroughStream();
187
+ const stream = new stream_1.PassThrough();
501
188
  stream.end(buffer);
502
189
  return this.read(stream, options);
503
190
  }
504
- async loadFromFiles(zipData, options) {
505
- const model = {
506
- worksheets: [],
507
- worksheetHash: {},
508
- worksheetRels: [],
509
- themes: {},
510
- media: [],
511
- mediaIndex: {},
512
- drawings: {},
513
- drawingRels: {},
514
- comments: {},
515
- tables: {},
516
- vmlDrawings: {},
517
- // Pivot table storage for loaded files
518
- pivotTables: {},
519
- pivotTableRels: {},
520
- pivotCacheDefinitions: {},
521
- pivotCacheDefinitionRels: {},
522
- pivotCacheRecords: {}
523
- };
524
- // Convert fflate format to JSZip-like structure for compatibility
525
- const entries = Object.keys(zipData).map(name => ({
526
- name,
527
- dir: name.endsWith("/"),
528
- data: zipData[name]
529
- }));
530
- for (const entry of entries) {
531
- if (!entry.dir) {
532
- let entryName = entry.name;
533
- if (entryName[0] === "/") {
534
- entryName = entryName.substr(1);
535
- }
536
- let stream;
537
- if (entryName.match(/xl\/media\//) ||
538
- // themes are not parsed as stream
539
- entryName.match(/xl\/theme\/([a-zA-Z0-9]+)[.]xml/)) {
540
- stream = new stream_1.PassThrough();
541
- stream.end(Buffer.from(entry.data));
542
- }
543
- else {
544
- // use object mode to avoid buffer-string convention
545
- stream = new stream_1.PassThrough({
546
- readableObjectMode: true,
547
- writableObjectMode: true
548
- });
549
- const content = (0, utils_js_1.bufferToString)(Buffer.from(entry.data));
550
- stream.end(content);
551
- }
552
- let match;
553
- match = entryName.match(/xl\/worksheets\/sheet(\d+)[.]xml/);
554
- if (match) {
555
- const sheetNo = parseInt(match[1], 10);
556
- await this._processWorksheetEntry(stream, model, sheetNo, options, entryName);
557
- }
558
- else {
559
- switch (entryName) {
560
- case "_rels/.rels":
561
- model.globalRels = await this.parseRels(stream);
562
- break;
563
- case "xl/workbook.xml": {
564
- const workbook = await this.parseWorkbook(stream);
565
- model.sheets = workbook.sheets;
566
- model.definedNames = workbook.definedNames;
567
- model.views = workbook.views;
568
- model.properties = workbook.properties;
569
- model.calcProperties = workbook.calcProperties;
570
- // pivotCaches contains the mapping from rId to cacheId
571
- // needed for linking pivot tables to their cache data
572
- model.pivotCaches = workbook.pivotCaches;
573
- break;
574
- }
575
- case "xl/sharedStrings.xml":
576
- model.sharedStrings = new shared_strings_xform_js_1.SharedStringsXform();
577
- await model.sharedStrings.parseStream(stream);
578
- break;
579
- case "xl/_rels/workbook.xml.rels":
580
- model.workbookRels = await this.parseRels(stream);
581
- break;
582
- case "docProps/app.xml": {
583
- const appXform = new app_xform_js_1.AppXform();
584
- const appProperties = await appXform.parseStream(stream);
585
- model.company = appProperties.company;
586
- model.manager = appProperties.manager;
587
- break;
588
- }
589
- case "docProps/core.xml": {
590
- const coreXform = new core_xform_js_1.CoreXform();
591
- const coreProperties = await coreXform.parseStream(stream);
592
- Object.assign(model, coreProperties);
593
- break;
594
- }
595
- case "xl/styles.xml":
596
- model.styles = new styles_xform_js_1.StylesXform();
597
- await model.styles.parseStream(stream);
598
- break;
599
- default: {
600
- match = entryName.match(/xl\/worksheets\/_rels\/sheet(\d+)[.]xml[.]rels/);
601
- if (match) {
602
- const sheetNo = parseInt(match[1], 10);
603
- await this._processWorksheetRelsEntry(stream, model, sheetNo);
604
- break;
605
- }
606
- match = entryName.match(/xl\/media\/([a-zA-Z0-9]+[.][a-zA-Z0-9]{3,4})$/);
607
- if (match) {
608
- await this._processMediaEntry(stream, model, match[1]);
609
- break;
610
- }
611
- match = entryName.match(/xl\/drawings\/(drawing\d+)[.]xml/);
612
- if (match) {
613
- await this._processDrawingEntry(stream, model, match[1]);
614
- break;
615
- }
616
- match = entryName.match(/xl\/drawings\/_rels\/(drawing\d+)[.]xml[.]rels/);
617
- if (match) {
618
- await this._processDrawingRelsEntry(stream, model, match[1]);
619
- break;
620
- }
621
- match = entryName.match(/xl\/drawings\/(vmlDrawing\d+)[.]vml/);
622
- if (match) {
623
- await this._processVmlDrawingEntry(stream, model, match[1]);
624
- break;
625
- }
626
- match = entryName.match(/xl\/comments(\d+)[.]xml/);
627
- if (match) {
628
- await this._processCommentEntry(stream, model, `comments${match[1]}`);
629
- break;
630
- }
631
- match = entryName.match(/xl\/tables\/(table\d+)[.]xml/);
632
- if (match) {
633
- await this._processTableEntry(stream, model, match[1]);
634
- break;
635
- }
636
- match = entryName.match(/xl\/theme\/([a-zA-Z0-9]+)[.]xml/);
637
- if (match) {
638
- await this._processThemeEntry(stream, model, match[1]);
639
- break;
640
- }
641
- // Pivot table files
642
- match = entryName.match(/xl\/pivotTables\/(pivotTable\d+)[.]xml/);
643
- if (match) {
644
- await this._processPivotTableEntry(stream, model, match[1]);
645
- break;
646
- }
647
- match = entryName.match(/xl\/pivotTables\/_rels\/(pivotTable\d+)[.]xml[.]rels/);
648
- if (match) {
649
- await this._processPivotTableRelsEntry(stream, model, match[1]);
650
- break;
651
- }
652
- // Pivot cache files
653
- match = entryName.match(/xl\/pivotCache\/(pivotCacheDefinition\d+)[.]xml/);
654
- if (match) {
655
- await this._processPivotCacheDefinitionEntry(stream, model, match[1]);
656
- break;
657
- }
658
- match = entryName.match(/xl\/pivotCache\/_rels\/(pivotCacheDefinition\d+)[.]xml[.]rels/);
659
- if (match) {
660
- await this._processPivotCacheDefinitionRelsEntry(stream, model, match[1]);
661
- break;
662
- }
663
- match = entryName.match(/xl\/pivotCache\/(pivotCacheRecords\d+)[.]xml/);
664
- if (match) {
665
- await this._processPivotCacheRecordsEntry(stream, model, match[1]);
666
- break;
667
- }
668
- }
669
- }
670
- }
671
- }
672
- }
673
- this.reconcile(model, options);
674
- // apply model
675
- this.workbook.model = model;
676
- return this.workbook;
677
- }
678
- // =========================================================================
679
- // Write
680
- async addContentTypes(zip, model) {
681
- const xform = new content_types_xform_js_1.ContentTypesXform();
682
- const xml = xform.toXml(model);
683
- zip.append(xml, { name: "[Content_Types].xml" });
684
- }
685
- async addApp(zip, model) {
686
- const xform = new app_xform_js_1.AppXform();
687
- const xml = xform.toXml(model);
688
- zip.append(xml, { name: "docProps/app.xml" });
689
- }
690
- async addCore(zip, model) {
691
- const xform = new core_xform_js_1.CoreXform();
692
- zip.append(xform.toXml(model), { name: "docProps/core.xml" });
693
- }
694
- async addThemes(zip, model) {
695
- const themes = model.themes || { theme1: theme1_js_1.theme1Xml };
696
- Object.keys(themes).forEach(name => {
697
- const xml = themes[name];
698
- const path = `xl/theme/${name}.xml`;
699
- zip.append(xml, { name: path });
700
- });
701
- }
702
- async addOfficeRels(zip, _model) {
703
- const xform = new relationships_xform_js_1.RelationshipsXform();
704
- const xml = xform.toXml([
705
- { Id: "rId1", Type: XLSX.RelType.OfficeDocument, Target: "xl/workbook.xml" },
706
- { Id: "rId2", Type: XLSX.RelType.CoreProperties, Target: "docProps/core.xml" },
707
- { Id: "rId3", Type: XLSX.RelType.ExtenderProperties, Target: "docProps/app.xml" }
708
- ]);
709
- zip.append(xml, { name: "_rels/.rels" });
710
- }
711
- async addWorkbookRels(zip, model) {
712
- let count = 1;
713
- const relationships = [
714
- { Id: `rId${count++}`, Type: XLSX.RelType.Styles, Target: "styles.xml" },
715
- { Id: `rId${count++}`, Type: XLSX.RelType.Theme, Target: "theme/theme1.xml" }
716
- ];
717
- if (model.sharedStrings.count) {
718
- relationships.push({
719
- Id: `rId${count++}`,
720
- Type: XLSX.RelType.SharedStrings,
721
- Target: "sharedStrings.xml"
722
- });
723
- }
724
- // Add relationships for all pivot tables
725
- (model.pivotTables || []).forEach((pivotTable) => {
726
- pivotTable.rId = `rId${count++}`;
727
- relationships.push({
728
- Id: pivotTable.rId,
729
- Type: XLSX.RelType.PivotCacheDefinition,
730
- Target: `pivotCache/pivotCacheDefinition${pivotTable.tableNumber}.xml`
731
- });
732
- });
733
- model.worksheets.forEach((worksheet, index) => {
734
- // Use sequential index (1-based) for file naming, not worksheet.id (sheetId)
735
- // sheetId can be non-sequential (e.g., 1, 3, 5) which would create gaps in filenames
736
- worksheet.rId = `rId${count++}`;
737
- worksheet.fileIndex = index + 1; // Store for use in addWorksheets and content types
738
- relationships.push({
739
- Id: worksheet.rId,
740
- Type: XLSX.RelType.Worksheet,
741
- Target: `worksheets/sheet${worksheet.fileIndex}.xml`
742
- });
743
- });
744
- const xform = new relationships_xform_js_1.RelationshipsXform();
745
- const xml = xform.toXml(relationships);
746
- zip.append(xml, { name: "xl/_rels/workbook.xml.rels" });
747
- }
748
- async addSharedStrings(zip, model) {
749
- if (model.sharedStrings && model.sharedStrings.count) {
750
- zip.append(model.sharedStrings.xml, { name: "xl/sharedStrings.xml" });
751
- }
752
- }
753
- async addStyles(zip, model) {
754
- const { xml } = model.styles;
755
- if (xml) {
756
- zip.append(xml, { name: "xl/styles.xml" });
757
- }
758
- }
759
- async addWorkbook(zip, model) {
760
- const xform = new workbook_xform_js_1.WorkbookXform();
761
- zip.append(xform.toXml(model), { name: "xl/workbook.xml" });
762
- }
763
- async addWorksheets(zip, model) {
764
- // preparation phase
765
- const worksheetXform = new worksheet_xform_js_1.WorkSheetXform();
766
- const relationshipsXform = new relationships_xform_js_1.RelationshipsXform();
767
- const commentsXform = new comments_xform_js_1.CommentsXform();
768
- const vmlNotesXform = new vml_notes_xform_js_1.VmlNotesXform();
769
- // write sheets
770
- model.worksheets.forEach((worksheet, index) => {
771
- // Use fileIndex if set by addWorkbookRels, otherwise use index + 1
772
- const fileIndex = worksheet.fileIndex || index + 1;
773
- let xmlStream = new xml_stream_js_1.XmlStream();
774
- worksheetXform.render(xmlStream, worksheet);
775
- zip.append(xmlStream.xml, { name: `xl/worksheets/sheet${fileIndex}.xml` });
776
- if (worksheet.rels && worksheet.rels.length) {
777
- xmlStream = new xml_stream_js_1.XmlStream();
778
- relationshipsXform.render(xmlStream, worksheet.rels);
779
- zip.append(xmlStream.xml, { name: `xl/worksheets/_rels/sheet${fileIndex}.xml.rels` });
780
- }
781
- if (worksheet.comments.length > 0) {
782
- xmlStream = new xml_stream_js_1.XmlStream();
783
- commentsXform.render(xmlStream, worksheet);
784
- zip.append(xmlStream.xml, { name: `xl/comments${fileIndex}.xml` });
785
- xmlStream = new xml_stream_js_1.XmlStream();
786
- vmlNotesXform.render(xmlStream, worksheet);
787
- zip.append(xmlStream.xml, { name: `xl/drawings/vmlDrawing${fileIndex}.vml` });
788
- }
789
- });
191
+ async writeBuffer(options) {
192
+ const stream = new stream_buf_1.StreamBuf();
193
+ await this.write(stream, options);
194
+ return stream.read();
790
195
  }
196
+ // ===========================================================================
197
+ // Node.js specific: Media handling with file support
198
+ // ===========================================================================
791
199
  async addMedia(zip, model) {
792
200
  await Promise.all(model.media.map(async (medium) => {
793
201
  if (medium.type === "image") {
@@ -808,187 +216,5 @@ class XLSX {
808
216
  throw new Error("Unsupported media");
809
217
  }));
810
218
  }
811
- addDrawings(zip, model) {
812
- const drawingXform = new drawing_xform_js_1.DrawingXform();
813
- const relsXform = new relationships_xform_js_1.RelationshipsXform();
814
- model.worksheets.forEach((worksheet) => {
815
- const { drawing } = worksheet;
816
- if (drawing) {
817
- drawingXform.prepare(drawing);
818
- let xml = drawingXform.toXml(drawing);
819
- zip.append(xml, { name: `xl/drawings/${drawing.name}.xml` });
820
- xml = relsXform.toXml(drawing.rels);
821
- zip.append(xml, { name: `xl/drawings/_rels/${drawing.name}.xml.rels` });
822
- }
823
- });
824
- }
825
- addTables(zip, model) {
826
- const tableXform = new table_xform_js_1.TableXform();
827
- model.worksheets.forEach((worksheet) => {
828
- const { tables } = worksheet;
829
- tables.forEach((table) => {
830
- tableXform.prepare(table, {});
831
- const tableXml = tableXform.toXml(table);
832
- zip.append(tableXml, { name: `xl/tables/${table.target}` });
833
- });
834
- });
835
- }
836
- addPivotTables(zip, model) {
837
- if (!model.pivotTables.length) {
838
- return;
839
- }
840
- const pivotCacheRecordsXform = new pivot_cache_records_xform_js_1.PivotCacheRecordsXform();
841
- const pivotCacheDefinitionXform = new pivot_cache_definition_xform_js_1.PivotCacheDefinitionXform();
842
- const pivotTableXform = new pivot_table_xform_js_1.PivotTableXform();
843
- const relsXform = new relationships_xform_js_1.RelationshipsXform();
844
- // Generate files for each pivot table
845
- model.pivotTables.forEach((pivotTable) => {
846
- const n = pivotTable.tableNumber;
847
- // For loaded pivot tables, use the stored cache data
848
- // For new pivot tables, use the source data
849
- const isLoaded = pivotTable.isLoaded;
850
- if (isLoaded) {
851
- // Loaded pivot table - use stored cache definition and records
852
- if (pivotTable.cacheDefinition) {
853
- const xml = pivotCacheDefinitionXform.toXml(pivotTable.cacheDefinition);
854
- zip.append(xml, { name: `xl/pivotCache/pivotCacheDefinition${n}.xml` });
855
- }
856
- if (pivotTable.cacheRecords) {
857
- const xml = pivotCacheRecordsXform.toXml(pivotTable.cacheRecords);
858
- zip.append(xml, { name: `xl/pivotCache/pivotCacheRecords${n}.xml` });
859
- }
860
- }
861
- else {
862
- // New pivot table - generate from source
863
- let xml = pivotCacheRecordsXform.toXml(pivotTable);
864
- zip.append(xml, { name: `xl/pivotCache/pivotCacheRecords${n}.xml` });
865
- xml = pivotCacheDefinitionXform.toXml(pivotTable);
866
- zip.append(xml, { name: `xl/pivotCache/pivotCacheDefinition${n}.xml` });
867
- }
868
- // pivot cache definition rels (same for both)
869
- let xml = relsXform.toXml([
870
- {
871
- Id: "rId1",
872
- Type: XLSX.RelType.PivotCacheRecords,
873
- Target: `pivotCacheRecords${n}.xml`
874
- }
875
- ]);
876
- zip.append(xml, { name: `xl/pivotCache/_rels/pivotCacheDefinition${n}.xml.rels` });
877
- // pivot table
878
- xml = pivotTableXform.toXml(pivotTable);
879
- zip.append(xml, { name: `xl/pivotTables/pivotTable${n}.xml` });
880
- xml = relsXform.toXml([
881
- {
882
- Id: "rId1",
883
- Type: XLSX.RelType.PivotCacheDefinition,
884
- Target: `../pivotCache/pivotCacheDefinition${n}.xml`
885
- }
886
- ]);
887
- zip.append(xml, { name: `xl/pivotTables/_rels/pivotTable${n}.xml.rels` });
888
- });
889
- }
890
- _finalize(zip) {
891
- return new Promise((resolve, reject) => {
892
- zip.on("finish", () => {
893
- resolve(this);
894
- });
895
- zip.on("error", reject);
896
- zip.finalize();
897
- });
898
- }
899
- prepareModel(model, options) {
900
- // ensure following properties have sane values
901
- model.creator = model.creator || "ExcelTS";
902
- model.lastModifiedBy = model.lastModifiedBy || "ExcelTS";
903
- model.created = model.created || new Date();
904
- model.modified = model.modified || new Date();
905
- model.useSharedStrings =
906
- options.useSharedStrings !== undefined ? options.useSharedStrings : true;
907
- model.useStyles = options.useStyles !== undefined ? options.useStyles : true;
908
- // Manage the shared strings
909
- model.sharedStrings = new shared_strings_xform_js_1.SharedStringsXform();
910
- // add a style manager to handle cell formats, fonts, etc.
911
- model.styles = model.useStyles ? new styles_xform_js_1.StylesXform(true) : new styles_xform_js_1.StylesXform.Mock();
912
- // prepare all of the things before the render
913
- const workbookXform = new workbook_xform_js_1.WorkbookXform();
914
- const worksheetXform = new worksheet_xform_js_1.WorkSheetXform();
915
- workbookXform.prepare(model);
916
- const worksheetOptions = {
917
- sharedStrings: model.sharedStrings,
918
- styles: model.styles,
919
- date1904: model.properties.date1904,
920
- drawingsCount: 0,
921
- media: model.media
922
- };
923
- worksheetOptions.drawings = model.drawings = [];
924
- worksheetOptions.commentRefs = model.commentRefs = [];
925
- let tableCount = 0;
926
- model.tables = [];
927
- model.worksheets.forEach((worksheet) => {
928
- // assign unique filenames to tables
929
- worksheet.tables.forEach((table) => {
930
- tableCount++;
931
- table.target = `table${tableCount}.xml`;
932
- table.id = tableCount;
933
- model.tables.push(table);
934
- });
935
- worksheetXform.prepare(worksheet, worksheetOptions);
936
- });
937
- // TODO: workbook drawing list
938
- }
939
- async write(stream, options) {
940
- options = options || {};
941
- const { model } = this.workbook;
942
- const zip = new zip_stream_js_1.ZipWriter(options.zip);
943
- zip.pipe(stream);
944
- this.prepareModel(model, options);
945
- // render
946
- await this.addContentTypes(zip, model);
947
- await this.addOfficeRels(zip, model);
948
- await this.addWorkbookRels(zip, model);
949
- await this.addWorksheets(zip, model);
950
- await this.addSharedStrings(zip, model); // always after worksheets
951
- this.addDrawings(zip, model);
952
- this.addTables(zip, model);
953
- this.addPivotTables(zip, model);
954
- await Promise.all([this.addThemes(zip, model), this.addStyles(zip, model)]);
955
- await this.addMedia(zip, model);
956
- await Promise.all([this.addApp(zip, model), this.addCore(zip, model)]);
957
- await this.addWorkbook(zip, model);
958
- return this._finalize(zip);
959
- }
960
- writeFile(filename, options) {
961
- const stream = fs_1.default.createWriteStream(filename);
962
- return new Promise((resolve, reject) => {
963
- const cleanup = () => {
964
- stream.removeListener("finish", onFinish);
965
- stream.removeListener("error", onError);
966
- };
967
- const onFinish = () => {
968
- cleanup();
969
- resolve();
970
- };
971
- const onError = (error) => {
972
- cleanup();
973
- reject(error);
974
- };
975
- stream.once("finish", onFinish);
976
- stream.on("error", onError);
977
- this.write(stream, options)
978
- .then(() => {
979
- stream.end();
980
- })
981
- .catch(err => {
982
- cleanup();
983
- reject(err);
984
- });
985
- });
986
- }
987
- async writeBuffer(options) {
988
- const stream = new stream_buf_js_1.StreamBuf();
989
- await this.write(stream, options);
990
- return stream.read();
991
- }
992
219
  }
993
220
  exports.XLSX = XLSX;
994
- XLSX.RelType = rel_type_js_1.RelType;