Reading examples
Reading Excel examples, explained clearly.
Open a focused example to see the implementation path, copy-ready PHP, expected workbook behavior, and the production boundary that matters.
01Read XLSX rowsRead one worksheet into associative PHP rows while skipping empty records and enforcing a safe row limit.
EasyDirect API+
Read one worksheet into associative PHP rows while skipping empty records and enforcing a safe row limit.
MnbExcel::read()sheet()withHeaderRow()toArray()<?php
use Mnb\PHPExcel\MnbExcel;
$rows = MnbExcel::read(__DIR__ . '/fixtures/students.xlsx')
->sheet('Students')
->withHeaderRow()
->toArray([
'skip_empty_rows' => true,
'max_rows' => 5000,
]);
foreach ($rows as $row) {
echo $row['student_id'] . ': ' . $row['name'] . PHP_EOL;
}02List and select worksheetsDiscover worksheet names first, then select a sheet by name instead of relying on workbook order.
EasyDirect API+
Discover worksheet names first, then select a sheet by name instead of relying on workbook order.
MnbExcel::read()sheetNames()sheet()toArray()<?php
use Mnb\PHPExcel\MnbExcel;
$workbook = MnbExcel::read(__DIR__ . '/fixtures/sales-workbook.xlsx');
$sheetNames = $workbook->sheetNames();
print_r($sheetNames);
$orders = $workbook
->sheet('Orders')
->withHeaderRow()
->toArray();03Detect the header row automaticallyInspect a messy worksheet, report the likely header row and confidence, then read using semantic header detection.
MediumDirect API+
Inspect a messy worksheet, report the likely header row and confidence, then read using semantic header detection.
detectHeader()autoDetectHeader()headerAtPhysicalRow()toArray()<?php
use Mnb\PHPExcel\MnbExcel;
$session = MnbExcel::read(__DIR__ . '/fixtures/vendor-export.xlsx')
->sheet(1);
$detection = $session->detectHeader([
'header_detection_rows' => 30,
]);
printf(
"Header row: %d (confidence %.2f)\n",
$detection->row,
$detection->confidence
);
$rows = $session
->autoDetectHeader(sampleRows: 30, minimumConfidence: 0.45)
->toArray([
'strict_header_detection' => true,
'header_case' => 'snake',
]);04Read selected rows and columnsLimit the source range and project only required worksheet columns before converting rows to PHP arrays.
MediumDirect API+
Limit the source range and project only required worksheet columns before converting rows to PHP arrays.
range()projectColumns()withHeaderRow()selectColumns()<?php
use Mnb\PHPExcel\MnbExcel;
$rows = MnbExcel::read(__DIR__ . '/fixtures/products.xlsx')
->sheet('Products')
->range(startRow: 1, endRow: 5000, startColumn: 'A', endColumn: 'F')
->projectColumns(['A', 'B', 'F'])
->withHeaderRow()
->toArray();05Read cells, formulas, dates, and metadataRead direct cell values, ranges, calculated formulas, typed cell details, comments, hyperlinks, and worksheet metadata.
AdvancedDirect API+
Read direct cell values, ranges, calculated formulas, typed cell details, comments, hyperlinks, and worksheet metadata.
cell()rangeValues()calculatedCell()cellDetails()sheetMetadata()<?php
use Mnb\PHPExcel\MnbExcel;
$sheet = MnbExcel::read(__DIR__ . '/fixtures/finance-report.xlsx')
->sheet('Summary');
$title = $sheet->cell('B2');
$monthlyTotals = $sheet->rangeValues('D5:D16');
$calculatedTotal = $sheet->calculatedCell('D17');
$details = $sheet->cellDetails('D17');
$metadata = $sheet->sheetMetadata();
print_r([
'title' => $title,
'monthly_totals' => $monthlyTotals,
'formula' => $details->formula,
'cached_value' => $details->cachedValue,
'calculated_value' => $calculatedTotal,
'comments' => $details->comments,
'hyperlinks' => $details->hyperlinks,
'sheet_summary' => $metadata['summary'] ?? [],
]);06Inspect an XLSX workbook without materializing rowsInspect file size, encryption state, worksheet metadata, package warnings, and validation errors without converting worksheet cells into a complete PHP array.
EasyDirect API+
Inspect file size, encryption state, worksheet metadata, package warnings, and validation errors without converting worksheet cells into a complete PHP array.
MnbExcel::inspect()ReadSession::inspect()<?php
use Mnb\PHPExcel\MnbExcel;
$inspection = MnbExcel::inspect(__DIR__ . '/fixtures/orders.xlsx');
print_r([
'status' => $inspection['status'],
'file' => $inspection['file'],
'size_bytes' => $inspection['size_bytes'],
'encrypted' => $inspection['encrypted'],
'sheet_count' => count($inspection['sheets']),
'warnings' => $inspection['warnings'],
'errors' => $inspection['errors'],
]);07List worksheets and inspect their dimensionsList worksheet names directly, then inspect visibility, dimensions, declared last rows and columns, and physical row-tag counts.
EasyDirect API+
List worksheet names directly, then inspect visibility, dimensions, declared last rows and columns, and physical row-tag counts.
MnbExcel::sheetNames()MnbExcel::inspect()<?php
use Mnb\PHPExcel\MnbExcel;
$path = __DIR__ . '/fixtures/orders.xlsx';
$names = MnbExcel::sheetNames($path);
$inspection = MnbExcel::inspect($path);
print_r($names);
foreach ($inspection['sheets'] as $sheet) {
printf(
"%s: %s, dimension %s, declared row %s, row tags %s\n",
$sheet['name'],
$sheet['state'],
$sheet['dimension'] ?? 'unknown',
$sheet['declared_last_row'] ?? 'unknown',
$sheet['row_tag_count'] ?? 'unknown'
);
}08Find inspection metadata for one worksheetSelect one worksheet from the inspection result and read its dimensions, hidden rows and columns, merges, filters, and drawing flags.
MediumDirect API+
Select one worksheet from the inspection result and read its dimensions, hidden rows and columns, merges, filters, and drawing flags.
MnbExcel::inspect()ReadSession::inspect()<?php
use Mnb\PHPExcel\MnbExcel;
$inspection = MnbExcel::inspect(__DIR__ . '/fixtures/orders.xlsx');
$orders = null;
foreach ($inspection['sheets'] as $sheet) {
if ($sheet['name'] === 'Orders') {
$orders = $sheet;
break;
}
}
if ($orders === null) {
throw new RuntimeException('Orders worksheet was not found.');
}
print_r([
'dimension' => $orders['dimension'],
'declared_last_row' => $orders['declared_last_row'],
'declared_last_column' => $orders['declared_last_column'],
'row_tag_count' => $orders['row_tag_count'],
'hidden_row_count' => $orders['hidden_row_count'],
'hidden_column_count' => $orders['hidden_column_count'],
'has_merge_cells' => $orders['has_merge_cells'],
'has_auto_filter' => $orders['has_auto_filter'],
'has_drawing' => $orders['has_drawing'],
]);09Count rows without building a complete arrayStream normalized rows through the regular reader and count them without collecting the complete workbook result in memory.
MediumDirect API+
Stream normalized rows through the regular reader and count them without collecting the complete workbook result in memory.
ReadSession::countRows()MnbExcel::sheetNames()<?php
use Mnb\PHPExcel\MnbExcel;
$path = __DIR__ . '/fixtures/orders.xlsx';
$filledRows = MnbExcel::read($path)
->sheet('Orders')
->withHeaderRow()
->countRows(['skip_empty_rows' => true]);
$allSheetCounts = [];
foreach (MnbExcel::sheetNames($path) as $name) {
$allSheetCounts[$name] = MnbExcel::read($path)
->sheet($name)
->withHeaderRow()
->countRows(['skip_empty_rows' => true]);
}
print_r(compact('filledRows', 'allSheetCounts'));10Select an optional sheet or use the active sheetAccept a nullable worksheet input without hiding non-empty typos, then continue with the workbook active sheet when no value was supplied.
EasyDirect API+
Accept a nullable worksheet input without hiding non-empty typos, then continue with the workbook active sheet when no value was supplied.
ReadSession::sheetOrActive()ReadSession::sheetIfExists()ReadSession::activeSheet()<?php
$requestedSheet = trim((string) ($_GET['sheet'] ?? ''));
$session = MnbExcel::read(__DIR__ . '/fixtures/report.xlsx')
->sheetOrActive($requestedSheet)
->withHeaderRow(1);
foreach ($session->rows() as $row) {
print_r($row);
}11Check for data rows before collecting an arrayEvaluate normalized rows after header and empty-row options, then materialize the result only when data exists.
EasyDirect API+
Evaluate normalized rows after header and empty-row options, then materialize the result only when data exists.
ReadSession::isEmpty()ReadSession::hasRows()ReadSession::toArray()<?php
$session = MnbExcel::read(__DIR__ . '/fixtures/orders.xlsx')
->sheet('Orders')
->withHeaderRow(1)
->withOptions(['skip_empty_rows' => true]);
if ($session->isEmpty()) {
echo "No data rows.\n";
return;
}
$rows = $session->toArray();
foreach ($rows as $row) {
print_r($row);
}