@cj-tech-master/excelts 5.0.6 → 5.1.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 (273) hide show
  1. package/dist/browser/index.browser.d.ts +1 -1
  2. package/dist/browser/index.d.ts +1 -1
  3. package/dist/browser/modules/archive/unzip/stream.base.js +19 -19
  4. package/dist/browser/modules/archive/unzip/stream.browser.js +3 -3
  5. package/dist/browser/modules/csv/csv-core.js +6 -3
  6. package/dist/browser/modules/csv/csv.browser.js +2 -2
  7. package/dist/browser/modules/csv/csv.js +1 -1
  8. package/dist/browser/modules/excel/anchor.js +4 -4
  9. package/dist/browser/modules/excel/cell.js +5 -5
  10. package/dist/browser/modules/excel/column.js +4 -4
  11. package/dist/browser/modules/excel/defined-names.js +1 -1
  12. package/dist/browser/modules/excel/form-control.js +1 -1
  13. package/dist/browser/modules/excel/pivot-table.d.ts +168 -17
  14. package/dist/browser/modules/excel/pivot-table.js +278 -70
  15. package/dist/browser/modules/excel/row.js +4 -4
  16. package/dist/browser/modules/excel/stream/workbook-reader.browser.js +4 -4
  17. package/dist/browser/modules/excel/stream/workbook-writer.browser.js +4 -4
  18. package/dist/browser/modules/excel/stream/worksheet-reader.js +1 -1
  19. package/dist/browser/modules/excel/stream/worksheet-writer.js +4 -4
  20. package/dist/browser/modules/excel/table.js +2 -2
  21. package/dist/browser/modules/excel/types.d.ts +0 -4
  22. package/dist/browser/modules/excel/utils/cell-format.js +3 -3
  23. package/dist/browser/modules/excel/utils/shared-formula.js +1 -1
  24. package/dist/browser/modules/excel/utils/stream-buf.js +2 -2
  25. package/dist/browser/modules/excel/utils/string-buf.js +1 -1
  26. package/dist/browser/modules/excel/workbook.d.ts +0 -2
  27. package/dist/browser/modules/excel/workbook.js +4 -5
  28. package/dist/browser/modules/excel/worksheet.js +9 -9
  29. package/dist/browser/modules/excel/xlsx/xform/base-xform.d.ts +5 -5
  30. package/dist/browser/modules/excel/xlsx/xform/base-xform.js +1 -1
  31. package/dist/browser/modules/excel/xlsx/xform/book/defined-name-xform.js +2 -2
  32. package/dist/browser/modules/excel/xlsx/xform/book/workbook-view-xform.js +4 -4
  33. package/dist/browser/modules/excel/xlsx/xform/book/workbook-xform.js +16 -4
  34. package/dist/browser/modules/excel/xlsx/xform/comment/comment-xform.d.ts +1 -2
  35. package/dist/browser/modules/excel/xlsx/xform/comment/comments-xform.d.ts +1 -2
  36. package/dist/browser/modules/excel/xlsx/xform/comment/style/vml-position-xform.d.ts +3 -4
  37. package/dist/browser/modules/excel/xlsx/xform/comment/style/vml-position-xform.js +1 -1
  38. package/dist/browser/modules/excel/xlsx/xform/comment/style/vml-protection-xform.js +1 -1
  39. package/dist/browser/modules/excel/xlsx/xform/comment/vml-client-data-xform.d.ts +1 -2
  40. package/dist/browser/modules/excel/xlsx/xform/comment/vml-notes-xform.d.ts +1 -2
  41. package/dist/browser/modules/excel/xlsx/xform/comment/vml-shape-xform.js +1 -1
  42. package/dist/browser/modules/excel/xlsx/xform/comment/vml-textbox-xform.d.ts +1 -2
  43. package/dist/browser/modules/excel/xlsx/xform/comment/vml-textbox-xform.js +1 -1
  44. package/dist/browser/modules/excel/xlsx/xform/composite-xform.d.ts +1 -1
  45. package/dist/browser/modules/excel/xlsx/xform/core/app-xform.js +1 -1
  46. package/dist/browser/modules/excel/xlsx/xform/core/content-types-xform.js +24 -11
  47. package/dist/browser/modules/excel/xlsx/xform/drawing/base-cell-anchor-xform.js +1 -1
  48. package/dist/browser/modules/excel/xlsx/xform/drawing/blip-xform.d.ts +1 -2
  49. package/dist/browser/modules/excel/xlsx/xform/drawing/cell-position-xform.d.ts +1 -2
  50. package/dist/browser/modules/excel/xlsx/xform/drawing/ctrl-prop-xform.d.ts +1 -2
  51. package/dist/browser/modules/excel/xlsx/xform/drawing/drawing-xform.d.ts +1 -2
  52. package/dist/browser/modules/excel/xlsx/xform/drawing/ext-xform.d.ts +1 -2
  53. package/dist/browser/modules/excel/xlsx/xform/drawing/ext-xform.js +2 -2
  54. package/dist/browser/modules/excel/xlsx/xform/drawing/one-cell-anchor-xform.js +1 -1
  55. package/dist/browser/modules/excel/xlsx/xform/drawing/two-cell-anchor-xform.js +1 -1
  56. package/dist/browser/modules/excel/xlsx/xform/drawing/vml-drawing-xform.d.ts +1 -2
  57. package/dist/browser/modules/excel/xlsx/xform/list-xform.d.ts +1 -2
  58. package/dist/browser/modules/excel/xlsx/xform/list-xform.js +3 -3
  59. package/dist/browser/modules/excel/xlsx/xform/pivot-table/cache-field-xform.d.ts +5 -15
  60. package/dist/browser/modules/excel/xlsx/xform/pivot-table/cache-field-xform.js +134 -52
  61. package/dist/browser/modules/excel/xlsx/xform/pivot-table/cache-field.d.ts +14 -15
  62. package/dist/browser/modules/excel/xlsx/xform/pivot-table/cache-field.js +244 -70
  63. package/dist/browser/modules/excel/xlsx/xform/pivot-table/pivot-cache-definition-xform.d.ts +13 -29
  64. package/dist/browser/modules/excel/xlsx/xform/pivot-table/pivot-cache-definition-xform.js +213 -37
  65. package/dist/browser/modules/excel/xlsx/xform/pivot-table/pivot-cache-records-xform.d.ts +7 -34
  66. package/dist/browser/modules/excel/xlsx/xform/pivot-table/pivot-cache-records-xform.js +143 -41
  67. package/dist/browser/modules/excel/xlsx/xform/pivot-table/pivot-table-xform.d.ts +101 -27
  68. package/dist/browser/modules/excel/xlsx/xform/pivot-table/pivot-table-xform.js +793 -408
  69. package/dist/browser/modules/excel/xlsx/xform/pivot-table/raw-xml-collector.d.ts +78 -0
  70. package/dist/browser/modules/excel/xlsx/xform/pivot-table/raw-xml-collector.js +149 -0
  71. package/dist/browser/modules/excel/xlsx/xform/sheet/cell-xform.js +1 -1
  72. package/dist/browser/modules/excel/xlsx/xform/sheet/cf/cf-rule-xform.js +1 -1
  73. package/dist/browser/modules/excel/xlsx/xform/sheet/cf/conditional-formattings-xform.js +1 -1
  74. package/dist/browser/modules/excel/xlsx/xform/sheet/cf-ext/cf-rule-ext-xform.js +1 -1
  75. package/dist/browser/modules/excel/xlsx/xform/sheet/col-xform.js +3 -3
  76. package/dist/browser/modules/excel/xlsx/xform/sheet/data-validations-xform.js +3 -3
  77. package/dist/browser/modules/excel/xlsx/xform/sheet/header-footer-xform.js +6 -6
  78. package/dist/browser/modules/excel/xlsx/xform/sheet/page-setup-xform.js +11 -11
  79. package/dist/browser/modules/excel/xlsx/xform/sheet/row-xform.d.ts +1 -2
  80. package/dist/browser/modules/excel/xlsx/xform/sheet/sheet-format-properties-xform.js +3 -3
  81. package/dist/browser/modules/excel/xlsx/xform/sheet/sheet-view-xform.d.ts +1 -2
  82. package/dist/browser/modules/excel/xlsx/xform/sheet/sheet-view-xform.js +10 -10
  83. package/dist/browser/modules/excel/xlsx/xform/sheet/worksheet-xform.js +12 -12
  84. package/dist/browser/modules/excel/xlsx/xform/strings/phonetic-text-xform.js +2 -2
  85. package/dist/browser/modules/excel/xlsx/xform/style/color-xform.js +1 -1
  86. package/dist/browser/modules/excel/xlsx/xform/style/style-xform.js +5 -5
  87. package/dist/browser/modules/excel/xlsx/xform/table/auto-filter-xform.d.ts +1 -2
  88. package/dist/browser/modules/excel/xlsx/xform/table/custom-filter-xform.d.ts +1 -2
  89. package/dist/browser/modules/excel/xlsx/xform/table/filter-column-xform.d.ts +1 -2
  90. package/dist/browser/modules/excel/xlsx/xform/table/filter-xform.d.ts +1 -2
  91. package/dist/browser/modules/excel/xlsx/xform/table/table-column-xform.d.ts +1 -2
  92. package/dist/browser/modules/excel/xlsx/xform/table/table-style-info-xform.d.ts +1 -2
  93. package/dist/browser/modules/excel/xlsx/xform/table/table-xform.d.ts +1 -2
  94. package/dist/browser/modules/excel/xlsx/xlsx.browser.d.ts +5 -2
  95. package/dist/browser/modules/excel/xlsx/xlsx.browser.js +88 -54
  96. package/dist/browser/utils/env.d.ts +0 -5
  97. package/dist/browser/utils/env.js +0 -7
  98. package/dist/browser/utils/utils.base.d.ts +8 -13
  99. package/dist/browser/utils/utils.base.js +40 -47
  100. package/dist/browser/utils/utils.browser.d.ts +1 -1
  101. package/dist/browser/utils/utils.browser.js +1 -1
  102. package/dist/browser/utils/utils.d.ts +1 -1
  103. package/dist/browser/utils/utils.js +1 -1
  104. package/dist/cjs/modules/archive/unzip/stream.base.js +19 -19
  105. package/dist/cjs/modules/archive/unzip/stream.browser.js +3 -3
  106. package/dist/cjs/modules/csv/csv-core.js +6 -3
  107. package/dist/cjs/modules/csv/csv.browser.js +2 -2
  108. package/dist/cjs/modules/csv/csv.js +1 -1
  109. package/dist/cjs/modules/excel/anchor.js +4 -4
  110. package/dist/cjs/modules/excel/cell.js +5 -5
  111. package/dist/cjs/modules/excel/column.js +4 -4
  112. package/dist/cjs/modules/excel/defined-names.js +1 -1
  113. package/dist/cjs/modules/excel/form-control.js +1 -1
  114. package/dist/cjs/modules/excel/pivot-table.js +280 -70
  115. package/dist/cjs/modules/excel/row.js +4 -4
  116. package/dist/cjs/modules/excel/stream/workbook-reader.browser.js +4 -4
  117. package/dist/cjs/modules/excel/stream/workbook-writer.browser.js +4 -4
  118. package/dist/cjs/modules/excel/stream/worksheet-reader.js +1 -1
  119. package/dist/cjs/modules/excel/stream/worksheet-writer.js +4 -4
  120. package/dist/cjs/modules/excel/table.js +2 -2
  121. package/dist/cjs/modules/excel/utils/cell-format.js +3 -3
  122. package/dist/cjs/modules/excel/utils/shared-formula.js +1 -1
  123. package/dist/cjs/modules/excel/utils/stream-buf.js +2 -2
  124. package/dist/cjs/modules/excel/utils/string-buf.js +1 -1
  125. package/dist/cjs/modules/excel/workbook.js +4 -5
  126. package/dist/cjs/modules/excel/worksheet.js +9 -9
  127. package/dist/cjs/modules/excel/xlsx/xform/base-xform.js +1 -1
  128. package/dist/cjs/modules/excel/xlsx/xform/book/defined-name-xform.js +2 -2
  129. package/dist/cjs/modules/excel/xlsx/xform/book/workbook-view-xform.js +4 -4
  130. package/dist/cjs/modules/excel/xlsx/xform/book/workbook-xform.js +16 -4
  131. package/dist/cjs/modules/excel/xlsx/xform/comment/style/vml-position-xform.js +1 -1
  132. package/dist/cjs/modules/excel/xlsx/xform/comment/style/vml-protection-xform.js +1 -1
  133. package/dist/cjs/modules/excel/xlsx/xform/comment/vml-shape-xform.js +1 -1
  134. package/dist/cjs/modules/excel/xlsx/xform/comment/vml-textbox-xform.js +1 -1
  135. package/dist/cjs/modules/excel/xlsx/xform/core/app-xform.js +1 -1
  136. package/dist/cjs/modules/excel/xlsx/xform/core/content-types-xform.js +24 -11
  137. package/dist/cjs/modules/excel/xlsx/xform/drawing/base-cell-anchor-xform.js +1 -1
  138. package/dist/cjs/modules/excel/xlsx/xform/drawing/ext-xform.js +2 -2
  139. package/dist/cjs/modules/excel/xlsx/xform/drawing/one-cell-anchor-xform.js +1 -1
  140. package/dist/cjs/modules/excel/xlsx/xform/drawing/two-cell-anchor-xform.js +1 -1
  141. package/dist/cjs/modules/excel/xlsx/xform/list-xform.js +3 -3
  142. package/dist/cjs/modules/excel/xlsx/xform/pivot-table/cache-field-xform.js +133 -51
  143. package/dist/cjs/modules/excel/xlsx/xform/pivot-table/cache-field.js +245 -71
  144. package/dist/cjs/modules/excel/xlsx/xform/pivot-table/pivot-cache-definition-xform.js +212 -36
  145. package/dist/cjs/modules/excel/xlsx/xform/pivot-table/pivot-cache-records-xform.js +142 -40
  146. package/dist/cjs/modules/excel/xlsx/xform/pivot-table/pivot-table-xform.js +793 -408
  147. package/dist/cjs/modules/excel/xlsx/xform/pivot-table/raw-xml-collector.js +153 -0
  148. package/dist/cjs/modules/excel/xlsx/xform/sheet/cell-xform.js +1 -1
  149. package/dist/cjs/modules/excel/xlsx/xform/sheet/cf/cf-rule-xform.js +1 -1
  150. package/dist/cjs/modules/excel/xlsx/xform/sheet/cf/conditional-formattings-xform.js +1 -1
  151. package/dist/cjs/modules/excel/xlsx/xform/sheet/cf-ext/cf-rule-ext-xform.js +1 -1
  152. package/dist/cjs/modules/excel/xlsx/xform/sheet/col-xform.js +3 -3
  153. package/dist/cjs/modules/excel/xlsx/xform/sheet/data-validations-xform.js +3 -3
  154. package/dist/cjs/modules/excel/xlsx/xform/sheet/header-footer-xform.js +6 -6
  155. package/dist/cjs/modules/excel/xlsx/xform/sheet/page-setup-xform.js +11 -11
  156. package/dist/cjs/modules/excel/xlsx/xform/sheet/sheet-format-properties-xform.js +3 -3
  157. package/dist/cjs/modules/excel/xlsx/xform/sheet/sheet-view-xform.js +10 -10
  158. package/dist/cjs/modules/excel/xlsx/xform/sheet/worksheet-xform.js +12 -12
  159. package/dist/cjs/modules/excel/xlsx/xform/strings/phonetic-text-xform.js +2 -2
  160. package/dist/cjs/modules/excel/xlsx/xform/style/color-xform.js +1 -1
  161. package/dist/cjs/modules/excel/xlsx/xform/style/style-xform.js +5 -5
  162. package/dist/cjs/modules/excel/xlsx/xlsx.browser.js +88 -54
  163. package/dist/cjs/utils/env.js +0 -8
  164. package/dist/cjs/utils/utils.base.js +41 -54
  165. package/dist/cjs/utils/utils.browser.js +2 -7
  166. package/dist/cjs/utils/utils.js +2 -7
  167. package/dist/esm/modules/archive/unzip/stream.base.js +19 -19
  168. package/dist/esm/modules/archive/unzip/stream.browser.js +3 -3
  169. package/dist/esm/modules/csv/csv-core.js +6 -3
  170. package/dist/esm/modules/csv/csv.browser.js +2 -2
  171. package/dist/esm/modules/csv/csv.js +1 -1
  172. package/dist/esm/modules/excel/anchor.js +4 -4
  173. package/dist/esm/modules/excel/cell.js +5 -5
  174. package/dist/esm/modules/excel/column.js +4 -4
  175. package/dist/esm/modules/excel/defined-names.js +1 -1
  176. package/dist/esm/modules/excel/form-control.js +1 -1
  177. package/dist/esm/modules/excel/pivot-table.js +278 -70
  178. package/dist/esm/modules/excel/row.js +4 -4
  179. package/dist/esm/modules/excel/stream/workbook-reader.browser.js +4 -4
  180. package/dist/esm/modules/excel/stream/workbook-writer.browser.js +4 -4
  181. package/dist/esm/modules/excel/stream/worksheet-reader.js +1 -1
  182. package/dist/esm/modules/excel/stream/worksheet-writer.js +4 -4
  183. package/dist/esm/modules/excel/table.js +2 -2
  184. package/dist/esm/modules/excel/utils/cell-format.js +3 -3
  185. package/dist/esm/modules/excel/utils/shared-formula.js +1 -1
  186. package/dist/esm/modules/excel/utils/stream-buf.js +2 -2
  187. package/dist/esm/modules/excel/utils/string-buf.js +1 -1
  188. package/dist/esm/modules/excel/workbook.js +4 -5
  189. package/dist/esm/modules/excel/worksheet.js +9 -9
  190. package/dist/esm/modules/excel/xlsx/xform/base-xform.js +1 -1
  191. package/dist/esm/modules/excel/xlsx/xform/book/defined-name-xform.js +2 -2
  192. package/dist/esm/modules/excel/xlsx/xform/book/workbook-view-xform.js +4 -4
  193. package/dist/esm/modules/excel/xlsx/xform/book/workbook-xform.js +16 -4
  194. package/dist/esm/modules/excel/xlsx/xform/comment/style/vml-position-xform.js +1 -1
  195. package/dist/esm/modules/excel/xlsx/xform/comment/style/vml-protection-xform.js +1 -1
  196. package/dist/esm/modules/excel/xlsx/xform/comment/vml-shape-xform.js +1 -1
  197. package/dist/esm/modules/excel/xlsx/xform/comment/vml-textbox-xform.js +1 -1
  198. package/dist/esm/modules/excel/xlsx/xform/core/app-xform.js +1 -1
  199. package/dist/esm/modules/excel/xlsx/xform/core/content-types-xform.js +24 -11
  200. package/dist/esm/modules/excel/xlsx/xform/drawing/base-cell-anchor-xform.js +1 -1
  201. package/dist/esm/modules/excel/xlsx/xform/drawing/ext-xform.js +2 -2
  202. package/dist/esm/modules/excel/xlsx/xform/drawing/one-cell-anchor-xform.js +1 -1
  203. package/dist/esm/modules/excel/xlsx/xform/drawing/two-cell-anchor-xform.js +1 -1
  204. package/dist/esm/modules/excel/xlsx/xform/list-xform.js +3 -3
  205. package/dist/esm/modules/excel/xlsx/xform/pivot-table/cache-field-xform.js +134 -52
  206. package/dist/esm/modules/excel/xlsx/xform/pivot-table/cache-field.js +244 -70
  207. package/dist/esm/modules/excel/xlsx/xform/pivot-table/pivot-cache-definition-xform.js +213 -37
  208. package/dist/esm/modules/excel/xlsx/xform/pivot-table/pivot-cache-records-xform.js +143 -41
  209. package/dist/esm/modules/excel/xlsx/xform/pivot-table/pivot-table-xform.js +793 -408
  210. package/dist/esm/modules/excel/xlsx/xform/pivot-table/raw-xml-collector.js +149 -0
  211. package/dist/esm/modules/excel/xlsx/xform/sheet/cell-xform.js +1 -1
  212. package/dist/esm/modules/excel/xlsx/xform/sheet/cf/cf-rule-xform.js +1 -1
  213. package/dist/esm/modules/excel/xlsx/xform/sheet/cf/conditional-formattings-xform.js +1 -1
  214. package/dist/esm/modules/excel/xlsx/xform/sheet/cf-ext/cf-rule-ext-xform.js +1 -1
  215. package/dist/esm/modules/excel/xlsx/xform/sheet/col-xform.js +3 -3
  216. package/dist/esm/modules/excel/xlsx/xform/sheet/data-validations-xform.js +3 -3
  217. package/dist/esm/modules/excel/xlsx/xform/sheet/header-footer-xform.js +6 -6
  218. package/dist/esm/modules/excel/xlsx/xform/sheet/page-setup-xform.js +11 -11
  219. package/dist/esm/modules/excel/xlsx/xform/sheet/sheet-format-properties-xform.js +3 -3
  220. package/dist/esm/modules/excel/xlsx/xform/sheet/sheet-view-xform.js +10 -10
  221. package/dist/esm/modules/excel/xlsx/xform/sheet/worksheet-xform.js +12 -12
  222. package/dist/esm/modules/excel/xlsx/xform/strings/phonetic-text-xform.js +2 -2
  223. package/dist/esm/modules/excel/xlsx/xform/style/color-xform.js +1 -1
  224. package/dist/esm/modules/excel/xlsx/xform/style/style-xform.js +5 -5
  225. package/dist/esm/modules/excel/xlsx/xlsx.browser.js +88 -54
  226. package/dist/esm/utils/env.js +0 -7
  227. package/dist/esm/utils/utils.base.js +40 -47
  228. package/dist/esm/utils/utils.browser.js +1 -1
  229. package/dist/esm/utils/utils.js +1 -1
  230. package/dist/iife/excelts.iife.js +1553 -718
  231. package/dist/iife/excelts.iife.js.map +1 -1
  232. package/dist/iife/excelts.iife.min.js +36 -105
  233. package/dist/types/index.browser.d.ts +1 -1
  234. package/dist/types/index.d.ts +1 -1
  235. package/dist/types/modules/excel/pivot-table.d.ts +168 -17
  236. package/dist/types/modules/excel/types.d.ts +0 -4
  237. package/dist/types/modules/excel/workbook.d.ts +0 -2
  238. package/dist/types/modules/excel/xlsx/xform/base-xform.d.ts +5 -5
  239. package/dist/types/modules/excel/xlsx/xform/comment/comment-xform.d.ts +1 -2
  240. package/dist/types/modules/excel/xlsx/xform/comment/comments-xform.d.ts +1 -2
  241. package/dist/types/modules/excel/xlsx/xform/comment/style/vml-position-xform.d.ts +3 -4
  242. package/dist/types/modules/excel/xlsx/xform/comment/vml-client-data-xform.d.ts +1 -2
  243. package/dist/types/modules/excel/xlsx/xform/comment/vml-notes-xform.d.ts +1 -2
  244. package/dist/types/modules/excel/xlsx/xform/comment/vml-textbox-xform.d.ts +1 -2
  245. package/dist/types/modules/excel/xlsx/xform/composite-xform.d.ts +1 -1
  246. package/dist/types/modules/excel/xlsx/xform/drawing/blip-xform.d.ts +1 -2
  247. package/dist/types/modules/excel/xlsx/xform/drawing/cell-position-xform.d.ts +1 -2
  248. package/dist/types/modules/excel/xlsx/xform/drawing/ctrl-prop-xform.d.ts +1 -2
  249. package/dist/types/modules/excel/xlsx/xform/drawing/drawing-xform.d.ts +1 -2
  250. package/dist/types/modules/excel/xlsx/xform/drawing/ext-xform.d.ts +1 -2
  251. package/dist/types/modules/excel/xlsx/xform/drawing/vml-drawing-xform.d.ts +1 -2
  252. package/dist/types/modules/excel/xlsx/xform/list-xform.d.ts +1 -2
  253. package/dist/types/modules/excel/xlsx/xform/pivot-table/cache-field-xform.d.ts +5 -15
  254. package/dist/types/modules/excel/xlsx/xform/pivot-table/cache-field.d.ts +14 -15
  255. package/dist/types/modules/excel/xlsx/xform/pivot-table/pivot-cache-definition-xform.d.ts +13 -29
  256. package/dist/types/modules/excel/xlsx/xform/pivot-table/pivot-cache-records-xform.d.ts +7 -34
  257. package/dist/types/modules/excel/xlsx/xform/pivot-table/pivot-table-xform.d.ts +101 -27
  258. package/dist/types/modules/excel/xlsx/xform/pivot-table/raw-xml-collector.d.ts +78 -0
  259. package/dist/types/modules/excel/xlsx/xform/sheet/row-xform.d.ts +1 -2
  260. package/dist/types/modules/excel/xlsx/xform/sheet/sheet-view-xform.d.ts +1 -2
  261. package/dist/types/modules/excel/xlsx/xform/table/auto-filter-xform.d.ts +1 -2
  262. package/dist/types/modules/excel/xlsx/xform/table/custom-filter-xform.d.ts +1 -2
  263. package/dist/types/modules/excel/xlsx/xform/table/filter-column-xform.d.ts +1 -2
  264. package/dist/types/modules/excel/xlsx/xform/table/filter-xform.d.ts +1 -2
  265. package/dist/types/modules/excel/xlsx/xform/table/table-column-xform.d.ts +1 -2
  266. package/dist/types/modules/excel/xlsx/xform/table/table-style-info-xform.d.ts +1 -2
  267. package/dist/types/modules/excel/xlsx/xform/table/table-xform.d.ts +1 -2
  268. package/dist/types/modules/excel/xlsx/xlsx.browser.d.ts +5 -2
  269. package/dist/types/utils/env.d.ts +0 -5
  270. package/dist/types/utils/utils.base.d.ts +8 -13
  271. package/dist/types/utils/utils.browser.d.ts +1 -1
  272. package/dist/types/utils/utils.d.ts +1 -1
  273. package/package.json +1 -1
@@ -69,10 +69,10 @@ export function createDefaultWriteMapper(dateFormat, dateUTC) {
69
69
  return function mapValue(value) {
70
70
  if (value) {
71
71
  if (value.text || value.hyperlink) {
72
- return value.hyperlink || value.text || "";
72
+ return value.hyperlink ?? value.text ?? "";
73
73
  }
74
74
  if (value.formula || value.result) {
75
- return value.result || "";
75
+ return value.result ?? "";
76
76
  }
77
77
  if (value instanceof Date) {
78
78
  return formatter.format(value);
@@ -19,7 +19,7 @@ class CSV extends CSVBrowser {
19
19
  }
20
20
  async writeFile(filename, options) {
21
21
  const writeStream = fs.createWriteStream(filename, {
22
- encoding: (options?.encoding || "utf8"),
22
+ encoding: (options?.encoding ?? "utf8"),
23
23
  highWaterMark: options?.highWaterMark ?? 64 * 1024
24
24
  });
25
25
  return this.write(writeStream, options);
@@ -26,10 +26,10 @@ class Anchor {
26
26
  this.nativeRowOff = 0;
27
27
  }
28
28
  else if (isAnchorModel(address)) {
29
- this.nativeCol = address.nativeCol || 0;
30
- this.nativeColOff = address.nativeColOff || 0;
31
- this.nativeRow = address.nativeRow || 0;
32
- this.nativeRowOff = address.nativeRowOff || 0;
29
+ this.nativeCol = address.nativeCol ?? 0;
30
+ this.nativeColOff = address.nativeColOff ?? 0;
31
+ this.nativeRow = address.nativeRow ?? 0;
32
+ this.nativeRowOff = address.nativeRowOff ?? 0;
33
33
  }
34
34
  else if (isSimpleAddress(address)) {
35
35
  this.col = address.col + offset;
@@ -500,8 +500,8 @@ class HyperlinkValue {
500
500
  }
501
501
  get value() {
502
502
  return {
503
- text: this.model.text || "",
504
- hyperlink: this.model.hyperlink || "",
503
+ text: this.model.text ?? "",
504
+ hyperlink: this.model.hyperlink ?? "",
505
505
  tooltip: this.model.tooltip
506
506
  };
507
507
  }
@@ -537,11 +537,11 @@ class HyperlinkValue {
537
537
  this.model.address = value;
538
538
  }
539
539
  toCsvString() {
540
- return this.model.hyperlink || "";
540
+ return this.model.hyperlink ?? "";
541
541
  }
542
542
  release() { }
543
543
  toString() {
544
- return this.model.text || "";
544
+ return this.model.text ?? "";
545
545
  }
546
546
  }
547
547
  class MergeValue {
@@ -734,7 +734,7 @@ class FormulaValue {
734
734
  return this._translatedFormula;
735
735
  }
736
736
  toCsvString() {
737
- return `${this.model.result || ""}`;
737
+ return `${this.model.result ?? ""}`;
738
738
  }
739
739
  release() { }
740
740
  toString() {
@@ -126,7 +126,7 @@ class Column {
126
126
  * Set an outline level for columns
127
127
  */
128
128
  get outlineLevel() {
129
- return this._outlineLevel || 0;
129
+ return this._outlineLevel ?? 0;
130
130
  }
131
131
  set outlineLevel(value) {
132
132
  this._outlineLevel = value;
@@ -230,8 +230,8 @@ class Column {
230
230
  */
231
231
  addPageBreak(top, bottom) {
232
232
  const ws = this._worksheet;
233
- const topRow = Math.max(0, (top || 0) - 1) || 0;
234
- const bottomRow = Math.max(0, (bottom || 0) - 1) || 1048575;
233
+ const topRow = Math.max(0, (top ?? 0) - 1) || 0;
234
+ const bottomRow = Math.max(0, (bottom ?? 0) - 1) || 1048575;
235
235
  const pb = {
236
236
  id: this._number,
237
237
  max: bottomRow,
@@ -340,7 +340,7 @@ class Column {
340
340
  ? worksheetOrCols
341
341
  : worksheetOrCols;
342
342
  let cols = Array.isArray(worksheetOrCols) ? worksheetOrCols : (colsMaybe ?? []);
343
- cols = cols || [];
343
+ cols = cols ?? [];
344
344
  const columns = [];
345
345
  let count = 1;
346
346
  let index = 0;
@@ -204,7 +204,7 @@ class DefinedNames {
204
204
  value.forEach(definedName => {
205
205
  const matrix = (matrixMap[definedName.name] = new CellMatrix());
206
206
  definedName.ranges.forEach(rangeStr => {
207
- if (rangeRegexp.test(rangeStr.split("!").pop() || "")) {
207
+ if (rangeRegexp.test(rangeStr.split("!").pop() ?? "")) {
208
208
  matrix.addCell(rangeStr);
209
209
  }
210
210
  });
@@ -30,7 +30,7 @@ class FormCheckbox {
30
30
  // Parse range to get anchors
31
31
  const { tl, br } = this._parseRange(range);
32
32
  // Generate shape ID (starting from 1025)
33
- const existingCount = worksheet.formControls?.length || 0;
33
+ const existingCount = worksheet.formControls?.length ?? 0;
34
34
  const shapeId = 1025 + existingCount;
35
35
  // Parse link cell reference
36
36
  let link;
@@ -1,6 +1,39 @@
1
1
  import { range, toSortedArray } from "../../utils/utils.js";
2
2
  import { colCache } from "./utils/col-cache.js";
3
- // TK(2023-10-10): turn this into a class constructor.
3
+ /**
4
+ * Wrapper for OOXML error values in sharedItems (e.g. `<e v="REF!"/>`).
5
+ * Distinguishes error strings from regular strings so they roundtrip as `<e>` not `<s>`.
6
+ */
7
+ export class PivotErrorValue {
8
+ constructor(code) {
9
+ this.code = code;
10
+ }
11
+ /** Returns the display form with '#' prefix, e.g. "#REF!" */
12
+ toString() {
13
+ return `#${this.code}`;
14
+ }
15
+ }
16
+ /** Map from PivotTableSubtotal to its Excel display name prefix */
17
+ export const METRIC_DISPLAY_NAMES = {
18
+ sum: "Sum",
19
+ count: "Count",
20
+ average: "Average",
21
+ max: "Max",
22
+ min: "Min",
23
+ product: "Product",
24
+ countNums: "Count Numbers",
25
+ stdDev: "StdDev",
26
+ stdDevP: "StdDevP",
27
+ var: "Var",
28
+ varP: "VarP"
29
+ };
30
+ /** Set of all valid PivotTableSubtotal values (for runtime validation) */
31
+ export const VALID_SUBTOTALS = new Set(Object.keys(METRIC_DISPLAY_NAMES));
32
+ /**
33
+ * Data rows start at index 2 in ExcelJS sparse arrays:
34
+ * index 0 = empty (ExcelJS convention), index 1 = header row.
35
+ */
36
+ const DATA_START_INDEX = 2;
4
37
  /**
5
38
  * Creates a PivotTableSource adapter from a Table object.
6
39
  * This allows Tables to be used as pivot table data sources with the same interface as Worksheets.
@@ -29,6 +62,9 @@ function createTableSourceAdapter(table) {
29
62
  const dataRows = tableModel.rows.map(row => [undefined, ...row]); // sparse array starting at index 1
30
63
  // Calculate the range reference for the table
31
64
  const tl = tableModel.tl;
65
+ if (!tl) {
66
+ throw new Error(`Table "${tableModel.name}" is missing top-left cell address (tl)`);
67
+ }
32
68
  const startRow = tl.row;
33
69
  const startCol = tl.col;
34
70
  const endRow = startRow + tableModel.rows.length; // header row + data rows
@@ -37,13 +73,15 @@ function createTableSourceAdapter(table) {
37
73
  // Use the worksheet name (not table name) for pivotCacheDefinition's worksheetSource
38
74
  // The sheet attribute in worksheetSource must reference the actual worksheet name
39
75
  const worksheetName = table.worksheet.name;
76
+ const tableName = tableModel.name;
40
77
  return {
41
78
  name: worksheetName,
79
+ tableName,
42
80
  getRow(rowNumber) {
43
81
  if (rowNumber === 1) {
44
82
  return { values: headerRow };
45
83
  }
46
- const dataIndex = rowNumber - 2; // rowNumber 2 maps to index 0
84
+ const dataIndex = rowNumber - DATA_START_INDEX; // rowNumber 2 maps to index 0
47
85
  if (dataIndex >= 0 && dataIndex < dataRows.length) {
48
86
  return { values: dataRows[dataIndex] };
49
87
  }
@@ -74,66 +112,87 @@ function createTableSourceAdapter(table) {
74
112
  dimensions: { shortRange }
75
113
  };
76
114
  }
115
+ /** Base cache ID starts at 10 (Excel convention), each subsequent table increments */
116
+ const BASE_CACHE_ID = 10;
77
117
  /**
78
118
  * Resolves the data source from the model, supporting both sourceSheet and sourceTable.
119
+ * Validates that exactly one source is provided.
79
120
  */
80
121
  function resolveSource(model) {
122
+ if (model.sourceSheet && model.sourceTable) {
123
+ throw new Error("Cannot specify both sourceSheet and sourceTable. Choose one.");
124
+ }
81
125
  if (model.sourceTable) {
82
126
  return createTableSourceAdapter(model.sourceTable);
83
127
  }
84
- // For sourceSheet, it already implements the required interface
128
+ if (!model.sourceSheet) {
129
+ throw new Error("Either sourceSheet or sourceTable must be provided.");
130
+ }
85
131
  return model.sourceSheet;
86
132
  }
133
+ /** Resolve a value entry to its column name string */
134
+ function resolveValueName(v) {
135
+ return typeof v === "string" ? v : v.name;
136
+ }
137
+ /** Resolve a value entry's metric (or undefined if inheriting table-wide default) */
138
+ function resolveValueMetric(v) {
139
+ return typeof v === "string" ? undefined : v.metric;
140
+ }
87
141
  function makePivotTable(worksheet, model) {
88
- // Example `model`:
89
- // {
90
- // // Source of data (either sourceSheet OR sourceTable):
91
- // sourceSheet: worksheet1, // Use entire sheet range
92
- // // OR
93
- // sourceTable: table, // Use table data
94
- //
95
- // // Pivot table fields: values indicate field names;
96
- // // they come from the first row in `worksheet1` or table column names.
97
- // rows: ['A', 'B'],
98
- // columns: ['C'],
99
- // values: ['E'], // only 1 item possible for now
100
- // metric: 'sum', // only 'sum' possible for now
101
- // }
102
- // Validate source exists before trying to resolve it
103
- if (!model.sourceSheet && !model.sourceTable) {
104
- throw new Error("Either sourceSheet or sourceTable must be provided.");
105
- }
106
- if (model.sourceSheet && model.sourceTable) {
107
- throw new Error("Cannot specify both sourceSheet and sourceTable. Choose one.");
108
- }
109
- // Resolve source first to avoid creating adapter multiple times
142
+ // Resolve source (validates exactly one source is provided)
110
143
  const source = resolveSource(model);
111
- validate(worksheet, model, source);
112
- const { rows, values } = model;
144
+ validate(model, source);
145
+ const { rows } = model;
113
146
  const columns = model.columns ?? [];
114
- const cacheFields = makeCacheFields(source, [...rows, ...columns], values);
115
- const nameToIndex = cacheFields.reduce((result, cacheField, index) => {
116
- result[cacheField.name] = index;
117
- return result;
118
- }, {});
119
- const rowIndices = rows.map(row => nameToIndex[row]);
120
- const columnIndices = columns.map(column => nameToIndex[column]);
121
- const valueIndices = values.map(value => nameToIndex[value]);
122
- // Calculate tableNumber based on existing pivot tables (1-indexed)
123
- const tableNumber = worksheet.workbook.pivotTables.length + 1;
124
- // Base cache ID starts at 10 (Excel convention), each subsequent table increments
125
- const BASE_CACHE_ID = 10;
147
+ const pages = model.pages ?? [];
148
+ const valueNames = model.values.map(resolveValueName);
149
+ const defaultMetric = model.metric ?? "sum";
150
+ const valueMetrics = model.values.map(v => resolveValueMetric(v) ?? defaultMetric);
151
+ const cacheFields = makeCacheFields(source, [...rows, ...columns, ...pages], valueNames);
152
+ const nameToIndex = {};
153
+ for (let i = 0; i < cacheFields.length; i++) {
154
+ nameToIndex[cacheFields[i].name] = i;
155
+ }
156
+ const resolveIndex = (fieldName, role) => {
157
+ const idx = nameToIndex[fieldName];
158
+ if (idx === undefined) {
159
+ throw new Error(`${role} field "${fieldName}" not found in cache fields`);
160
+ }
161
+ return idx;
162
+ };
163
+ const rowIndices = rows.map(row => resolveIndex(row, "Row"));
164
+ const columnIndices = columns.map(column => resolveIndex(column, "Column"));
165
+ const valueIndices = valueNames.map(value => resolveIndex(value, "Value"));
166
+ const pageIndices = pages.map(page => resolveIndex(page, "Page"));
167
+ // R9-B1: Calculate tableNumber as max(existing)+1 to avoid collision with loaded
168
+ // pivot tables that may have non-contiguous numbering (e.g. [1, 2, 5]).
169
+ // Using length+1 would collide when adding multiple new tables.
170
+ const existingTableNumbers = worksheet.workbook.pivotTables
171
+ .map(pt => pt.tableNumber)
172
+ .filter(n => Number.isFinite(n));
173
+ const tableNumber = existingTableNumbers.length > 0
174
+ ? existingTableNumbers.reduce((a, b) => (a > b ? a : b), -Infinity) + 1
175
+ : 1;
176
+ // Dynamic cacheId: avoid collision with existing (loaded) pivot tables.
177
+ // Find the max cacheId already in use and start from max+1.
178
+ const existingCacheIds = worksheet.workbook.pivotTables
179
+ .map(pt => parseInt(pt.cacheId, 10))
180
+ .filter(id => Number.isFinite(id));
181
+ // R8-O3: Use reduce instead of Math.max(...spread) to avoid stack overflow with many pivot tables
182
+ const nextCacheId = existingCacheIds.length > 0
183
+ ? existingCacheIds.reduce((a, b) => (a > b ? a : b), -Infinity) + 1
184
+ : BASE_CACHE_ID + tableNumber - 1;
126
185
  // form pivot table object
127
186
  return {
128
187
  source,
129
188
  rows: rowIndices,
130
189
  columns: columnIndices,
131
190
  values: valueIndices,
132
- metric: model.metric ?? "sum",
191
+ pages: pageIndices,
192
+ metric: defaultMetric,
193
+ valueMetrics,
133
194
  cacheFields,
134
- // Dynamic cacheId: 10 for first table, 11 for second, etc.
135
- // Used in <pivotTableDefinition> and xl/workbook.xml
136
- cacheId: String(BASE_CACHE_ID + tableNumber - 1),
195
+ cacheId: String(nextCacheId),
137
196
  // Control whether pivot table style overrides worksheet column widths
138
197
  // '0' = preserve worksheet column widths (useful for custom sizing)
139
198
  // '1' = apply pivot table style width/height (default Excel behavior)
@@ -142,77 +201,224 @@ function makePivotTable(worksheet, model) {
142
201
  tableNumber
143
202
  };
144
203
  }
145
- function validate(_worksheet, model, source) {
146
- if (model.metric && model.metric !== "sum" && model.metric !== "count") {
147
- throw new Error('Only the "sum" and "count" metrics are supported at this time.');
148
- }
204
+ function validate(model, source) {
149
205
  const columns = model.columns ?? [];
206
+ const pages = model.pages ?? [];
207
+ const valueNames = model.values.map(resolveValueName);
150
208
  // Get header names from source (already resolved)
151
209
  const headerNames = source.getRow(1).values.slice(1);
152
- // Use Set for O(1) lookup
153
- const headerNameSet = new Set(headerNames);
154
- for (const name of [...model.rows, ...columns, ...model.values]) {
210
+ // Validate no empty header names (null, undefined, empty-string, or whitespace-only).
211
+ // Note: numeric 0 and boolean false are valid headers (they coerce to "0"/"false").
212
+ for (let i = 0; i < headerNames.length; i++) {
213
+ const h = headerNames[i];
214
+ if (h === null || h === undefined || h === "" || (typeof h === "string" && h.trim() === "")) {
215
+ throw new Error(`Empty or missing header name at column ${i + 1} in ${source.name}. Pivot tables require all columns to have non-empty headers.`);
216
+ }
217
+ }
218
+ // Validate no duplicate header names
219
+ const headerDupCheck = new Set();
220
+ for (const h of headerNames) {
221
+ const name = String(h);
222
+ if (headerDupCheck.has(name)) {
223
+ throw new Error(`Duplicate header name "${name}" found in ${source.name}. Pivot tables require unique column names.`);
224
+ }
225
+ headerDupCheck.add(name);
226
+ }
227
+ // Use Set for O(1) lookup — coerce to String for consistent comparison with user-supplied names
228
+ const headerNameSet = new Set(headerNames.map(String));
229
+ const validateFieldExists = (name) => {
155
230
  if (!headerNameSet.has(name)) {
156
231
  throw new Error(`The header name "${name}" was not found in ${source.name}.`);
157
232
  }
233
+ };
234
+ for (const name of model.rows) {
235
+ validateFieldExists(name);
236
+ }
237
+ for (const name of columns) {
238
+ validateFieldExists(name);
239
+ }
240
+ for (const name of valueNames) {
241
+ validateFieldExists(name);
242
+ }
243
+ for (const name of pages) {
244
+ validateFieldExists(name);
245
+ }
246
+ // Validate no duplicate field names across axis areas (rows, columns, pages).
247
+ // A field can only belong to one axis area. Values can overlap with axis areas (dataField="1").
248
+ const fieldToAxis = new Map();
249
+ const axisAreas = [
250
+ { name: "rows", fields: model.rows },
251
+ { name: "columns", fields: columns },
252
+ { name: "pages", fields: pages }
253
+ ];
254
+ for (const area of axisAreas) {
255
+ for (const field of area.fields) {
256
+ const existing = fieldToAxis.get(field);
257
+ if (existing === area.name) {
258
+ throw new Error(`Duplicate field "${field}" in ${area.name}. Each field can only appear once per axis area.`);
259
+ }
260
+ else if (existing) {
261
+ throw new Error(`Field "${field}" cannot appear in both ${existing} and ${area.name}. Each field can only be assigned to one axis area.`);
262
+ }
263
+ fieldToAxis.set(field, area.name);
264
+ }
158
265
  }
159
266
  if (!model.rows.length) {
160
267
  throw new Error("No pivot table rows specified.");
161
268
  }
162
269
  // Allow empty columns - Excel will use "Values" as column field
163
- // But can't have multiple values with columns specified
164
270
  if (model.values.length < 1) {
165
271
  throw new Error("Must have at least one value.");
166
272
  }
167
- if (model.values.length > 1 && columns.length > 0) {
168
- throw new Error("It is currently not possible to have multiple values when columns are specified. Please either supply an empty array for columns or a single value.");
273
+ // Validate metric values at runtime (guards against `as any` bypasses)
274
+ if (model.metric !== undefined && !VALID_SUBTOTALS.has(model.metric)) {
275
+ throw new Error(`Invalid metric "${model.metric}". Must be one of: ${[...VALID_SUBTOTALS].join(", ")}.`);
169
276
  }
277
+ for (const v of model.values) {
278
+ const perMetric = resolveValueMetric(v);
279
+ if (perMetric !== undefined && !VALID_SUBTOTALS.has(perMetric)) {
280
+ throw new Error(`Invalid metric "${perMetric}" on value field "${resolveValueName(v)}". Must be one of: ${[...VALID_SUBTOTALS].join(", ")}.`);
281
+ }
282
+ }
283
+ // Validate no duplicate value field names
284
+ const valueDupCheck = new Set();
285
+ for (const name of valueNames) {
286
+ if (valueDupCheck.has(name)) {
287
+ throw new Error(`Duplicate value field "${name}". Each value field name must be unique.`);
288
+ }
289
+ valueDupCheck.add(name);
290
+ }
291
+ // Multiple values with columns is supported — the synthetic "Values" pseudo-field
292
+ // (field x="-2") is appended to colFields so Excel positions the data field labels
293
+ // correctly on the column axis.
294
+ }
295
+ /**
296
+ * R8-B2: Unwrap complex cell value types to a primitive suitable for pivot table shared items.
297
+ * - CellErrorValue ({error:"#REF!"}) → PivotErrorValue
298
+ * - CellRichTextValue ({richText:[...]}) → concatenated plain text
299
+ * - CellFormulaValue / CellArrayFormulaValue / CellSharedFormulaValue → result value (recursive)
300
+ * - CellHyperlinkValue ({text,hyperlink}) → text string
301
+ * - CellCheckboxValue ({checkbox:bool}) → boolean
302
+ * - Other objects → String(v)
303
+ */
304
+ function unwrapCellValue(v) {
305
+ if (v === null || v === undefined) {
306
+ return null;
307
+ }
308
+ if (typeof v !== "object") {
309
+ // Already a primitive (string, number, boolean)
310
+ return v;
311
+ }
312
+ if (v instanceof Date) {
313
+ return v;
314
+ }
315
+ if (v instanceof PivotErrorValue) {
316
+ return v;
317
+ }
318
+ const obj = v;
319
+ // CellErrorValue: { error: "#REF!" } → PivotErrorValue with code "REF!" (strip leading #)
320
+ if (typeof obj.error === "string") {
321
+ const errorStr = obj.error;
322
+ return new PivotErrorValue(errorStr.startsWith("#") ? errorStr.slice(1) : errorStr);
323
+ }
324
+ // CellFormulaValue / CellArrayFormulaValue / CellSharedFormulaValue: { formula/sharedFormula, result }
325
+ if ("formula" in obj || "sharedFormula" in obj) {
326
+ const result = obj.result;
327
+ if (result === undefined || result === null) {
328
+ return null;
329
+ }
330
+ // result can be number | string | boolean | Date | CellErrorValue — recurse
331
+ return unwrapCellValue(result);
332
+ }
333
+ // CellRichTextValue: { richText: [{text:"..."}, ...] }
334
+ if (Array.isArray(obj.richText)) {
335
+ return obj.richText.map(rt => rt.text ?? "").join("");
336
+ }
337
+ // CellHyperlinkValue: { text, hyperlink }
338
+ if (typeof obj.text === "string" && typeof obj.hyperlink === "string") {
339
+ return obj.text;
340
+ }
341
+ // CellCheckboxValue: { checkbox: boolean }
342
+ if (typeof obj.checkbox === "boolean") {
343
+ return obj.checkbox;
344
+ }
345
+ // Unknown object — fallback to string
346
+ return String(v);
170
347
  }
171
348
  function makeCacheFields(source, fieldNamesWithSharedItems, valueFieldNames) {
172
349
  // Cache fields are used in pivot tables to reference source data.
173
350
  // Fields in fieldNamesWithSharedItems get their unique values extracted as sharedItems.
174
351
  // Fields in valueFieldNames (but not in fieldNamesWithSharedItems) get min/max calculated.
175
- // Other fields are unused and get empty sharedItems.
352
+ // Other fields are unused and get null sharedItems.
176
353
  const names = source.getRow(1).values;
177
354
  // Use Set for O(1) lookup instead of object
178
355
  const sharedItemsFields = new Set(fieldNamesWithSharedItems);
179
356
  const valueFields = new Set(valueFieldNames);
180
357
  const aggregate = (columnIndex) => {
181
358
  const columnValues = source.getColumn(columnIndex).values;
182
- // Build unique values set directly, skipping header (index 0,1) and null/undefined
359
+ // Build unique values set directly, skipping header (index 0,1).
360
+ // null/undefined are tracked separately (collapsed to a single null sentinel)
361
+ // because Set treats each null as the same key but undefined as a separate key,
362
+ // and we need null in sharedItems so renderCellNew can find it via indexOf.
183
363
  const uniqueValues = new Set();
184
- for (let i = 2; i < columnValues.length; i++) {
185
- const v = columnValues[i];
186
- if (v !== null && v !== undefined) {
364
+ // R8-B12: PivotErrorValue uses reference equality in Set, so track error strings
365
+ // separately to avoid duplicates (e.g., two PivotErrorValue("#REF!") instances).
366
+ const seenErrors = new Map();
367
+ let hasNull = false;
368
+ for (let i = DATA_START_INDEX; i < columnValues.length; i++) {
369
+ // R8-B2: Unwrap complex cell values (formula results, rich text, errors, etc.)
370
+ const v = unwrapCellValue(columnValues[i]);
371
+ if (v === null || (typeof v === "number" && isNaN(v))) {
372
+ hasNull = true;
373
+ }
374
+ else if (v instanceof PivotErrorValue) {
375
+ // R8-B12: Deduplicate PivotErrorValue by error string
376
+ if (!seenErrors.has(v.code)) {
377
+ seenErrors.set(v.code, v);
378
+ uniqueValues.add(v);
379
+ }
380
+ }
381
+ else {
187
382
  uniqueValues.add(v);
188
383
  }
189
384
  }
190
- return toSortedArray(uniqueValues);
385
+ const sorted = toSortedArray(uniqueValues);
386
+ // Append null at the end (OOXML convention: <m/> items go last in sharedItems)
387
+ if (hasNull) {
388
+ sorted.push(null);
389
+ }
390
+ return sorted;
191
391
  };
192
- // Calculate min/max for numeric fields
392
+ // Calculate min/max and integer status for numeric fields
193
393
  const getMinMax = (columnIndex) => {
194
394
  const columnValues = source.getColumn(columnIndex).values;
195
395
  let min = Infinity;
196
396
  let max = -Infinity;
197
397
  let hasNumeric = false;
198
- for (let i = 2; i < columnValues.length; i++) {
199
- const v = columnValues[i];
200
- if (typeof v === "number" && !isNaN(v)) {
398
+ let allInteger = true;
399
+ for (let i = DATA_START_INDEX; i < columnValues.length; i++) {
400
+ // R8-B10: Unwrap formula/complex cell values to extract numeric results
401
+ const unwrapped = unwrapCellValue(columnValues[i]);
402
+ if (typeof unwrapped === "number" && !isNaN(unwrapped)) {
201
403
  hasNumeric = true;
202
- if (v < min) {
203
- min = v;
404
+ if (unwrapped < min) {
405
+ min = unwrapped;
406
+ }
407
+ if (unwrapped > max) {
408
+ max = unwrapped;
204
409
  }
205
- if (v > max) {
206
- max = v;
410
+ if (!Number.isInteger(unwrapped)) {
411
+ allInteger = false;
207
412
  }
208
413
  }
209
414
  }
210
- return hasNumeric ? { minValue: min, maxValue: max } : null;
415
+ return hasNumeric ? { minValue: min, maxValue: max, allInteger } : null;
211
416
  };
212
417
  // Build result array
213
418
  const result = [];
214
419
  for (const columnIndex of range(1, names.length)) {
215
- const name = names[columnIndex];
420
+ const rawName = names[columnIndex];
421
+ const name = String(rawName);
216
422
  if (sharedItemsFields.has(name)) {
217
423
  // Field used for rows/columns - extract unique values as sharedItems
218
424
  result.push({ name, sharedItems: aggregate(columnIndex) });
@@ -223,8 +429,10 @@ function makeCacheFields(source, fieldNamesWithSharedItems, valueFieldNames) {
223
429
  result.push({
224
430
  name,
225
431
  sharedItems: null,
432
+ containsNumber: minMax ? "1" : undefined,
226
433
  minValue: minMax?.minValue,
227
- maxValue: minMax?.maxValue
434
+ maxValue: minMax?.maxValue,
435
+ containsInteger: minMax?.allInteger ? "1" : undefined
228
436
  });
229
437
  }
230
438
  else {
@@ -156,8 +156,8 @@ class Row {
156
156
  // Page Breaks
157
157
  addPageBreak(lft, rght) {
158
158
  const ws = this._worksheet;
159
- const left = Math.max(0, (lft || 0) - 1) || 0;
160
- const right = Math.max(0, (rght || 0) - 1) || 16838;
159
+ const left = Math.max(0, (lft ?? 0) - 1) || 0;
160
+ const right = Math.max(0, (rght ?? 0) - 1) || 16838;
161
161
  const pb = {
162
162
  id: this._number,
163
163
  max: right,
@@ -351,7 +351,7 @@ class Row {
351
351
  this._hidden = value;
352
352
  }
353
353
  get outlineLevel() {
354
- return this._outlineLevel || 0;
354
+ return this._outlineLevel ?? 0;
355
355
  }
356
356
  set outlineLevel(value) {
357
357
  this._outlineLevel = value;
@@ -435,7 +435,7 @@ class Row {
435
435
  delete this.height;
436
436
  }
437
437
  this.hidden = value.hidden;
438
- this.outlineLevel = value.outlineLevel || 0;
438
+ this.outlineLevel = value.outlineLevel ?? 0;
439
439
  this.dyDescent = value.dyDescent;
440
440
  this.style = (value.style && JSON.parse(JSON.stringify(value.style))) || {};
441
441
  }
@@ -169,7 +169,7 @@ export class WorkbookReaderBase extends EventEmitter {
169
169
  this.workbookRels = await xform.parseStream(iterateStream(entry));
170
170
  // Build fast lookup for worksheet relationship ids.
171
171
  this._workbookRelIdByTarget = Object.create(null);
172
- for (const rel of this.workbookRels || []) {
172
+ for (const rel of this.workbookRels ?? []) {
173
173
  if (rel?.Target && rel?.Id) {
174
174
  this._workbookRelIdByTarget[rel.Target] = rel.Id;
175
175
  }
@@ -182,7 +182,7 @@ export class WorkbookReaderBase extends EventEmitter {
182
182
  this.properties = workbook.map?.workbookPr;
183
183
  // Build fast lookup for sheet metadata by relationship id.
184
184
  this._sheetByRelId = Object.create(null);
185
- for (const sheet of this.model?.sheets || []) {
185
+ for (const sheet of this.model?.sheets ?? []) {
186
186
  this._sheetByRelId[sheet.rId] = sheet;
187
187
  }
188
188
  }
@@ -289,10 +289,10 @@ export class WorkbookReaderBase extends EventEmitter {
289
289
  break;
290
290
  case "si":
291
291
  if (this.options.sharedStrings === "cache") {
292
- this.sharedStrings.push(richText.length ? { richText } : text || "");
292
+ this.sharedStrings.push(richText.length ? { richText } : (text ?? ""));
293
293
  }
294
294
  else if (this.options.sharedStrings === "emit") {
295
- yield { index: index++, text: richText.length ? { richText } : text || "" };
295
+ yield { index: index++, text: richText.length ? { richText } : (text ?? "") };
296
296
  }
297
297
  richText = [];
298
298
  font = null;