Converting an Excel workbook to JSON in Python usually means loading the .xlsx file with pandas or openpyxl, calling to_json or building a list of dicts, and writing the result to disk. The output is one JSON object per data row, where the keys come from the first row of the selected worksheet and the values come from the stored cells underneath. A 1,000-row inventory sheet becomes an array of 1,000 objects, a 50-row invoice log becomes 50 objects, and a blank cell becomes null rather than an empty string or zero. The conversion is a deliberate handoff: the workbook stays behind, the JSON becomes the new file you actually ship. The interesting questions are where the conversion runs, what the converter actually reads, and whether the JSON it produces is a faithful representation of the worksheet or a lossy simplification of it.

What Excel-to-JSON Conversion Actually Produces
JSON is a plain text representation of structured data, not a spreadsheet clone. It does not carry column widths, conditional formatting, charts, images, comments, filters, print settings, workbook protection, named ranges, or the original formula source text. Those parts of an .xlsx file are intentionally outside the export. What moves across is the structured grid: header names in row one, records below them, one JSON object per row.
Because JSON objects require unique string keys, the header row of the worksheet has to be a clean set of field names. Duplicates collapse silently, blanks become ambiguous keys, and merged header cells produce values that were never intended as field names. The right place to fix a messy header is the spreadsheet itself; a converter that invents field names would make the output harder to audit.
How Python Typically Converts Excel to JSON
Two libraries dominate the Python path. pandas is the higher-level option and is almost always the first thing a tutorial shows. openpyxl is the lower-level option that reads the OOXML file directly and gives you more control over how each cell is interpreted.
The pandas path is short and well known:
import pandas as pd df = pd.read_excel("sales.xlsx", sheet_name="Q1") records = df.to_dict(orient="records") import json; json.dump(records, open("sales.json", "w"), indent=2)
orient="records" is the parameter that produces an array of objects, the shape most APIs and JavaScript code expect. read_excel uses openpyxl under the hood for .xlsx files, so the underlying read is the same.
The openpyxl path is more explicit about reading stored values rather than formula text:
from openpyxl import load_workbook wb = load_workbook("sales.xlsx", data_only=True, read_only=True) ws = wb["Q1"] rows = ws.iter_rows(values_only=True) headers = next(rows) data = [dict(zip(headers, row)) for row in rows]
The data_only=True flag is the important one. Without it, openpyxl returns the formula string for any cell whose stored value is the result of a calculation. With it, you get the cached stored value the workbook last computed. That cached value is also what a JSON consumer will see, which is why a Python conversion of a workbook that has never been opened in Excel may export blanks for formula cells.
Where Python and Server-Based Converters Hit Limits
Both Python approaches have practical friction. pandas pulls in NumPy and several other dependencies, which makes a fresh project install noticeably heavier than a single pip install pandas suggests. openpyxl is lighter, but you still write the JSON serialization yourself and decide how to handle missing values, dates, and duplicates. Either loop adds a loop when there is more than one worksheet to export.
Hosted converters add a different kind of friction. They ask you to upload the workbook to a remote server, wait for a result, and download a file. That workflow is fine for a public sample spreadsheet and unacceptable for anything containing customer data, financial records, or anything governed by an internal data-handling policy. The server may retain a copy, may log filenames, and is almost always out of your control.
There are also shared limitations between Python and server tools worth naming explicitly:
- Formulas are not recalculated by either path; only the stored value is exported.
- Macros, external links, and embedded scripts are ignored for safety reasons.
- Dates often export as numeric serial values because neither approach knows the locale or the intended format.
- Multiple worksheets require either a loop or a separate conversion per sheet.
- A workbook with a missing, blank, or merged header row produces ambiguous JSON objects whose keys are null, None, or numbered.
For a clean export, the source worksheet needs a header row of unique non-empty field names and data rows of consistent shape. If the source is messy, the JSON will be messy too.
Export a Worksheet to JSON Locally in Your Browser
If the goal is to ship JSON without installing Python and without uploading a workbook, a local browser export is the simplest path. The Excel to JSON Converter reads one .xlsx workbook in your browser tab, selects one worksheet, and produces a JSON file you can download. The workbook is not sent to a server, queued, or retained.
- Open the Excel to JSON Converter in your browser tab.
- Choose one local .xlsx workbook no larger than 20 MB.
- Select the worksheet whose first row contains unique field names.
- Convert the worksheet to JSON and download the generated file.
- Open the JSON download and inspect the records before passing them to another system.
The first non-empty row is treated as the field-name row, and every header must be non-empty and unique. Duplicate keys would otherwise overwrite data in a JSON object, which is a silent corruption. Each following row becomes one JSON record, and empty cells become null. Stored text, number, and Boolean values are preserved as ordinary JSON values.
Before the workbook is read, the page validates the classic ZIP directory, limits the file size to 20 MB, rejects Zip64 and multi-disk packages, and bounds the declared expanded package size and entry count. Those limits reduce accidental browser memory pressure; they are not a promise that every small file is inexpensive to parse. A damaged, encrypted, oversized, or unsupported workbook stops with an error instead of producing a partial download. The selected worksheet must also stay within 100,000 addressed cells.
What the Local Export Keeps and What It Drops
JSON is a data representation, not a spreadsheet clone, and the browser export is explicit about which parts of the .xlsx file move across and which stay behind. The table below summarizes the boundary.
| Workbook element | Outcome in the JSON |
|---|---|
| Stored text, number, and Boolean cells | Preserved as ordinary JSON values |
| Empty cells | Become null |
| Header row (first non-empty) | Becomes the object keys |
| Date cells | Stay as their stored numeric value; no locale is inferred |
| Formula cells | Export their stored value only; no recalculation |
| Macros, external links, embedded scripts | Ignored |
| Charts, images, comments | Dropped |
| Conditional formatting, filters, column width | Dropped |
| Print settings, workbook protection, named ranges | Dropped |
| Other worksheets in the workbook | Not exported; one worksheet per conversion |
If a visual inspection matters before the export, open the workbook in an Excel viewer first. The export does not merge workbooks, normalize values, infer nested objects, validate a business schema, or repair formulas, and it does not guarantee that another application will interpret every JSON value the same way. Keep the original workbook as the source of record.
Validate the JSON File Before You Hand It Off
Once the JSON file is on disk, validate it before you pass it to another system. A header collision, a stray unescaped quote from a cell value, or a truncated record can produce a JSON file that parses but does not mean what the spreadsheet said. Run the file through a JSON validator to confirm it parses, then skim the first few records to confirm the keys match the headers you intended.
The JSON Validator checks whether the file is valid, reports syntax errors with line and column positions, and shows a structure diagnostic so you can see whether the top level is the array of records you expected. If the validator reports an error, the fix is usually in the source worksheet: a header with a quote in it, a trailing comma in a cell, or a header that collides with another header after whitespace normalization.
For day-to-day work, the right order is: prepare the worksheet so the header row is unique and non-empty, export one worksheet at a time, validate the JSON, and keep the original workbook beside the JSON so any later question about a value has a source of truth to point at.
Related reading: View Excel Online History Without Uploading.
Related reading: Remove Excel Link From PPT Chart: Audit the Workbook.