Парсинг Excel: листы, формулы, объединённые ячейки и примеры на разных языках

Разбор Excel-файлов в коде: листы, формулы, объединённые ячейки, стили и примеры чтения на Python, PHP, JavaScript и C#.

КP
Команда Parsing.agency
Сбор данных под задачи бизнеса
Опубликовано: 6 марта 2025

Excel-файлы (.xlsx, реже старый .xls) — самый частый формат, в котором бизнес присылает данные: прайс-листы, остатки, отчёты, выгрузки из учётных систем. В отличие от CSV, Excel это не текст, а структурированный документ: внутри .xlsx лежит ZIP-архив с XML-описанием листов, стилей и формул. Поэтому читать его «как строки» нельзя — нужны библиотеки, понимающие внутреннее устройство книги. Статья продолжает наш обзор парсинга документов.

Что усложняет парсинг Excel

В отличие от плоского CSV, в книге Excel несколько слоёв сложности. Во-первых, много листов — данные могут быть разнесены по вкладкам, и нужно явно выбирать нужный. Во-вторых, формулы: в ячейке может храниться как формула =B2*C2, так и её вычисленное значение, и от способа чтения зависит, что вы получите. В-третьих, объединённые ячейки, из-за которых заголовок «висит» над несколькими колонками, а в данных появляются пустые места. В-четвёртых, форматы: дата может прийти не как 2026-06-01, а как число 46184 (серийный номер даты Excel), а цена — как число с хранимым форматом валюты. Всё это нужно учитывать при извлечении.

Python

Базовый инструмент для .xlsxopenpyxl. Он даёт полный контроль над книгой: листами, ячейками, объединениями.

python
from openpyxl import load_workbook

wb = load_workbook("prices.xlsx", data_only=True)  # data_only=True → значения вместо формул
ws = wb["Прайс"]                                    # выбираем нужный лист по имени

for row in ws.iter_rows(min_row=2, values_only=True):
    sku, name, price = row[0], row[1], row[2]
    print(sku, name, price)

Обратите внимание на data_only=True: без него ячейка с формулой вернёт текст формулы, а не результат. И помните, что вычисленное значение появляется только если файл хотя бы раз открывали в Excel — openpyxl сам формулы не считает.

Когда нужен не построчный обход, а анализ — фильтры, агрегаты, объединение таблиц — берут pandas, который читает лист в DataFrame одной строкой (под капотом он использует openpyxl).

python
import pandas as pd

df = pd.read_excel("prices.xlsx", sheet_name="Прайс")
print(df[df["price"] > 3000])

# при необходимости — конвертация в CSV
df.to_csv("prices.csv", index=False, encoding="utf-8-sig")

Для старого бинарного формата .xls pandas использует отдельный движок xlrd; современные файлы .xlsx обрабатываются через openpyxl.

JavaScript / Node.js

В экосистеме JS стандарт де-факто — SheetJS (пакет xlsx). Он работает и в Node, и в браузере, читает почти любые форматы таблиц и удобно превращает лист в массив объектов.

javascript
const XLSX = require("xlsx");

const wb = XLSX.readFile("prices.xlsx");
const sheet = wb.Sheets[wb.SheetNames[0]];   // первый лист
const rows = XLSX.utils.sheet_to_json(sheet); // массив объектов по заголовкам

for (const row of rows) {
  console.log(row.sku, row.name, row.price);
}

Когда нужно не только читать, но и формировать сложные книги со стилями, подойдёт ExcelJS.

PHP

Основная библиотека — PhpSpreadsheet (преемник старой PHPExcel). Она читает и пишет .xlsx и .xls, понимает формулы и форматы.

php
<?php
require "vendor/autoload.php";
use PhpOffice\PhpSpreadsheet\IOFactory;

$spreadsheet = IOFactory::load("prices.xlsx");
$rows = $spreadsheet->getActiveSheet()->toArray(null, true, true, true);

foreach (array_slice($rows, 1) as $row) { // пропускаем заголовок
    echo $row["A"] . " — " . $row["B"] . " — " . $row["C"] . "\n";
}

Go

В Go де-факто стандарт — excelize. Он читает листы в виде строк и поддерживает формулы, стили и стриминг для больших файлов.

go
package main

import (
    "fmt"
    "github.com/xuri/excelize/v2"
)

func main() {
    f, err := excelize.OpenFile("prices.xlsx")
    if err != nil {
        panic(err)
    }
    defer f.Close()

    rows, _ := f.GetRows("Прайс")
    for _, row := range rows[1:] {
        fmt.Println(row[0], row[1], row[2])
    }
}

Практические советы

Перед написанием парсера полезно открыть файл глазами и понять его структуру: где начинаются данные (часто первые строки заняты шапкой и логотипом), есть ли объединённые ячейки в заголовках, на каком листе нужные данные. Если шапка нестандартная, проще указать парсеру стартовую строку, чем пытаться угадывать. Даты и числа лучше нормализовать сразу после чтения — привести к единому формату, потому что в одном файле они нередко записаны по-разному.

Если книги однотипны, но многолистовые, с объединёнными ячейками и формулами, а присылают их регулярно — мы настроим автоматический парсинг Excel с выгрузкой в базу или в CSV для дальнейшей обработки. Когда же отчёты приходят не в Excel, а сверстаны под печать, это уже парсинг PDF — смотрите соответствующую статью.