188 lines
4.4 KiB
PHP
188 lines
4.4 KiB
PHP
<?php
|
|
/**
|
|
* PHP version 8.1
|
|
*
|
|
* Import rows from an Excel workbook into the Controls MySQL database.
|
|
*
|
|
* Usage (PowerShell):
|
|
* php scripts/import_excel_to_db.php corelab/2021-2022%20molasses%.xlsm
|
|
*
|
|
* The script expects the first row of the worksheet to hold column headers.
|
|
* Map spreadsheet column names to database columns in the $columnMap array
|
|
* below. Adjust the target table, unique key, and upsert behaviour to match
|
|
* your schema.
|
|
*
|
|
* @category Scripts
|
|
* @package ControlsRework
|
|
* @author LASUCA IT <it@lasuca.com>
|
|
* @license https://lasuca.com/ Proprietary
|
|
* @link https://lasuca.com/
|
|
*/
|
|
|
|
declare(strict_types=1);
|
|
|
|
require __DIR__ . '/../config.php';
|
|
require __DIR__ . '/../simplexlsx.class.php';
|
|
|
|
const TARGET_TABLE = 'lab_samples';
|
|
|
|
$excelPath = $argv[1] ?? null;
|
|
|
|
$columnMap = [
|
|
// 'Spreadsheet Header' => 'database_column',
|
|
'Sample Date' => 'sample_date',
|
|
'Sample ID' => 'sample_id',
|
|
'Brix' => 'brix',
|
|
'Pol' => 'pol',
|
|
'Purity' => 'purity',
|
|
];
|
|
|
|
if ($excelPath === null) {
|
|
$usage = 'Usage: php scripts/import_excel_to_db.php '
|
|
. '<path-to-excel-file> [sheetIndex]' . PHP_EOL;
|
|
fwrite(STDERR, $usage);
|
|
exit(1);
|
|
}
|
|
|
|
if (!is_file($excelPath)) {
|
|
fwrite(STDERR, "Excel file not found: {$excelPath}" . PHP_EOL);
|
|
exit(1);
|
|
}
|
|
|
|
$sheetIndex = isset($argv[2]) ? (int) $argv[2] : 0;
|
|
|
|
try {
|
|
$xlsx = SimpleXLSX::parse($excelPath);
|
|
} catch (Throwable $exception) {
|
|
fwrite(
|
|
STDERR,
|
|
'Unable to open spreadsheet: ' . $exception->getMessage() . PHP_EOL
|
|
);
|
|
exit(1);
|
|
}
|
|
|
|
$sheetNames = $xlsx->sheetNames();
|
|
if (!isset($sheetNames[$sheetIndex])) {
|
|
$sheetList = implode(', ', $sheetNames);
|
|
fwrite(
|
|
STDERR,
|
|
"Sheet index {$sheetIndex} not found. Available sheets: {$sheetList}" .
|
|
PHP_EOL
|
|
);
|
|
exit(1);
|
|
}
|
|
|
|
$rows = $xlsx->rows($sheetIndex);
|
|
if (empty($rows)) {
|
|
fwrite(STDERR, "No rows found in sheet {$sheetNames[$sheetIndex]}" . PHP_EOL);
|
|
exit(0);
|
|
}
|
|
|
|
$headers = array_map('trim', array_shift($rows));
|
|
|
|
$columnPositions = [];
|
|
foreach ($headers as $index => $header) {
|
|
if ($header === '') {
|
|
continue;
|
|
}
|
|
|
|
if (isset($columnMap[$header])) {
|
|
$columnPositions[$columnMap[$header]] = $index;
|
|
}
|
|
}
|
|
|
|
if (empty($columnPositions)) {
|
|
fwrite(STDERR, 'No mapped columns were found in the spreadsheet.' . PHP_EOL);
|
|
exit(1);
|
|
}
|
|
|
|
$pdo = new PDO(
|
|
'mysql:host=' . DB_HOST . ';dbname=' . DB_DATABASE . ';charset=utf8mb4',
|
|
DB_USER,
|
|
DB_PASSWORD,
|
|
[
|
|
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
|
|
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
|
|
]
|
|
);
|
|
|
|
$pdo->beginTransaction();
|
|
|
|
$columns = array_keys($columnPositions);
|
|
$placeholders = array_map(
|
|
static fn (string $column): string => ':' . $column,
|
|
$columns
|
|
);
|
|
|
|
$updateFragments = array_map(
|
|
static fn (string $column): string => sprintf('%1$s = VALUES(%1$s)', $column),
|
|
$columns
|
|
);
|
|
|
|
$sql = sprintf(
|
|
'INSERT INTO %s (%s) VALUES (%s) ON DUPLICATE KEY UPDATE %s',
|
|
TARGET_TABLE,
|
|
implode(', ', $columns),
|
|
implode(', ', $placeholders),
|
|
implode(', ', $updateFragments)
|
|
);
|
|
|
|
$statement = $pdo->prepare($sql);
|
|
|
|
$imported = 0;
|
|
foreach ($rows as $rowIndex => $row) {
|
|
if (!is_array($row)) {
|
|
continue;
|
|
}
|
|
|
|
$payload = [];
|
|
foreach ($columnPositions as $column => $position) {
|
|
$cellValue = $row[$position] ?? null;
|
|
|
|
if ($cellValue instanceof DateTimeInterface) {
|
|
$cellValue = $cellValue->format('Y-m-d H:i:s');
|
|
} elseif (is_numeric($cellValue)) {
|
|
$cellValue = (float) $cellValue;
|
|
} elseif ($cellValue !== null) {
|
|
$cellValue = trim((string) $cellValue);
|
|
}
|
|
|
|
$payload[':' . $column] = $cellValue === '' ? null : $cellValue;
|
|
}
|
|
|
|
$hasContent = array_filter(
|
|
$payload,
|
|
static fn ($value) => $value !== null
|
|
);
|
|
|
|
if (empty($hasContent)) {
|
|
continue;
|
|
}
|
|
|
|
try {
|
|
$statement->execute($payload);
|
|
$imported++;
|
|
} catch (Throwable $exception) {
|
|
$pdo->rollBack();
|
|
fwrite(
|
|
STDERR,
|
|
sprintf(
|
|
'Failed on spreadsheet row %d: %s%s',
|
|
$rowIndex + 2,
|
|
$exception->getMessage(),
|
|
PHP_EOL
|
|
)
|
|
);
|
|
exit(1);
|
|
}
|
|
}
|
|
|
|
$pdo->commit();
|
|
|
|
echo sprintf(
|
|
"Imported %d row(s) from sheet '%s' into %s on %s" . PHP_EOL,
|
|
$imported,
|
|
$sheetNames[$sheetIndex],
|
|
TARGET_TABLE,
|
|
DB_DATABASE
|
|
); |