@cj-tech-master/excelts 7.0.1 → 7.1.0-canary.20260401153228.4a85b2c

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 (225) hide show
  1. package/README.md +55 -56
  2. package/README_zh.md +55 -56
  3. package/dist/browser/index.browser.d.ts +1 -1
  4. package/dist/browser/index.browser.js +1 -1
  5. package/dist/browser/index.d.ts +1 -1
  6. package/dist/browser/index.js +1 -1
  7. package/dist/browser/modules/excel/stream/hyperlink-reader.js +36 -30
  8. package/dist/browser/modules/excel/stream/sheet-comments-writer.js +7 -7
  9. package/dist/browser/modules/excel/stream/sheet-rels-writer.js +4 -4
  10. package/dist/browser/modules/excel/stream/workbook-reader.browser.js +221 -103
  11. package/dist/browser/modules/excel/stream/workbook-writer.browser.js +12 -4
  12. package/dist/browser/modules/excel/stream/worksheet-reader.js +232 -216
  13. package/dist/browser/modules/excel/utils/col-cache.d.ts +1 -0
  14. package/dist/browser/modules/excel/utils/col-cache.js +42 -21
  15. package/dist/browser/modules/excel/utils/ooxml-validator.js +40 -18
  16. package/dist/browser/modules/excel/utils/stream-buf.js +6 -1
  17. package/dist/browser/modules/excel/utils/string-buf.js +19 -10
  18. package/dist/browser/modules/excel/xlsx/xform/base-xform.d.ts +8 -2
  19. package/dist/browser/modules/excel/xlsx/xform/base-xform.js +127 -10
  20. package/dist/browser/modules/excel/xlsx/xform/book/sheet-xform.js +1 -2
  21. package/dist/browser/modules/excel/xlsx/xform/book/workbook-xform.js +2 -2
  22. package/dist/browser/modules/excel/xlsx/xform/comment/comments-xform.js +2 -2
  23. package/dist/browser/modules/excel/xlsx/xform/comment/vml-notes-xform.js +2 -2
  24. package/dist/browser/modules/excel/xlsx/xform/core/app-xform.js +2 -2
  25. package/dist/browser/modules/excel/xlsx/xform/core/content-types-xform.js +2 -2
  26. package/dist/browser/modules/excel/xlsx/xform/core/core-xform.js +2 -2
  27. package/dist/browser/modules/excel/xlsx/xform/core/relationships-xform.js +2 -2
  28. package/dist/browser/modules/excel/xlsx/xform/drawing/ctrl-prop-xform.js +2 -2
  29. package/dist/browser/modules/excel/xlsx/xform/drawing/drawing-xform.js +2 -2
  30. package/dist/browser/modules/excel/xlsx/xform/drawing/vml-drawing-xform.js +2 -2
  31. package/dist/browser/modules/excel/xlsx/xform/pivot-table/cache-field.js +1 -1
  32. package/dist/browser/modules/excel/xlsx/xform/pivot-table/pivot-cache-definition-xform.d.ts +2 -2
  33. package/dist/browser/modules/excel/xlsx/xform/pivot-table/pivot-cache-definition-xform.js +8 -8
  34. package/dist/browser/modules/excel/xlsx/xform/pivot-table/pivot-cache-records-xform.d.ts +2 -2
  35. package/dist/browser/modules/excel/xlsx/xform/pivot-table/pivot-cache-records-xform.js +11 -11
  36. package/dist/browser/modules/excel/xlsx/xform/pivot-table/pivot-table-xform.d.ts +2 -2
  37. package/dist/browser/modules/excel/xlsx/xform/pivot-table/pivot-table-xform.js +14 -14
  38. package/dist/browser/modules/excel/xlsx/xform/pivot-table/raw-xml-collector.js +1 -1
  39. package/dist/browser/modules/excel/xlsx/xform/sheet/cell-xform.js +4 -4
  40. package/dist/browser/modules/excel/xlsx/xform/sheet/header-footer-xform.js +35 -42
  41. package/dist/browser/modules/excel/xlsx/xform/sheet/row-xform.js +11 -7
  42. package/dist/browser/modules/excel/xlsx/xform/sheet/sheet-properties-xform.js +15 -13
  43. package/dist/browser/modules/excel/xlsx/xform/sheet/worksheet-xform.js +17 -7
  44. package/dist/browser/modules/excel/xlsx/xform/static-xform.js +3 -3
  45. package/dist/browser/modules/excel/xlsx/xform/strings/shared-strings-xform.js +2 -2
  46. package/dist/browser/modules/excel/xlsx/xform/strings/text-xform.d.ts +0 -1
  47. package/dist/browser/modules/excel/xlsx/xform/strings/text-xform.js +11 -4
  48. package/dist/browser/modules/excel/xlsx/xform/style/alignment-xform.js +5 -11
  49. package/dist/browser/modules/excel/xlsx/xform/style/fill-xform.js +8 -12
  50. package/dist/browser/modules/excel/xlsx/xform/style/protection-xform.js +9 -15
  51. package/dist/browser/modules/excel/xlsx/xform/style/styles-xform.js +7 -7
  52. package/dist/browser/modules/excel/xlsx/xform/table/table-xform.js +2 -2
  53. package/dist/browser/modules/excel/xlsx/xlsx.browser.d.ts +17 -4
  54. package/dist/browser/modules/excel/xlsx/xlsx.browser.js +131 -82
  55. package/dist/browser/modules/excel/xlsx/xlsx.js +8 -9
  56. package/dist/browser/modules/xml/dom.d.ts +52 -0
  57. package/dist/browser/modules/xml/dom.js +252 -0
  58. package/dist/browser/modules/xml/encode.d.ts +64 -0
  59. package/dist/browser/modules/xml/encode.js +258 -0
  60. package/dist/browser/modules/xml/errors.d.ts +38 -0
  61. package/dist/browser/modules/xml/errors.js +64 -0
  62. package/dist/browser/modules/xml/index.d.ts +20 -0
  63. package/dist/browser/modules/xml/index.js +31 -0
  64. package/dist/browser/modules/xml/query.d.ts +49 -0
  65. package/dist/browser/modules/xml/query.js +185 -0
  66. package/dist/browser/modules/xml/sax.d.ts +169 -0
  67. package/dist/browser/modules/xml/sax.js +1777 -0
  68. package/dist/browser/modules/xml/stream-writer.d.ts +59 -0
  69. package/dist/browser/modules/xml/stream-writer.js +210 -0
  70. package/dist/browser/modules/xml/types.d.ts +218 -0
  71. package/dist/browser/modules/xml/types.js +7 -0
  72. package/dist/browser/modules/xml/writer.d.ts +75 -0
  73. package/dist/browser/modules/xml/writer.js +270 -0
  74. package/dist/browser/utils/utils.base.d.ts +1 -6
  75. package/dist/browser/utils/utils.base.js +38 -84
  76. package/dist/browser/utils/utils.browser.d.ts +1 -1
  77. package/dist/browser/utils/utils.browser.js +1 -1
  78. package/dist/browser/utils/utils.d.ts +1 -1
  79. package/dist/browser/utils/utils.js +1 -1
  80. package/dist/cjs/index.js +3 -3
  81. package/dist/cjs/modules/excel/stream/hyperlink-reader.js +36 -30
  82. package/dist/cjs/modules/excel/stream/sheet-comments-writer.js +7 -7
  83. package/dist/cjs/modules/excel/stream/sheet-rels-writer.js +5 -5
  84. package/dist/cjs/modules/excel/stream/workbook-reader.browser.js +221 -103
  85. package/dist/cjs/modules/excel/stream/workbook-writer.browser.js +12 -4
  86. package/dist/cjs/modules/excel/stream/worksheet-reader.js +231 -215
  87. package/dist/cjs/modules/excel/utils/col-cache.js +42 -21
  88. package/dist/cjs/modules/excel/utils/ooxml-validator.js +41 -19
  89. package/dist/cjs/modules/excel/utils/stream-buf.js +6 -1
  90. package/dist/cjs/modules/excel/utils/string-buf.js +19 -10
  91. package/dist/cjs/modules/excel/xlsx/xform/base-xform.js +127 -10
  92. package/dist/cjs/modules/excel/xlsx/xform/book/sheet-xform.js +1 -2
  93. package/dist/cjs/modules/excel/xlsx/xform/book/workbook-xform.js +2 -2
  94. package/dist/cjs/modules/excel/xlsx/xform/comment/comments-xform.js +2 -2
  95. package/dist/cjs/modules/excel/xlsx/xform/comment/vml-notes-xform.js +2 -2
  96. package/dist/cjs/modules/excel/xlsx/xform/core/app-xform.js +2 -2
  97. package/dist/cjs/modules/excel/xlsx/xform/core/content-types-xform.js +2 -2
  98. package/dist/cjs/modules/excel/xlsx/xform/core/core-xform.js +2 -2
  99. package/dist/cjs/modules/excel/xlsx/xform/core/relationships-xform.js +2 -2
  100. package/dist/cjs/modules/excel/xlsx/xform/drawing/ctrl-prop-xform.js +2 -2
  101. package/dist/cjs/modules/excel/xlsx/xform/drawing/drawing-xform.js +2 -2
  102. package/dist/cjs/modules/excel/xlsx/xform/drawing/vml-drawing-xform.js +2 -2
  103. package/dist/cjs/modules/excel/xlsx/xform/pivot-table/cache-field.js +5 -5
  104. package/dist/cjs/modules/excel/xlsx/xform/pivot-table/pivot-cache-definition-xform.js +8 -8
  105. package/dist/cjs/modules/excel/xlsx/xform/pivot-table/pivot-cache-records-xform.js +14 -14
  106. package/dist/cjs/modules/excel/xlsx/xform/pivot-table/pivot-table-xform.js +14 -14
  107. package/dist/cjs/modules/excel/xlsx/xform/pivot-table/raw-xml-collector.js +3 -3
  108. package/dist/cjs/modules/excel/xlsx/xform/sheet/cell-xform.js +3 -3
  109. package/dist/cjs/modules/excel/xlsx/xform/sheet/header-footer-xform.js +35 -42
  110. package/dist/cjs/modules/excel/xlsx/xform/sheet/row-xform.js +11 -7
  111. package/dist/cjs/modules/excel/xlsx/xform/sheet/sheet-properties-xform.js +15 -13
  112. package/dist/cjs/modules/excel/xlsx/xform/sheet/worksheet-xform.js +17 -7
  113. package/dist/cjs/modules/excel/xlsx/xform/static-xform.js +3 -3
  114. package/dist/cjs/modules/excel/xlsx/xform/strings/shared-strings-xform.js +2 -2
  115. package/dist/cjs/modules/excel/xlsx/xform/strings/text-xform.js +11 -4
  116. package/dist/cjs/modules/excel/xlsx/xform/style/alignment-xform.js +5 -11
  117. package/dist/cjs/modules/excel/xlsx/xform/style/fill-xform.js +8 -12
  118. package/dist/cjs/modules/excel/xlsx/xform/style/protection-xform.js +9 -15
  119. package/dist/cjs/modules/excel/xlsx/xform/style/styles-xform.js +7 -7
  120. package/dist/cjs/modules/excel/xlsx/xform/table/table-xform.js +2 -2
  121. package/dist/cjs/modules/excel/xlsx/xlsx.browser.js +131 -82
  122. package/dist/cjs/modules/excel/xlsx/xlsx.js +8 -9
  123. package/dist/cjs/modules/xml/dom.js +259 -0
  124. package/dist/cjs/modules/xml/encode.js +267 -0
  125. package/dist/cjs/modules/xml/errors.js +72 -0
  126. package/dist/cjs/modules/xml/index.js +59 -0
  127. package/dist/cjs/modules/xml/query.js +188 -0
  128. package/dist/cjs/modules/xml/sax.js +1782 -0
  129. package/dist/cjs/modules/xml/stream-writer.js +213 -0
  130. package/dist/cjs/modules/xml/types.js +8 -0
  131. package/dist/cjs/modules/xml/writer.js +274 -0
  132. package/dist/cjs/utils/utils.base.js +41 -86
  133. package/dist/cjs/utils/utils.browser.js +1 -3
  134. package/dist/cjs/utils/utils.js +1 -3
  135. package/dist/esm/index.browser.js +1 -1
  136. package/dist/esm/index.js +1 -1
  137. package/dist/esm/modules/excel/stream/hyperlink-reader.js +36 -30
  138. package/dist/esm/modules/excel/stream/sheet-comments-writer.js +7 -7
  139. package/dist/esm/modules/excel/stream/sheet-rels-writer.js +4 -4
  140. package/dist/esm/modules/excel/stream/workbook-reader.browser.js +221 -103
  141. package/dist/esm/modules/excel/stream/workbook-writer.browser.js +12 -4
  142. package/dist/esm/modules/excel/stream/worksheet-reader.js +232 -216
  143. package/dist/esm/modules/excel/utils/col-cache.js +42 -21
  144. package/dist/esm/modules/excel/utils/ooxml-validator.js +40 -18
  145. package/dist/esm/modules/excel/utils/stream-buf.js +6 -1
  146. package/dist/esm/modules/excel/utils/string-buf.js +19 -10
  147. package/dist/esm/modules/excel/xlsx/xform/base-xform.js +127 -10
  148. package/dist/esm/modules/excel/xlsx/xform/book/sheet-xform.js +1 -2
  149. package/dist/esm/modules/excel/xlsx/xform/book/workbook-xform.js +2 -2
  150. package/dist/esm/modules/excel/xlsx/xform/comment/comments-xform.js +2 -2
  151. package/dist/esm/modules/excel/xlsx/xform/comment/vml-notes-xform.js +2 -2
  152. package/dist/esm/modules/excel/xlsx/xform/core/app-xform.js +2 -2
  153. package/dist/esm/modules/excel/xlsx/xform/core/content-types-xform.js +2 -2
  154. package/dist/esm/modules/excel/xlsx/xform/core/core-xform.js +2 -2
  155. package/dist/esm/modules/excel/xlsx/xform/core/relationships-xform.js +2 -2
  156. package/dist/esm/modules/excel/xlsx/xform/drawing/ctrl-prop-xform.js +2 -2
  157. package/dist/esm/modules/excel/xlsx/xform/drawing/drawing-xform.js +2 -2
  158. package/dist/esm/modules/excel/xlsx/xform/drawing/vml-drawing-xform.js +2 -2
  159. package/dist/esm/modules/excel/xlsx/xform/pivot-table/cache-field.js +1 -1
  160. package/dist/esm/modules/excel/xlsx/xform/pivot-table/pivot-cache-definition-xform.js +8 -8
  161. package/dist/esm/modules/excel/xlsx/xform/pivot-table/pivot-cache-records-xform.js +11 -11
  162. package/dist/esm/modules/excel/xlsx/xform/pivot-table/pivot-table-xform.js +14 -14
  163. package/dist/esm/modules/excel/xlsx/xform/pivot-table/raw-xml-collector.js +1 -1
  164. package/dist/esm/modules/excel/xlsx/xform/sheet/cell-xform.js +4 -4
  165. package/dist/esm/modules/excel/xlsx/xform/sheet/header-footer-xform.js +35 -42
  166. package/dist/esm/modules/excel/xlsx/xform/sheet/row-xform.js +11 -7
  167. package/dist/esm/modules/excel/xlsx/xform/sheet/sheet-properties-xform.js +15 -13
  168. package/dist/esm/modules/excel/xlsx/xform/sheet/worksheet-xform.js +17 -7
  169. package/dist/esm/modules/excel/xlsx/xform/static-xform.js +3 -3
  170. package/dist/esm/modules/excel/xlsx/xform/strings/shared-strings-xform.js +2 -2
  171. package/dist/esm/modules/excel/xlsx/xform/strings/text-xform.js +11 -4
  172. package/dist/esm/modules/excel/xlsx/xform/style/alignment-xform.js +5 -11
  173. package/dist/esm/modules/excel/xlsx/xform/style/fill-xform.js +8 -12
  174. package/dist/esm/modules/excel/xlsx/xform/style/protection-xform.js +9 -15
  175. package/dist/esm/modules/excel/xlsx/xform/style/styles-xform.js +7 -7
  176. package/dist/esm/modules/excel/xlsx/xform/table/table-xform.js +2 -2
  177. package/dist/esm/modules/excel/xlsx/xlsx.browser.js +131 -82
  178. package/dist/esm/modules/excel/xlsx/xlsx.js +8 -9
  179. package/dist/esm/modules/xml/dom.js +252 -0
  180. package/dist/esm/modules/xml/encode.js +258 -0
  181. package/dist/esm/modules/xml/errors.js +64 -0
  182. package/dist/esm/modules/xml/index.js +31 -0
  183. package/dist/esm/modules/xml/query.js +185 -0
  184. package/dist/esm/modules/xml/sax.js +1777 -0
  185. package/dist/esm/modules/xml/stream-writer.js +210 -0
  186. package/dist/esm/modules/xml/types.js +7 -0
  187. package/dist/esm/modules/xml/writer.js +270 -0
  188. package/dist/esm/utils/utils.base.js +38 -84
  189. package/dist/esm/utils/utils.browser.js +1 -1
  190. package/dist/esm/utils/utils.js +1 -1
  191. package/dist/iife/excelts.iife.js +1712 -771
  192. package/dist/iife/excelts.iife.js.map +1 -1
  193. package/dist/iife/excelts.iife.min.js +50 -48
  194. package/dist/types/index.browser.d.ts +1 -1
  195. package/dist/types/index.d.ts +1 -1
  196. package/dist/types/modules/excel/utils/col-cache.d.ts +1 -0
  197. package/dist/types/modules/excel/xlsx/xform/base-xform.d.ts +8 -2
  198. package/dist/types/modules/excel/xlsx/xform/pivot-table/pivot-cache-definition-xform.d.ts +2 -2
  199. package/dist/types/modules/excel/xlsx/xform/pivot-table/pivot-cache-records-xform.d.ts +2 -2
  200. package/dist/types/modules/excel/xlsx/xform/pivot-table/pivot-table-xform.d.ts +2 -2
  201. package/dist/types/modules/excel/xlsx/xform/strings/text-xform.d.ts +0 -1
  202. package/dist/types/modules/excel/xlsx/xlsx.browser.d.ts +17 -4
  203. package/dist/types/modules/xml/dom.d.ts +52 -0
  204. package/dist/types/modules/xml/encode.d.ts +64 -0
  205. package/dist/types/modules/xml/errors.d.ts +38 -0
  206. package/dist/types/modules/xml/index.d.ts +20 -0
  207. package/dist/types/modules/xml/query.d.ts +49 -0
  208. package/dist/types/modules/xml/sax.d.ts +169 -0
  209. package/dist/types/modules/xml/stream-writer.d.ts +59 -0
  210. package/dist/types/modules/xml/types.d.ts +218 -0
  211. package/dist/types/modules/xml/writer.d.ts +75 -0
  212. package/dist/types/utils/utils.base.d.ts +1 -6
  213. package/dist/types/utils/utils.browser.d.ts +1 -1
  214. package/dist/types/utils/utils.d.ts +1 -1
  215. package/package.json +6 -6
  216. package/dist/browser/modules/excel/utils/parse-sax.d.ts +0 -113
  217. package/dist/browser/modules/excel/utils/parse-sax.js +0 -1215
  218. package/dist/browser/modules/excel/utils/xml-stream.d.ts +0 -34
  219. package/dist/browser/modules/excel/utils/xml-stream.js +0 -180
  220. package/dist/cjs/modules/excel/utils/parse-sax.js +0 -1219
  221. package/dist/cjs/modules/excel/utils/xml-stream.js +0 -183
  222. package/dist/esm/modules/excel/utils/parse-sax.js +0 -1215
  223. package/dist/esm/modules/excel/utils/xml-stream.js +0 -180
  224. package/dist/types/modules/excel/utils/parse-sax.d.ts +0 -113
  225. package/dist/types/modules/excel/utils/xml-stream.d.ts +0 -34
package/README.md CHANGED
@@ -9,10 +9,19 @@ Modern TypeScript Excel Workbook Manager - Read, manipulate and write spreadshee
9
9
  ExcelTS is a zero-dependency TypeScript toolkit for spreadsheets and documents:
10
10
 
11
11
  - 🚀 **Zero Runtime Dependencies** — Pure TypeScript, no external packages
12
- - 📦 **Five Modules** — Excel (XLSX/JSON), PDF (standalone engine + Excel bridge), CSV (RFC 4180), Archive (ZIP/TAR), Stream (cross-platform)
12
+ - 📦 **Six Modules** — Excel (XLSX/JSON), PDF (standalone engine + Excel bridge), CSV (RFC 4180), XML (SAX/DOM/Writer), Archive (ZIP/TAR), Stream (cross-platform)
13
+ - 🤖 **AI-Friendly** — Clean, consistent API designed to be easily generated and consumed by AI coding agents — one library handles Excel, PDF, CSV, XML, ZIP, and streaming with maximum efficiency
13
14
  - ✅ **Cross-Platform** — Node.js 22+, Bun, Chrome 89+, Firefox 102+, Safari 14.1+
14
15
  - ✅ **ESM First** — Native ES Modules with CommonJS compatibility and full tree-shaking
15
16
 
17
+ ## Module Documentation
18
+
19
+ - [XML Module](src/modules/xml/README.md) — Zero-dependency SAX/DOM parser, query engine, and dual-mode writer
20
+ - [PDF Module](src/modules/pdf/README.md) — Full-featured zero-dependency PDF engine with encryption and font embedding
21
+ - [CSV Module](src/modules/csv/README.md) — RFC 4180 parser/formatter, streaming, data generation
22
+ - [Archive Module](src/modules/archive/README.md) — ZIP/TAR create/read/edit, compression, encryption
23
+ - [Stream Module](src/modules/stream/README.md) — Cross-platform Readable/Writable/Transform/Duplex
24
+
16
25
  ## Translations
17
26
 
18
27
  - [中文文档](README_zh.md)
@@ -126,6 +135,9 @@ ExcelTS provides focused subpath exports for standalone module usage:
126
135
  // Main entry - Excel core (Workbook, Worksheet, Cell, etc.)
127
136
  import { Workbook, WorkbookWriter } from "@cj-tech-master/excelts";
128
137
 
138
+ // XML toolkit (SAX parser, DOM parser, query engine, writers)
139
+ import { SaxParser, parseXml, XmlWriter, query } from "@cj-tech-master/excelts/xml";
140
+
129
141
  // ZIP/TAR archive utilities
130
142
  import { zip, unzip, ZipArchive, compress } from "@cj-tech-master/excelts/zip";
131
143
 
@@ -136,12 +148,7 @@ import { parseCsv, formatCsv, CsvParserStream } from "@cj-tech-master/excelts/cs
136
148
  import { Readable, pipeline, createTransform } from "@cj-tech-master/excelts/stream";
137
149
  ```
138
150
 
139
- Each subpath supports `browser`, `import` (ESM), and `require` (CJS) conditions. See the module READMEs for details:
140
-
141
- - [PDF Module](src/modules/pdf/README.md) - Full-featured zero-dependency PDF engine with encryption and font embedding
142
- - [CSV Module](src/modules/csv/README.md) - RFC 4180 parser/formatter, streaming, data generation
143
- - [Archive Module](src/modules/archive/README.md) - ZIP/TAR create/read/edit, compression, encryption
144
- - [Stream Module](src/modules/stream/README.md) - Cross-platform Readable/Writable/Transform/Duplex
151
+ Each subpath supports `browser`, `import` (ESM), and `require` (CJS) conditions.
145
152
 
146
153
  ## PDF Export
147
154
 
@@ -251,6 +258,45 @@ archive APIs directly, ZIP string encoding can be customized via `ZipStringEncod
251
258
  When a non-UTF-8 encoding is used, Unicode extra fields can be emitted for better
252
259
  cross-tool compatibility.
253
260
 
261
+ ## XML Toolkit
262
+
263
+ ExcelTS includes a standalone, zero-dependency XML module with streaming and buffered parsing/writing. It powers the XLSX pipeline internally and is available as a standalone subpath export.
264
+
265
+ ### Key Features
266
+
267
+ - **SAX Parser** — Event-driven streaming parser with high throughput
268
+ - **DOM Parser** — Build a queryable XML tree from a string
269
+ - **Query Engine** — Simplified path expressions (`a/b[@id='1']`, `a//c`, `a/b[0]`)
270
+ - **Dual-Mode Writer** — Buffered (`XmlWriter`) and streaming (`XmlStreamWriter`)
271
+ - **Full Namespace Support** — Prefix resolution, reserved namespace enforcement, unbound prefix detection
272
+ - **Security Hardened** — Entity expansion limits, nesting depth limits, duplicate attribute rejection, BOM handling
273
+
274
+ ### Quick Example
275
+
276
+ ```typescript
277
+ import { SaxParser, parseXml, XmlWriter, query } from "@cj-tech-master/excelts/xml";
278
+
279
+ // SAX streaming parse
280
+ const parser = new SaxParser();
281
+ parser.on("opentag", tag => console.log(tag.name, tag.attributes));
282
+ parser.write('<root><item id="1">hello</item></root>');
283
+ parser.close();
284
+
285
+ // DOM parse + query
286
+ const doc = parseXml("<root><a><b>1</b><b>2</b></a></root>");
287
+ const items = queryAll(doc.root, "a/b"); // all <b> elements
288
+
289
+ // Write XML
290
+ const w = new XmlWriter();
291
+ w.openXml();
292
+ w.openNode("root");
293
+ w.leafNode("item", { id: "1" }, "hello");
294
+ w.closeNode();
295
+ console.log(w.xml);
296
+ ```
297
+
298
+ For the full API reference, see the [XML Module documentation](src/modules/xml/README.md).
299
+
254
300
  ### Editing an existing ZIP (ZipEditor)
255
301
 
256
302
  ExcelTS also includes a ZIP editor that can apply filesystem-like edits to an existing archive
@@ -532,6 +578,8 @@ import {
532
578
  // XML utilities
533
579
  xmlEncode,
534
580
  xmlDecode,
581
+ xmlEncodeAttr,
582
+ validateXmlName,
535
583
 
536
584
  // PDF export
537
585
  pdf, // Simplest: pdf([["A", 1], ["B", 2]]) → Uint8Array
@@ -571,28 +619,6 @@ For older browsers without native `CompressionStream` API (Firefox < 113, Safari
571
619
 
572
620
  ExcelTS does **not** require `crypto.randomUUID()` in browsers; it uses an internal UUID v4 generator with a `crypto.getRandomValues()` fallback.
573
621
 
574
- ## Maintainer
575
-
576
- This project is actively maintained by [CJ (@cjnoname)](https://github.com/cjnoname).
577
-
578
- ### Maintenance Status
579
-
580
- **Active Maintenance** - This project is actively maintained with a focus on:
581
-
582
- - 🔒 **Security Updates** - Timely security patches and dependency updates
583
- - 🐛 **Bug Fixes** - Critical bug fixes and stability improvements
584
- - 📦 **Dependency Management** - Keeping dependencies up-to-date and secure
585
- - 🔍 **Code Review** - Reviewing and merging community contributions
586
-
587
- ### Contributing
588
-
589
- While I may not have the bandwidth to develop new features regularly, **community contributions are highly valued and encouraged!**
590
-
591
- - 💡 **Pull Requests Welcome** - I will review and merge quality PRs promptly
592
- - 🚀 **Feature Proposals** - Open an issue to discuss new features before implementing
593
- - 🐛 **Bug Reports** - Please report bugs with reproducible examples
594
- - 📖 **Documentation** - Improvements to documentation are always appreciated
595
-
596
622
  ## API Documentation
597
623
 
598
624
  For detailed API documentation, please refer to the comprehensive documentation sections:
@@ -605,33 +631,6 @@ For detailed API documentation, please refer to the comprehensive documentation
605
631
  - Data Validation
606
632
  - Conditional Formatting
607
633
  - File I/O
608
- - [PDF Export](src/modules/pdf/README.md)
609
-
610
- ## Contributing Guidelines
611
-
612
- Contributions are welcome! Please feel free to submit a Pull Request.
613
-
614
- ### Before Submitting a PR
615
-
616
- 1. **Bug Fixes**: Add a unit-test or integration-test (in `src/**/__tests__`) that reproduces the issue
617
- 2. **New Features**: Open an issue first to discuss the feature and implementation approach
618
- 3. **Documentation**: Update relevant documentation and type definitions
619
- 4. **Code Style**: Follow the existing code style and pass all linters (`npm run lint`)
620
- 5. **Tests**: Ensure all tests pass (`npm test`) and add tests for new functionality
621
-
622
- ### Important Notes
623
-
624
- - **Version Numbers**: Please do not modify package version in PRs. Versions are managed through releases.
625
- - **License**: All contributions will be included under the project's MIT license
626
- - **Commit Messages**: Write clear, descriptive commit messages
627
-
628
- ### Getting Help
629
-
630
- If you need help or have questions:
631
-
632
- - 📖 Check existing [issues](https://github.com/cjnoname/excelts/issues) and [documentation](https://github.com/cjnoname/excelts)
633
- - 💬 Open a [new issue](https://github.com/cjnoname/excelts/issues/new) for discussion
634
- - 🐛 Use issue templates for bug reports
635
634
 
636
635
  ## License
637
636
 
package/README_zh.md CHANGED
@@ -9,10 +9,19 @@
9
9
  ExcelTS 是零依赖的 TypeScript 电子表格与文档工具包:
10
10
 
11
11
  - 🚀 **零运行时依赖** — 纯 TypeScript 实现,无任何外部包依赖
12
- - 📦 **五大模块** — Excel(XLSX/JSON)、PDF(独立引擎 + Excel 桥接)、CSV(RFC 4180)、Archive(ZIP/TAR)、Stream(跨平台)
12
+ - 📦 **六大模块** — Excel(XLSX/JSON)、PDF(独立引擎 + Excel 桥接)、CSV(RFC 4180)、XML(SAX/DOM/Writer)、Archive(ZIP/TAR)、Stream(跨平台)
13
+ - 🤖 **AI 最佳伴侣** — 简洁一致的 API 设计,让 AI 编程助手更容易生成处理各种文件的代码——一个库搞定 Excel、PDF、CSV、XML、ZIP 和流式处理,保持最高效率
13
14
  - ✅ **跨平台** — Node.js 22+、Bun、Chrome 89+、Firefox 102+、Safari 14.1+
14
15
  - ✅ **ESM 优先** — 原生 ES Modules,兼容 CommonJS,完整 tree-shaking 支持
15
16
 
17
+ ## 模块文档
18
+
19
+ - [XML 模块](src/modules/xml/README.md) — 零依赖 SAX/DOM 解析器、查询引擎和双模式写入器
20
+ - [PDF 模块](src/modules/pdf/README.md) — 零依赖 PDF 引擎,支持加密和字体嵌入
21
+ - [CSV 模块](src/modules/csv/README.md) — RFC 4180 解析/格式化、流式处理、数据生成
22
+ - [归档模块](src/modules/archive/README.md) — ZIP/TAR 创建/读取/编辑、压缩、加密
23
+ - [流模块](src/modules/stream/README.md) — 跨平台 Readable/Writable/Transform/Duplex
24
+
16
25
  ## 翻译
17
26
 
18
27
  - [English Documentation](README.md)
@@ -126,6 +135,9 @@ ExcelTS 提供独立模块的子路径导出:
126
135
  // 主入口 - Excel 核心(Workbook, Worksheet, Cell 等)
127
136
  import { Workbook, WorkbookWriter } from "@cj-tech-master/excelts";
128
137
 
138
+ // XML 工具包(SAX 解析器、DOM 解析器、查询引擎、写入器)
139
+ import { SaxParser, parseXml, XmlWriter, query } from "@cj-tech-master/excelts/xml";
140
+
129
141
  // ZIP/TAR 归档工具
130
142
  import { zip, unzip, ZipArchive, compress } from "@cj-tech-master/excelts/zip";
131
143
 
@@ -136,12 +148,7 @@ import { parseCsv, formatCsv, CsvParserStream } from "@cj-tech-master/excelts/cs
136
148
  import { Readable, pipeline, createTransform } from "@cj-tech-master/excelts/stream";
137
149
  ```
138
150
 
139
- 每个子路径支持 `browser`、`import`(ESM)和 `require`(CJS)条件。详见各模块文档:
140
-
141
- - [PDF 模块](src/modules/pdf/README.md) - 零依赖 Excel 转 PDF,支持加密和字体嵌入
142
- - [CSV 模块](src/modules/csv/README.md) - RFC 4180 解析/格式化、流式处理、数据生成
143
- - [归档模块](src/modules/archive/README.md) - ZIP/TAR 创建/读取/编辑、压缩、加密
144
- - [流模块](src/modules/stream/README.md) - 跨平台 Readable/Writable/Transform/Duplex
151
+ 每个子路径支持 `browser`、`import`(ESM)和 `require`(CJS)条件。
145
152
 
146
153
  ## PDF 导出
147
154
 
@@ -250,6 +257,45 @@ ExcelTS 内置 ZIP/TAR 归档工具(用于 XLSX 管线)。若直接使用归
250
257
 
251
258
  当使用非 UTF-8 编码时,可写入 Unicode Extra Field 以提升跨工具兼容性。
252
259
 
260
+ ## XML 工具包
261
+
262
+ ExcelTS 内置一个独立的、零依赖的 XML 模块,支持流式和缓冲两种解析/写入模式。它为 XLSX 管线提供底层支持,也可作为独立子路径导出使用。
263
+
264
+ ### 核心特性
265
+
266
+ - **SAX 解析器** — 事件驱动的高性能流式解析器
267
+ - **DOM 解析器** — 从字符串构建可查询的 XML 树
268
+ - **查询引擎** — 简化路径表达式(`a/b[@id='1']`、`a//c`、`a/b[0]`)
269
+ - **双模式写入** — 缓冲模式(`XmlWriter`)和流式模式(`XmlStreamWriter`)
270
+ - **完整命名空间支持** — 前缀解析、保留命名空间强制、未绑定前缀检测
271
+ - **安全加固** — 实体展开限制、嵌套深度限制、重复属性拒绝、BOM 处理
272
+
273
+ ### 快速示例
274
+
275
+ ```typescript
276
+ import { SaxParser, parseXml, XmlWriter, queryAll } from "@cj-tech-master/excelts/xml";
277
+
278
+ // SAX 流式解析
279
+ const parser = new SaxParser();
280
+ parser.on("opentag", tag => console.log(tag.name, tag.attributes));
281
+ parser.write('<root><item id="1">hello</item></root>');
282
+ parser.close();
283
+
284
+ // DOM 解析 + 查询
285
+ const doc = parseXml("<root><a><b>1</b><b>2</b></a></root>");
286
+ const items = queryAll(doc.root, "a/b"); // 所有 <b> 元素
287
+
288
+ // 写入 XML
289
+ const w = new XmlWriter();
290
+ w.openXml();
291
+ w.openNode("root");
292
+ w.leafNode("item", { id: "1" }, "hello");
293
+ w.closeNode();
294
+ console.log(w.xml);
295
+ ```
296
+
297
+ 完整 API 参考请见 [XML 模块文档](src/modules/xml/README.md)。
298
+
253
299
  ### 编辑现有 ZIP(ZipEditor)
254
300
 
255
301
  ExcelTS 也提供 ZIP 编辑器:对已有压缩包做类似文件系统的编辑,然后输出一个新的 ZIP。
@@ -530,6 +576,8 @@ import {
530
576
  // XML 工具
531
577
  xmlEncode,
532
578
  xmlDecode,
579
+ xmlEncodeAttr,
580
+ validateXmlName,
533
581
 
534
582
  // PDF 导出
535
583
  pdf, // 最简单:pdf([["A", 1], ["B", 2]]) → Uint8Array
@@ -569,28 +617,6 @@ import {
569
617
 
570
618
  浏览器端不要求必须支持 `crypto.randomUUID()`:ExcelTS 内置了 UUID v4 生成器,并会优先使用 `crypto.getRandomValues()` 作为 fallback。
571
619
 
572
- ## 维护者
573
-
574
- 本项目由 [CJ (@cjnoname)](https://github.com/cjnoname) 积极维护。
575
-
576
- ### 维护状态
577
-
578
- **积极维护中** - 本项目处于积极维护状态,重点关注:
579
-
580
- - 🔒 **安全更新** - 及时的安全补丁和依赖项更新
581
- - 🐛 **Bug 修复** - 关键 Bug 修复和稳定性改进
582
- - 📦 **依赖管理** - 保持依赖项最新且安全
583
- - 🔍 **代码审查** - 审查和合并社区贡献
584
-
585
- ### 贡献
586
-
587
- 虽然我可能没有足够的时间定期开发新功能,但**非常重视和欢迎社区贡献!**
588
-
589
- - 💡 **欢迎 Pull Request** - 我会及时审查并合并高质量的 PR
590
- - 🚀 **功能提议** - 在实现前请先开 issue 讨论新功能
591
- - 🐛 **Bug 报告** - 请提供可重现的示例报告 Bug
592
- - 📖 **文档改进** - 始终欢迎文档改进
593
-
594
620
  ## API 文档
595
621
 
596
622
  详细的 API 文档,请参考以下综合文档部分:
@@ -603,33 +629,6 @@ import {
603
629
  - 数据验证
604
630
  - 条件格式
605
631
  - 文件输入输出
606
- - [PDF 导出](src/modules/pdf/README.md)
607
-
608
- ## 贡献指南
609
-
610
- 欢迎贡献!请随时提交 Pull Request。
611
-
612
- ### 提交 PR 前
613
-
614
- 1. **Bug 修复**:在 `src/**/__tests__` 中添加能重现问题的单元测试或集成测试
615
- 2. **新功能**:先开 issue 讨论功能和实现方案
616
- 3. **文档**:更新相关文档和类型定义
617
- 4. **代码风格**:遵循现有代码风格并通过所有代码检查(`npm run lint`)
618
- 5. **测试**:确保所有测试通过(`npm test`)并为新功能添加测试
619
-
620
- ### 重要说明
621
-
622
- - **版本号**:请不要在 PR 中修改 package 版本。版本通过发布管理。
623
- - **许可证**:所有贡献都将包含在项目的 MIT 许可证下
624
- - **提交信息**:编写清晰、描述性的提交信息
625
-
626
- ### 获取帮助
627
-
628
- 如果需要帮助或有疑问:
629
-
630
- - 📖 查看现有的 [issues](https://github.com/cjnoname/excelts/issues) 和[文档](https://github.com/cjnoname/excelts)
631
- - 💬 开一个[新 issue](https://github.com/cjnoname/excelts/issues/new) 讨论
632
- - 🐛 使用 issue 模板报告 Bug
633
632
 
634
633
  ## 许可证
635
634
 
@@ -33,7 +33,7 @@ export type { CellAddress, SheetRange, Origin } from "./modules/excel/utils/addr
33
33
  export type { SheetToJSONOptions, AddJSONOptions, AddAOAOptions } from "./modules/excel/worksheet.js";
34
34
  export { dateToExcel, excelToDate } from "./utils/utils.base.js";
35
35
  export { base64ToUint8Array, uint8ArrayToBase64 } from "./utils/utils.base.js";
36
- export { xmlEncode, xmlDecode } from "./utils/utils.base.js";
36
+ export { xmlEncode, xmlDecode } from "./modules/xml/encode.js";
37
37
  export { DateParser, DateFormatter, getSupportedFormats, type DateFormat } from "./utils/datetime.js";
38
38
  export { BaseError, type BaseErrorOptions, toError, errorToJSON, getErrorChain, getRootCause } from "./utils/errors.js";
39
39
  export { concatUint8Arrays, toUint8Array, stringToUint8Array, uint8ArrayToString } from "./utils/binary.js";
@@ -48,7 +48,7 @@ export { dateToExcel, excelToDate } from "./utils/utils.base.js";
48
48
  // Base64 utilities (cross-platform)
49
49
  export { base64ToUint8Array, uint8ArrayToBase64 } from "./utils/utils.base.js";
50
50
  // XML utilities
51
- export { xmlEncode, xmlDecode } from "./utils/utils.base.js";
51
+ export { xmlEncode, xmlDecode } from "./modules/xml/encode.js";
52
52
  // Date parsing/formatting (high-performance, zero-dep)
53
53
  export { DateParser, DateFormatter, getSupportedFormats } from "./utils/datetime.js";
54
54
  // Error infrastructure
@@ -33,7 +33,7 @@ export type { CellAddress, SheetRange, Origin } from "./modules/excel/utils/addr
33
33
  export type { SheetToJSONOptions, AddJSONOptions, AddAOAOptions } from "./modules/excel/worksheet.js";
34
34
  export { dateToExcel, excelToDate } from "./utils/utils.base.js";
35
35
  export { base64ToUint8Array, uint8ArrayToBase64 } from "./utils/utils.base.js";
36
- export { xmlEncode, xmlDecode } from "./utils/utils.base.js";
36
+ export { xmlEncode, xmlDecode } from "./modules/xml/encode.js";
37
37
  export { DateParser, DateFormatter, getSupportedFormats, type DateFormat } from "./utils/datetime.js";
38
38
  export { BaseError, type BaseErrorOptions, toError, errorToJSON, getErrorChain, getRootCause } from "./utils/errors.js";
39
39
  export { concatUint8Arrays, toUint8Array, stringToUint8Array, uint8ArrayToString } from "./utils/binary.js";
@@ -44,7 +44,7 @@ export { dateToExcel, excelToDate } from "./utils/utils.base.js";
44
44
  // Base64 utilities (cross-platform)
45
45
  export { base64ToUint8Array, uint8ArrayToBase64 } from "./utils/utils.base.js";
46
46
  // XML utilities
47
- export { xmlEncode, xmlDecode } from "./utils/utils.base.js";
47
+ export { xmlEncode, xmlDecode } from "./modules/xml/encode.js";
48
48
  // Date parsing/formatting (high-performance, zero-dep)
49
49
  export { DateParser, DateFormatter, getSupportedFormats } from "./utils/datetime.js";
50
50
  // Error infrastructure
@@ -4,7 +4,7 @@
4
4
  * Cross-platform implementation.
5
5
  */
6
6
  import { EventEmitter } from "../../../utils/event-emitter.js";
7
- import { parseSax } from "../utils/parse-sax.js";
7
+ import { SaxParser } from "../../xml/sax.js";
8
8
  import { Enums } from "../enums.js";
9
9
  import { RelType } from "../xlsx/rel-type.js";
10
10
  class HyperlinkReader extends EventEmitter {
@@ -43,37 +43,43 @@ class HyperlinkReader extends EventEmitter {
43
43
  return;
44
44
  }
45
45
  try {
46
- for await (const events of parseSax(iterator)) {
47
- for (const { eventType, value } of events) {
48
- if (eventType !== "opentag") {
49
- continue;
50
- }
51
- const node = value;
52
- if (node.name !== "Relationship") {
53
- continue;
54
- }
55
- const attributes = node.attributes;
56
- if (attributes.Type !== RelType.Hyperlink) {
57
- continue;
58
- }
59
- const relationship = {
60
- type: Enums.RelationshipType.Hyperlink,
61
- rId: attributes.Id,
62
- target: attributes.Target,
63
- targetMode: attributes.TargetMode
64
- };
65
- if (emitHyperlinks) {
66
- this.emit("hyperlink", relationship);
67
- continue;
68
- }
69
- // cache mode
70
- const rId = relationship.rId;
71
- if (cachedHyperlinks && cachedHyperlinks[rId] === undefined) {
72
- this._hyperlinkCount += 1;
73
- }
74
- cachedHyperlinks[rId] = relationship;
46
+ const parser = new SaxParser({ position: false });
47
+ const decoder = new TextDecoder("utf-8", { fatal: true });
48
+ parser.on("opentag", (node) => {
49
+ if (node.name !== "Relationship") {
50
+ return;
75
51
  }
52
+ const attributes = node.attributes;
53
+ if (attributes.Type !== RelType.Hyperlink) {
54
+ return;
55
+ }
56
+ const relationship = {
57
+ type: Enums.RelationshipType.Hyperlink,
58
+ rId: attributes.Id,
59
+ target: attributes.Target,
60
+ targetMode: attributes.TargetMode
61
+ };
62
+ if (emitHyperlinks) {
63
+ this.emit("hyperlink", relationship);
64
+ return;
65
+ }
66
+ // cache mode
67
+ const rId = relationship.rId;
68
+ if (cachedHyperlinks && cachedHyperlinks[rId] === undefined) {
69
+ this._hyperlinkCount += 1;
70
+ }
71
+ cachedHyperlinks[rId] = relationship;
72
+ });
73
+ for await (const chunk of iterator) {
74
+ const chunkStr = typeof chunk === "string" ? chunk : decoder.decode(chunk, { stream: true });
75
+ parser.write(chunkStr);
76
+ }
77
+ // Flush trailing bytes (catches truncated UTF-8)
78
+ const trailing = decoder.decode();
79
+ if (trailing) {
80
+ parser.write(trailing);
76
81
  }
82
+ parser.close();
77
83
  this.emit("finished");
78
84
  }
79
85
  catch (error) {
@@ -1,4 +1,4 @@
1
- import { XmlStream } from "../utils/xml-stream.js";
1
+ import { XmlWriter } from "../../xml/writer.js";
2
2
  import { RelType } from "../xlsx/rel-type.js";
3
3
  import { colCache } from "../utils/col-cache.js";
4
4
  import { CommentXform } from "../xlsx/xform/comment/comment-xform.js";
@@ -60,13 +60,13 @@ class SheetCommentsWriter {
60
60
  }
61
61
  _writeComment(comment, index) {
62
62
  const commentXform = new CommentXform();
63
- const commentsXmlStream = new XmlStream();
64
- commentXform.render(commentsXmlStream, comment);
65
- this.commentsStream.write(commentsXmlStream.xml);
63
+ const commentsXmlWriter = new XmlWriter();
64
+ commentXform.render(commentsXmlWriter, comment);
65
+ this.commentsStream.write(commentsXmlWriter.xml);
66
66
  const vmlShapeXform = new VmlShapeXform();
67
- const vmlXmlStream = new XmlStream();
68
- vmlShapeXform.render(vmlXmlStream, comment, index);
69
- this.vmlStream.write(vmlXmlStream.xml);
67
+ const vmlXmlWriter = new XmlWriter();
68
+ vmlShapeXform.render(vmlXmlWriter, comment, index);
69
+ this.vmlStream.write(vmlXmlWriter.xml);
70
70
  }
71
71
  _writeClose() {
72
72
  this.commentsStream.write("</commentList></comments>");
@@ -1,4 +1,4 @@
1
- import { xmlEncode } from "../../../utils/utils.browser.js";
1
+ import { xmlEncode } from "../../xml/encode.js";
2
2
  import { RelType } from "../xlsx/rel-type.js";
3
3
  import { worksheetRelsPath } from "../utils/ooxml-paths.js";
4
4
  import { isInternalLink } from "../xlsx/xform/sheet/hyperlink-xform.js";
@@ -82,13 +82,13 @@ class SheetRelsWriter {
82
82
  const rId = `rId${++this.count}`;
83
83
  if (relationship.TargetMode) {
84
84
  this.stream.write(`<Relationship Id="${rId}"` +
85
- ` Type="${relationship.Type}"` +
85
+ ` Type="${xmlEncode(relationship.Type)}"` +
86
86
  ` Target="${xmlEncode(relationship.Target)}"` +
87
- ` TargetMode="${relationship.TargetMode}"` +
87
+ ` TargetMode="${xmlEncode(relationship.TargetMode)}"` +
88
88
  "/>");
89
89
  }
90
90
  else {
91
- this.stream.write(`<Relationship Id="${rId}" Type="${relationship.Type}" Target="${relationship.Target}"/>`);
91
+ this.stream.write(`<Relationship Id="${rId}" Type="${xmlEncode(relationship.Type)}" Target="${xmlEncode(relationship.Target)}"/>`);
92
92
  }
93
93
  return rId;
94
94
  }