Metadata-Version: 2.4
Name: msxls2xlsx
Version: 0.1.1
Summary: Convert legacy Excel XLS files to XLSX/XLSM with source preservation
Author: HuiTurn
License-Expression: MIT
Project-URL: Homepage, https://github.com/HuiTurn/xls2xlsx
Project-URL: Repository, https://github.com/HuiTurn/xls2xlsx
Project-URL: Issues, https://github.com/HuiTurn/xls2xlsx/issues
Keywords: xls,xlsx,excel,converter,biff,ooxml
Classifier: Development Status :: 3 - Alpha
Classifier: Environment :: Console
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Topic :: Office/Business :: Office Suites
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Dynamic: license-file

# xls2xlsx

`xls2xlsx` converts Excel 97–2003 `.xls` workbooks to `.xlsx` or `.xlsm`
directly from the published file-format specifications.

The distribution is named `msxls2xlsx`. The Python package and command-line
program are both named `xls2xlsx`.

The converter uses only the Python standard library at runtime. It does not
require `xlrd`, `openpyxl`, `Pillow`, `olefile`, Microsoft Excel, LibreOffice,
COM, Java, or external processes.

## Installation

```bash
python -m pip install msxls2xlsx
```

To install from source:

```bash
python -m pip install .
```

## Python API

Import `convert` for normal conversions:

```python
from xls2xlsx import convert

result = convert("input.xls", "output.xlsx")

print(result.output_path)
print(result.report.warnings)
print(result.report.statistics)
```

The converter does not overwrite existing files unless `overwrite=True` is
set. It preserves styles, VBA, and an exact copy of the source workbook by
default:

```python
result = convert(
    "input.xls",
    "output.xlsx",
    overwrite=True,
    preserve_styles=True,
    preserve_vba=True,
    preserve_source=True,
)
```

When no destination is given, a regular workbook is written as `.xlsx`. A
workbook containing VBA is written as `.xlsm` unless VBA preservation is
disabled.

### Inspect a workbook without converting it

`inspect_xls` is optional and independent of conversion. Use it when you need
to examine the BIFF version, sheet list, VBA status, or container metadata
without creating an output file:

```python
from xls2xlsx import inspect_xls

info = inspect_xls("input.xls")
print(info.to_dict())
```

## Command line

### Convert one workbook

```bash
xls2xlsx input.xls
xls2xlsx input.xls -o output.xlsx --report report.json
```

### Inspect a workbook

```bash
xls2xlsx inspect input.xls
xls2xlsx inspect input.xls --json
```

The `inspect` command is read-only and does not create an `.xlsx` or `.xlsm`
file.

### Convert a directory

```bash
xls2xlsx batch ./legacy -o ./converted
xls2xlsx batch ./legacy -o ./converted --recursive --report batch.json
```

Batch conversion:

- ignores Excel `~$` lock files;
- processes files in deterministic relative-path order;
- preserves the input directory structure under the output directory;
- isolates failures so one invalid workbook does not stop the batch;
- checks for output and report-path collisions before conversion;
- exits with status `1` when some files fail.

### Recover the original XLS file

```bash
xls2xlsx recover converted.xlsx -o recovered.xls
```

Recovery verifies the embedded file's length and SHA-256 digest. The same
operation is available through the Python API:

```python
from xls2xlsx import read_original_source, recover_original_source

stored = read_original_source("converted.xlsx")
recover_original_source("converted.xlsx", "recovered.xls")
```

### Common options

```text
--overwrite          Replace existing output and report files
--no-styles          Skip style conversion
--no-vba             Discard VBA and write an .xlsx file
--no-source-archive  Do not embed the original XLS file
--report FILE        Write a structured JSON report atomically
--json               Print structured output as JSON
--quiet              Suppress success messages
```

Exit status `0` means success, `1` means conversion failure or partial batch
failure, and `2` means invalid input or command usage.

## Conversion reports

Reports use a stable top-level structure:

```json
{
  "source": "/path/input.xls",
  "destination": "/path/output.xlsx",
  "diagnostics": [],
  "statistics": {
    "sheets": 1,
    "cells": 42,
    "vba_preserved": false,
    "source_archive_preserved": true
  }
}
```

Diagnostics have `info`, `warning`, or `error` severity. A diagnostic location
may identify a worksheet, cell, OLE stream, or BIFF offset. JSON reports are
written to a temporary file in the destination directory and then replaced
atomically.

## Source preservation and fidelity

The project provides two layers of preservation:

1. **Native conversion.** BIFF and OfficeArt content that has an OOXML
   equivalent is converted to editable `.xlsx` or `.xlsm` content.
2. **Byte-for-byte source preservation.** The complete original `.xls` file is
   embedded in a custom XML part by default, together with its file name,
   length, SHA-256 digest, and conversion report.

Recoverable source data does not mean that every runtime behavior can be
reproduced in OOXML. ActiveX events, legacy OLE activation, some combined or
3D charts, and complex grouped shapes have no exact OOXML equivalent. The
converter reports these cases and keeps the original bytes in the embedded
source archive.

Using `--no-source-archive` or `preserve_source=False` disables byte-for-byte
source recovery.

## Supported content

- Text, numbers, booleans, errors, dates, formulas, and cached formula values
- Fonts, colors, fills, borders, alignment, number formats, and protection
- Rich text, merged cells, row and column sizing, hiding, grouping, and outlines
- Sheet order and visibility, active sheets, panes, and page breaks
- Hyperlinks, comments, conditional formatting, data validation, filters, and
  print settings
- JPEG, PNG, DIB/BMP, TIFF, WMF, and EMF images
- Line, bar, area, pie, and scatter charts, including titles, legends, and series
- Basic DrawingML shapes and the original payloads of embedded OLE objects
- VBA projects and module streams in `.xlsm` output

## Format references

The implementation is based primarily on Microsoft's published
[MS-CFB](https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-cfb/53989ce4-7b05-4f8d-829b-d08d6148375b),
[MS-XLS](https://learn.microsoft.com/en-us/openspecs/office_file_formats/ms-xls/cd03cb5f-ca02-4934-a391-bb674cb8aa06),
and [MS-ODRAW](https://learn.microsoft.com/en-us/openspecs/office_file_formats/ms-odraw/8560795e-7759-4745-838f-f7f2ef2f1872)
documentation, together with the published ISO/IEC 29500 implementation notes.

## Related projects

`xls2xlsx` follows the same package and command conventions as
[doc2docx](https://github.com/HuiTurn/doc2docx) and
[ppt2pptx](https://github.com/HuiTurn/ppt2pptx):

| Distribution | Python package / CLI | Conversion |
| --- | --- | --- |
| `msdoc2docx` | `doc2docx` | DOC to DOCX |
| `msxls2xlsx` | `xls2xlsx` | XLS to XLSX/XLSM |
| `ppt2pptx` | `ppt2pptx` | PPT to PPTX |

The projects share a consistent API, CLI structure, report format, and exit
status conventions. Their conversion engines remain separate because the Word,
Excel, and PowerPoint binary formats use different data models.

## Development

Run the test suite with:

```bash
PYTHONPATH=src python -m unittest discover -s tests -v
```

The tests cover protocol parsing, formulas, styles, objects, VBA, source
recovery, structured reports, CLI workflows, isolated installation, and real
`.xls` fixtures from Apache POI. Fixture licensing information is available in
`tests/fixtures/apache-poi/`.

## License

This project is licensed under the MIT License.
