Guides / Field whitespace
Keep Leading and Trailing Whitespace in JSON-to-CSV Fields
Preserve whitespace inside each JSON string, export that string unchanged, and read the CSV with trimming disabled. In the Python recipe below, use skipinitialspace=False and do not call strip() on field values. Verify character counts and code points instead of judging a padded table display.
A field value can include significant space
Our fictional fixture has a padded name, tab characters around a team name, and a field containing one ordinary space. This page concerns those characters inside string values. It does not require retaining the indentation and spacing that format the JSON document itself.
[
{
"id": "W1",
"text": " Ada "
},
{
"id": "W2",
"text": "\tOps\t"
},
{
"id": "W3",
"text": " "
}
]Whether the source intended this padding is a separate business decision. For faithful conversion, preserve it first. If a downstream contract calls for cleanup, produce a separate changed-value record rather than silently redefining the source.
Make the invisible values inspectable
| Record | Python repr | Characters | Code points |
|---|---|---|---|
| W1 | ' Ada ' | 7 | U+0020, U+0020, U+0041, U+0064, U+0061, U+0020, U+0020 |
| W2 | '\tOps\t' | 5 | U+0009, U+004F, U+0070, U+0073, U+0009 |
| W3 | ' ' | 1 | U+0020 |
We generated and executed this fixture on 2026-10-17 with Python 3.12.14. The exporter wrote three data records and two columns. Its disk read-back recovered every projected field exactly. The displayed audit comes from those original strings; the downloadable evidence includes the changed results from the counterexamples.
In this fixture the padded name has seven characters, the tab-padded value has five, and the single-space value has one. An aligned display can make all three difficult to inspect. repr(value), len(value) and ord(character) expose the specific sequence without altering it.
Two cleanup options that change our result
The default minimal-quoting CSV writer does not quote a field merely because it begins with ordinary spaces. In our comma CSV, those spaces immediately follow the delimiter. Turning on skipinitialspace=True removed the leading spaces from W1 and reduced W3 to an empty field. It did not remove the surrounding tabs in W2. Calling strip() on the recovered fields changed all three text values.
faithful = list(csv.reader(stream, skipinitialspace=False))
# Do not silently add either operation to a faithful pipeline:
changed = list(csv.reader(other_stream, skipinitialspace=True))
trimmed = [[field.strip() for field in row] for row in faithful]Python's CSV reference defines skipinitialspace as ignoring spaces immediately following a delimiter; it is not a universal whitespace cleanup switch. Quoting and the exact position of a character affect parsing. The statements here describe our exported fixture, not every possible CSV dialect or importer.
Run the independent preservation recipe
python whitespace-export.py whitespace-input.json new-whitespace.csvDownload into one folder and use Python 3.12 or later. The fixed schema requires exactly id and text, both strings. The script rejects duplicate JSON object keys, nonstandard constants and strings that cannot be encoded as UTF-8 before creating the output. It reads at most 1,000,001 bytes and rejects input over its 1,000,000-byte demonstration policy. This is a local whole-memory recipe, not a browser benchmark or resource guarantee.
Exclusive creation avoids overwriting an existing file. A write or read-back failure can leave a partial output; retain the error and use a new filename after correcting the cause. Text preservation alone does not sanitize spreadsheet formulas.
Real question: did a table display remove the leading space?
A 2017 public question about retaining leading spaces in a pandas data frame raised this concern. Its answers inspected the underlying values and found the leading space was still present. That historical example is a reason to inspect the value, not evidence that current pandas or every display preserves it.
For our own export, compare the recovered string directly with the frozen source. If the comparison passes and the code-point sequence matches, a visually aligned preview is not evidence of data loss. If the sequence differs, identify the exact transformation step. Adding spaces based on how a cell looks can introduce new errors.
Check the receiving system as well
Our exporter verifies the saved file before declaring success. A later import can still trim values, so repeat the field audit on the receiving result. Agree on whether whitespace is significant before enabling normalization. Do not turn a one-space string into an empty value merely because it looks blank.
This page handles edge whitespace, not the separate distinction between null, missing and empty fields. See Verify Every Row and Field for the broader comparison, null and missing values for source states, and semicolon CSV for a receiving delimiter contract.
Use the JSON to CSV converter for an inspectable input, or reproduce this separate local recipe and its exact character audit.