You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit 7181b55
Browse filesBrowse the repository at this point in the historyBrowse files
Copy file name to clipboardExpand all lines: README.md
+8-1Lines changed: 8 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -294,7 +294,7 @@ let count = MiniExcel::insert(
294
294
assert_eq!(count, 1);
295
295
```
296
296
297
-
`insert_with_schema()` accepts a fallible, one-pass dynamic iterator. Source rows are disk-spooled and the constant-memory backend retains only the current row while generating the donor workbook; style rebasing currently materializes the generated worksheet XML. `insert_serialized()` accepts Serde structs. Existing unrelated ZIP entries, worksheet identities, formulas, and cached values are preserved, and an existing workbook is replaced only after the rewritten package validates and syncs.
297
+
`insert_with_schema()` accepts a fallible, one-pass dynamic iterator. Source rows and generated donor worksheet XML are disk-spooled; row generation, shared-string conversion, style-ID rebasing, and ZIP output are streamed without retaining the complete worksheet XML. `insert_serialized()` accepts Serde structs. Existing unrelated ZIP entries, worksheet identities, formulas, and cached values are preserved, and an existing workbook is replaced only after the rewritten package validates and syncs.
298
298
299
299
For separate borrowed streams, use `insert_from_reader_to_writer()`,
300
300
`insert_with_schema_from_reader_to_writer()`, or
@@ -307,6 +307,13 @@ or post-write validation guarantee.
307
307
308
308
The default `ExistingSheetPolicy::Reject` rejects duplicate worksheet names case-insensitively. Use `ExistingSheetPolicy::Replace` to replace a worksheet in place while preserving its workbook order, ID, relationship/path, visibility, and active state. The default `TargetRelationshipPolicy::Reject` accepts only a plain target with no worksheet relationships. `RemoveSupported` can remove target-owned tables, drawings with exclusively owned images, comments, VML drawings, and external hyperlinks; pivots, external links, unknown relationships, and shared/global parts are rejected or preserved conservatively. Insert writes XLSX packages, rejects macro-enabled `.xlsm` paths, and rejects `WriteOptions::with_overwrite_file(true)` because workbook replacement is controlled by the insert policy.
309
309
310
+
Insert preflight limits package entry count, individual and aggregate control XML, XML attribute
311
+
size, XML depth, and relationship count. It rejects unsafe or aliased part paths, internal
Insert holds a cross-process advisory lock and verifies a source SHA-256 fingerprint before commit;
314
+
concurrent writers or external source changes return a deterministic conflict instead of silently
315
+
overwriting newer content.
316
+
310
317
Appending a formula-free worksheet preserves an existing calculation chain and workbook calculation properties. Replacement removes the complete stale `calcChain` part, relationship, and content-type override, then sets `fullCalcOnLoad` and `forceFullCalc` so Excel recalculates on the next open. MiniExcel does not evaluate or rewrite formulas; formulas and cached values in untouched worksheets remain byte-identical.
Copy file name to clipboardExpand all lines: docs/compatibility.md
+2-1Lines changed: 2 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -11,6 +11,7 @@ The Rust MVP implements the smallest useful MiniExcel-style XLSX read/write surf
11
11
| Dependency | Locked API line | Role | License | MSRV note |
12
12
| --- | --- | --- | --- | --- |
13
13
|`atomicwrites`| 0.4 | Safe cross-platform atomic replacement for Windows path inserts | MIT | Windows-only dependency; checked with Rust 1.85 |
14
+
|`fs2`| 0.4 | Cross-platform advisory locking for path inserts | MIT OR Apache-2.0 | Checked with Rust 1.85 |
14
15
|`calamine`| 0.35 | XLSX parsing and Serde row deserialization | MIT | 0.35 declares Rust 1.83 |
15
16
|`clap`| 4.6 | Local CLI argument parsing | MIT OR Apache-2.0 | 4.6 declares Rust 1.85 |
16
17
|`rust_xlsxwriter`| 0.96 | New XLSX workbook generation and Serde serialization | MIT OR Apache-2.0 | 0.96 declares Rust 1.83 |
@@ -114,7 +115,7 @@ Path RAG exports retain parser state, repeated header context, and one output ch
114
115
115
116
The backend makes two sequential, bounded-memory passes over the selected worksheet entry. The first records the used extent and compact merged-cell rectangles. This is required for MiniExcel-compatible stable dynamic schemas when legal files omit `<dimension>`, to preserve style-only row elements like the .NET reader, and to support opt-in merged-cell filling without expanding ranges into an address map. The second pass emits rows and retains only anchor values for currently active merged ranges. Worksheet XML and prior rows are never retained; memory consists primarily of in-memory or disk-indexed shared strings, styles, merge metadata, parser buffers, the current row, and the bounded channel.
116
117
117
-
The internal writer assembles a new ZIP package with one or more worksheets. Path saves refuse existing files by default and can explicitly replace them. Path Insert APIs append or replace a worksheet through a validated package rewrite and atomic sibling-file replacement; unchanged ZIP entries and existing worksheet identities are preserved. Separate borrowed Insert APIs accept `Read + Seek` input and an empty `Write + Seek` output, leave both open, and preserve the same package behavior without atomic commit, rollback, or post-write validation. Fallible explicit-schema producers are consumed once through a disk spool and a constant-memory worksheet writer, while the generated donor worksheet XML is materialized for style rebasing. Template fills rewrite worksheet XML within a copied package; worksheet styles and unrelated ZIP parts are retained. Array expansion shifts row and cell addresses and updates the worksheet dimension. Formula expressions are preserved but not recalculated, and version 1 does not adjust formula references, merged ranges, tables, drawings, or defined names after inserted rows.
118
+
The internal writer assembles a new ZIP package with one or more worksheets. Path saves refuse existing files by default and can explicitly replace them. Path Insert APIs append or replace a worksheet through a validated package rewrite and atomic sibling-file replacement; unchanged ZIP entries and existing worksheet identities are preserved. Separate borrowed Insert APIs accept `Read + Seek` input and an empty `Write + Seek` output, leave both open, and preserve the same package behavior without atomic commit, rollback, or post-write validation. Fallible explicit-schema producers are consumed once through a disk spool and a constant-memory worksheet writer. Generated donor worksheet XML, shared-string conversion, style-ID rebasing, and ZIP insertion use temporary-file streams, so worksheet memory is independent of row count. Path Insert also uses advisory locking and a pre-commit source fingerprint to prevent lost concurrent updates. Template fills rewrite worksheet XML within a copied package; worksheet styles and unrelated ZIP parts are retained. Array expansion shifts row and cell addresses and updates the worksheet dimension. Formula expressions are preserved but not recalculated, and version 1 does not adjust formula references, merged ranges, tables, drawings, or defined names after inserted rows.
| Named tables | Missing | Query an OpenXML table by table name (`QueryTable`), including table-specific headers and bounds. |
31
31
| DataReader and DataTable | Missing |`IDataReader`/async reader access, schema tables, typed getters, `NextResult` sheet traversal, and `DataTable` materialization. |
32
-
| Caller-owned streams | Partial | Borrowed synchronous dynamic/typed/structured visitors, metadata reads, and dynamic/schema/typed/multi-sheet writers are implemented with leave-open semantics. Borrowed lazy iterators, async streams, and template streams remain unsupported. |
32
+
| Caller-owned streams | Partial | Borrowed synchronous dynamic/typed/structured visitors, metadata reads, dynamic/schema/typed/multi-sheet writers, and separate reader-to-writer Insert are implemented with leave-open semantics. Borrowed lazy iterators, async streams, and template streams remain unsupported. |
33
33
| Async and cancellation | Missing | Async query/export/template operations, async row sources, cancellation tokens, and progress callbacks. Rust iterators are synchronous even though path reads use a worker thread. |
34
34
| General save inputs | Partial | Export from general objects/enumerables, dictionaries, `DataTable`, `IDataReader`, and async enumerables, with progress. Rust accepts dynamic or same-type Serde slices and reports per-sheet row counts. |
35
35
| Multi-sheet export | Partial | Rust creates ordered visible, hidden, and very-hidden worksheets, but does not yet accept heterogeneous Serde row types in one call. |
36
-
| Existing-workbook operations |Missing|Insert or replace a sheet, copy and add a sheet, and rename, reorder, or change visibility of sheets. Rust always creates a new XLSX package. |
36
+
| Existing-workbook operations |Partial|Rust appends or strictly replaces worksheets through atomic path APIs or separate borrowed streams, preserving unrelated package parts and worksheet identity. Copy-and-add, rename, reorder, and standalone visibility mutation remain unsupported. |
37
37
| Templates | Partial | Rust fills path/byte templates with scalar values and single-row arrays while preserving package parts. Streams, grouping, conditions, parametrized sheets, `$=` formulas, formula-reference updates, and calculation-chain handling remain unsupported. |
38
38
| Pictures and merge processing | Missing | Add anchored pictures and merge adjacent identical cells through the templater surface. Structured reads do not provide authoring parity. |
39
39
| CSV | Missing | Dynamic/typed CSV query and save, append, columns, DataReader/DataTable, delimiter/newline/encoding/quoting configuration, and CSV/XLSX conversion. |
| Public read/write boundary |`miniexcel/src/facade.rs`, `miniexcel/src/options.rs`|`src/MiniExcel.OpenXml/Api/OpenXmlImporter.cs`, `OpenXmlExporter.cs`|
53
53
| Tables | No public table API |`OpenXmlImporter.QueryTableAsync`; `tests/MiniExcel.OpenXml.Tests/Tables/`|
54
54
| DataReader/DataTable | No public tabular adapter |`OpenXmlImporter.GetDataReader`, `GetAsyncDataReader`, `QueryAsDataTableAsync`; `tests/MiniExcel.OpenXml.Tests/DataReader/`|
55
-
| Multi-sheet and workbook edits | Writer creates multiple sheets in a new workbook; existing-workbook edits remain unsupported|`OpenXmlExporter.InsertSheetAsync`, `CopyAndAddSheetAsync`, `AlterSheetAsync`; `tests/MiniExcel.OpenXml.Tests/MultipleSheets/` and `AlterSheets/`|
55
+
| Multi-sheet and workbook edits | Writer creates multiple sheets; existing workbooks support append and strict replacement with package preservation and bounded explicit-schema producers|`OpenXmlExporter.InsertSheetAsync`, `CopyAndAddSheetAsync`, `AlterSheetAsync`; `tests/MiniExcel.OpenXml.Tests/MultipleSheets/` and `AlterSheets/`|
56
56
| Templates/pictures/merges | Basic template fill implemented; advanced directives and authoring remain deferred |`src/MiniExcel.OpenXml/Api/OpenXmlTemplater.cs`; `tests/MiniExcel.OpenXml.Tests/Templates/`|
0 commit comments