Skip to main content

Recover data from XLS files that exceed the 65,536-row limit

Project description

한국어 | English

long-xls

A simple tool to recover data from XLS files that exceed the 65,536-row limit.

The XLS format is structurally limited to 65,536 rows per sheet. However, some programs — legacy reporting utils, converting tools, stock trading platform exporters, etc. — keep writing BIFF cell records past this limit. The data is physically present in the file, but most programs and libraries (Excel, pandas, xlrd) either silently truncate it or throw an error, leaving no way to read the stored data.

long-xls reads the raw BIFF binary stream, detects row-index wrap-arounds at the 65,536 boundary, and reconstructs the full dataset.

The Problem

┌─────────────────────────────────────────────────────┐
│  Your XLS file (e.g. 370,000 rows of trade data)    │
│                                                     │
│  Row 1 ............ ✓ visible in Excel              │
│  Row 65,536 ....... ✓ visible in Excel              │
│  Row 65,537 ....... ✗ INVISIBLE — data is there     │
│  Row 370,000 ...... ✗ INVISIBLE — but recoverable!  │
└─────────────────────────────────────────────────────┘

Install

pip install long-xls              # xlsx output (default)
pip install "long-xls[parquet]"   # + parquet support
pip install "long-xls[all]"       # everything

Or download a standalone executable from Releases — no Python required.

Quick Start

# Convert to xlsx (default)
long-xls data.xls

# Convert to csv
long-xls data.xls -f csv

# Convert to parquet
long-xls data.xls -f parquet

# Include a JSON schema sidecar file
long-xls data.xls --schema

# Multiple files at once
long-xls *.xls -f csv -o output/

Commands

Command Description
long-xls data.xls Convert to xlsx (default)
long-xls data.xls -f csv Convert to csv
long-xls data.xls -f parquet Convert to parquet
long-xls data.xls --schema Also write .schema.json
long-xls schema data.xls Print JSON schema to stdout
long-xls scan data.xls Quick file scan (record counts only)

Options

Option Default Description
-f, --format xlsx Output format: xlsx, csv, parquet
-o, --output-dir same as input Output directory
-e, --encoding cp949 Text encoding for string cells
-y, --force off Overwrite existing files without asking
--schema off Write a .schema.json alongside output

Python API

from long_xls import parse, parse_to_dataframe, schema_json

# Parse and inspect
sheet = parse("data.xls")
print(f"{sheet.num_data_rows:,} rows recovered")

# Get a pandas DataFrame
df, sheet = parse_to_dataframe("data.xls")

# Export schema as JSON
import json
print(json.dumps(schema_json(sheet), indent=2))

Schema Output Example

{
  "file": "data.xls",
  "file_size": 29736094,
  "encoding": "cp949",
  "num_columns": 4,
  "num_data_rows": 371700,
  "row_limit_exceeded": true,
  "wraps": {"0": 5, "1": 5, "2": 5, "3": 5},
  "columns": [
    {"index": 0, "name": "date", "type": "string", "non_null_count": 371700},
    {"index": 1, "name": "time", "type": "string", "non_null_count": 371700},
    {"index": 2, "name": "price", "type": "float", "non_null_count": 371700},
    {"index": 3, "name": "volume", "type": "integer", "non_null_count": 371700}
  ]
}

Test Files

Synthetic test files (generator included)

Run tests/generate_test_xls.py to generate long-XLS test files of various sizes. It writes raw BIFF2 records to reproduce the row wrap-around behaviour.

python tests/generate_test_xls.py
File Rows Wraps Encoding Purpose
test_100k_rows.xls 100,000 1 UTF-8 Basic recovery verification
test_200k_rows.xls 200,000 3 UTF-8 Multi-wrap verification
test_70k_cp949.xls 70,000 1 CP949 Korean encoding verification

Real-world example: Kiwoom Securities HTS chart data

Futures tick chart data exported from Kiwoom Securities HTS. Contains 371,700 rows, but Excel only shows up to 65,535. long-xls recovers the entire dataset.

  • 20240808_KOSPI200_Tick_Kiwoom.xls — 371,700 rows (5 wraps), 29.7 MB

Building a Standalone Executable

pip install pyinstaller
python build_exe.py          # produces dist/long-xls.exe (Windows)

Author

seonhwa17kim (with help from GPT-5.5, Gemini 3.5, Claude Opus 4.8)

License

MIT Copyright (c) 2026 seonhwa17kim

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

long_xls-0.1.0.tar.gz (13.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

long_xls-0.1.0-py3-none-any.whl (12.9 kB view details)

Uploaded Python 3

File details

Details for the file long_xls-0.1.0.tar.gz.

File metadata

  • Download URL: long_xls-0.1.0.tar.gz
  • Upload date:
  • Size: 13.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.2

File hashes

Hashes for long_xls-0.1.0.tar.gz
Algorithm Hash digest
SHA256 b05a1ea3b2030b5a4c4f7d95830a00404e9cdc2cb3fd182222929492a15bd359
MD5 92c11012d03e18244ffe167b54dedbe9
BLAKE2b-256 53df36283f1258649f2aaed2642439d2d87c17fe25fe7a0c1f0c876d1ed2d08c

See more details on using hashes here.

File details

Details for the file long_xls-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: long_xls-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 12.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.2

File hashes

Hashes for long_xls-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 25f5f8b406a5f8b9d9e9fb3fa97c74836c3e22b3ebf29ab3ed0e73d27ac91877
MD5 968e018a76482b95cf9c45a5db45c3bf
BLAKE2b-256 28b97c12812eb068bc6d33e592aaf2449b5c687b7cea283d83caefc3632cbda0

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page