Skip to content

Keep leading and trailing blanks of template values visible in Excel - #1030

Open
ybai08 wants to merge 1 commit into
mini-software:masterfrom
ybai08:fix/template-preserve-blank-space
Open

ybai08 wants to merge 1 commit into
mini-software:masterfrom
ybai08:fix/template-preserve-blank-space

Conversation

@ybai08

@ybai08 ybai08 commented Oct 18, 2026 •

Copy link
Copy Markdown

Fixes #295

Problem

FillTemplate turns template cells into inline strings (<is><t>…</t></is>) but never writes xml:space="preserve" on the <t>. Excel drops leading and trailing blanks from a <t> without that attribute, so a value such as " Jack" shows as Jack, even though MiniExcel reads the blanks back. Export already handles this (#294, OpenXmlWriter sets preserveSpace); the template path did not.

As noted in the issue, the template keeps the original c element, so the attribute has to be added there.

Change

A new PreserveInlineStringSpaces pass in OpenXmlTemplate.Impl.cs runs after UpdateDimensionAndGetRowsInfo in both GenerateSheetByUpdateModeAsync and GenerateSheetByCreateModeAsync. It sets xml:space="preserve" on an inline <t> when:

  • its text starts or ends with white space. By this point the single values ({{Name}}) are already filled in, so this covers them and also static text;
  • or it still holds a {{…}} placeholder. List rows ({{employees.name}}) are filled in later by string replacement on the row XML, so the value is not known yet. Marking the template cell lets every generated row inherit the attribute without touching the per-row code.

The attribute only changes how Excel treats white space at the edges of the text. Cells without such white space look the same in Excel.

Output change

List cells that hold string placeholders now always come out as <t xml:space="preserve">…</t>, even when the value has no edge blanks. Single values only get the attribute when they need it. The text MiniExcel reads back is the same. TestIssueI4DQUN checked the exact <t> markup of a list cell, so its expected string was updated to include the attribute.

Tests

  • New TestIssue295 in MiniExcelGithubIssuesTests (next to TestIssue294):
    • single values (TestTemplateEasyFill.xlsx): A2 (" Jack") and E2 (" Jack has 123 points") carry xml:space="preserve" and keep their text;
    • list values (TestTemplateBasicIEmumerableFill.xlsx): A2, B2, A3 and B3 carry the attribute, the blanks in " Jack", "HR " and " IT " are kept, and Query reads them back unchanged.
  • Without the change to OpenXmlTemplate.Impl.cs, TestIssue295 fails (Expected: "preserve", Actual: null on A2) and so does the updated TestIssueI4DQUN. With it, both pass. Dropping either condition of the new check makes TestIssue295 fail again, once on the single-value part and once on the list part.

What was run (macOS arm64, .NET SDK 10.0.401; .NET 11 is not installed, so -p:TargetFrameworks=… limited the build to installed frameworks):

  • dotnet test tests/MiniExcel.OpenXml.Tests -p:TargetFrameworks=net10.0: 504 passed, 20 failed. The same 20 tests fail without this change, all with DllNotFoundException: SQLite.Interop.dll (System.Data.SQLite has no native library for osx-arm64 here).
  • The same on net8.0: 504 passed, the same 20 SQLite failures.
  • dotnet test tests/MiniExcel.Csv.Tests -p:TargetFrameworks=net10.0: 82 passed, 4 failed, all SQLite native-library errors as well.
  • dotnet build src/MiniExcel.OpenXml for netstandard2.0, net8.0 and net10.0: no new warnings.

Not run: net9.0 and net11.0, the SQLite-backed tests, and opening the output in Excel itself. The tests check the XML that Excel reads, not what Excel displays.

Summary by CodeRabbit

  • Bug Fixes
    • Preserved leading and trailing spaces in text generated from templates, including when placeholder values contain whitespace.
    • Retained those spaces when importing the generated values.

…ini-software#295)

FillTemplate wrote inline strings without xml:space="preserve", so Excel
dropped leading and trailing blanks from filled values. Mark a <t> that
starts or ends with white space, or that still holds a list placeholder
whose value is filled in later, the way the exporter already does (mini-software#294).
@coderabbitai

coderabbitai Bot commented Oct 18, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: defaults
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 4128351d-66b4-4d52-a886-c3e175abcb68
📥 Commits

Reviewing files that changed from the base of the PR and between 40d2baa and 89ee800.

📒 Files selected for processing: 3
  • src/MiniExcel.OpenXml/Templates/OpenXmlTemplate.Impl.cs
  • tests/MiniExcel.OpenXml.Tests/Issues/MiniExcelGiteeIssuesTests.cs
  • tests/MiniExcel.OpenXml.Tests/Issues/MiniExcelGithubIssuesTests.cs

Included review availability: This review used your included allowance. Your plan provides up to 8 included reviews per hour; 7 remain after this review.

📝 Walkthrough

Template generation now marks qualifying inline string text with xml:space="preserve". Tests verify whitespace in generated XML and imported values.

Changes: Template string whitespace

Layer / File(s) Summary
Preserve inline string whitespace
src/MiniExcel.OpenXml/Templates/OpenXmlTemplate.Impl.cs, tests/MiniExcel.OpenXml.Tests/Issues/MiniExcelGithubIssuesTests.cs, tests/MiniExcel.OpenXml.Tests/Issues/MiniExcelGiteeIssuesTests.cs
Both template-generation paths mark nonempty inline text for whitespace preservation when it has leading or trailing whitespace or contains {{. Tests check the XML attribute and verify whitespace in generated and imported values.

Priority: ⬇️ Low

Estimated code review effort: 2 (Simple) | ~10 minutes

Change: Bug fix · Severity of issue fixed: Low

Suggested reviewers: michelebastione

Merge Risk: ⚪ Minimal · up to 89ee8

No confirmed issue remains that would prevent merging after normal checks.

Security architecture risk: ⚪ Minimal · up to 89ee8

The change preserves whitespace in generated spreadsheet text without adding access, privileges, or external communication. No material security risk was identified in the changed behavior.

Retained concerns
No architecture-level concerns identified.

Security review details

Security Blast Radius

  • inferred — The introduced behavior is confined to generated worksheet text metadata within existing template operations. The inspected change does not expand the caller's destination access or give template values additional authority.

Trust Boundaries and Controls

  • observed — The inspected public overloads continue to accept caller-selected input and output, create a fresh template processor, and delegate to the existing save operation. The new helper is private within an internal class rather than a newly exposed public entrypoint.

Resilience and Maintainability Implications

  • inferred — Assigning the same constant attribute is idempotent and introduces no shared state or resource ownership. Existing cancellation and serialization sequencing remain in place. Update mode already deletes the original archive entry before writing; any partial-output exposure from interruption at that stage predates this change.
Pre-merge checks: Passed 4 · Failed 1

Failed Failed checks: 1 warning

Check name Status Explanation Resolution
Docstring Coverage Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 10 functions across 3 files. Write docstrings for the functions missing them to satisfy the coverage threshold.
Passed Passed checks: 4 passed
Check name Status Explanation
Description Check Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check Passed The title clearly describes the main change: preserving leading and trailing spaces in template values when displayed in Excel.
Linked Issues check Passed Issue #295 requires leading spaces in XLSX template output to remain visible in Excel. Both template-generation modes call PreserveInlineStringSpaces after single-value updates. The pass sets `xml:s…
Out of Scope Changes check Passed The changes stay within issue #295. The implementation adds whitespace preservation for template inline strings in both existing generation paths. TestIssue295 verifies the behavior, and the `TestIs…
Full details: Linked Issues check

Explanation

Issue #295 requires leading spaces in XLSX template output to remain visible in Excel. Both template-generation modes call PreserveInlineStringSpaces after single-value updates. The pass sets xml:space="preserve" on inline text that starts or ends with whitespace and on list placeholders that are filled later. TestIssue295 verifies the XML attribute and preserved values for scalar and list templates. The changes satisfy the active coding requirement.

Full details: Out of Scope Changes check

Explanation

The changes stay within issue #295. The implementation adds whitespace preservation for template inline strings in both existing generation paths. TestIssue295 verifies the behavior, and the TestIssueI4DQUN expectation update matches the new generated XML. No unrelated production behavior or unrelated test scope is introduced.

  • Fix all pre-merge checks with AI
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Comment @coderabbitai help to get the list of available commands.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

When applying a template whitespaces at the beginning of a string get hidden in the UI

1 participant