CSV quoting preserves field structure, but a spreadsheet may interpret a leading cell value as a formula.
Python CSV export: spreadsheet cells are an execution boundary
Operation contract
A support report includes an untrusted label beginning with =. csv.writer escapes delimiters and quotes; it does not decide whether a spreadsheet executes that cell. For a human-viewed export, this program adds a tab prefix to suspicious leading characters and quotes all fields. That changes the underlying data. Keep machine-readable interchange separate from the spreadsheet rendition. Header validation and row limits address other boundaries.
Failure and ownership boundary
Spreadsheet programs vary, and a save/reopen cycle can change how cells are interpreted. Test the actual spreadsheet used by your audience. The prefix policy applies only at the start of a cell; if a product trims whitespace or normalizes input first, do the policy after that normalization. Never claim this format is universally safe or lossless. A typed exchange format is better when clients need exact data.
Working program
import csv
import io
def spreadsheet_cell(value):
return "\t" + value if value and value[0] in "=+-@" else value
output = io.StringIO()
writer = csv.writer(output, lineterminator="\n", quoting=csv.QUOTE_ALL)
writer.writerow([spreadsheet_cell("=47+1"), spreadsheet_cell("safe-label")])
print(repr(output.getvalue()))Output
'"\t=47+1","safe-label"\n'Costs and limits
The cell scan is O(total field bytes). Maintaining two export contracts costs more than one file, but avoids silently corrupting a machine import.
Common Mistakes
- CSV quoting alone does not settle spreadsheet formula interpretation.
- No single text prefix is safe for every spreadsheet and downstream consumer.
- Do not feed altered display cells into a lossless import without a reversal contract.
Connected lessons
Python CSV imports: parse quoted fields before validating rows, Python CSV headers: reject duplicate names before row mapping, Python CSV ingestion: cap bytes, rows and fields before publication.
