Commit 92f59cd2 authored by Elias Villiger's avatar Elias Villiger
Browse files

Feature #4922 Excel Import - Implement importTable/Column/Region/Mode

parent 76483cc8
Pipeline #821 passed with stage
in 1 minute and 48 seconds
......@@ -263,7 +263,6 @@ const ERROR_DOWNLOAD_FOPEN_BLOCKED = 1706;
// Excel
const ERROR_EXCEL_POSITION_ARGUMENT_EMPTY = 1800;
const ERROR_EXCEL_INVALID_COORDINATES = 1801;
const ERROR_NO_IMPORT_TABLE = 1802;
// KeyValueParser
const ERROR_KVP_VALUE_HAS_NO_KEY = 1900;
......@@ -966,7 +965,14 @@ const FE_FILE_SPLIT = 'fileSplit';
const FE_FILE_SPLIT_SVG = 'svg';
const FE_FILE_SPLIT_TABLE_NAME = 'tableNameSplit';
const FE_FILE_DOWNLOAD_BUTTON = 'downloadButton';
const FE_DATA_IMPORT = 'dataImport';
// Excel Import
const FE_IMPORT_TO_TABLE = 'importToTable';
const FE_IMPORT_TO_COLUMNS = 'importToColumns';
const FE_IMPORT_REGION = 'importRegion';
const FE_IMPORT_MODE = 'importMode';
const FE_IMPORT_MODE_APPEND = 'append';
const FE_IMPORT_MODE_REPLACE = 'replace';
const FE_IMAGE_SOURCE = 'imageSource'; // Image source for a fabric element
const FE_SQL_VALIDATE = 'sqlValidate'; // Action: Query to validate form load
......
......@@ -558,43 +558,79 @@ class Save {
return false;
}
if (isset($formElement[FE_DATA_IMPORT])) { // Import
// TODO EV
$dataImports = explode('|', $formElement[FE_DATA_IMPORT]);
foreach ($dataImports as $dataImport) {
$arr = explode(',', $dataImport);
$tableName = $arr[0];
$tabNum = 1;
$cellStart = 'A1';
if (!empty($arr[1])) {
$tabNum = $arr[1];
}
if (!empty($arr[2])) {
$cellStart = $arr[2];
}
if ($tableName == '') {
throw new UserFormException("Please specify a table name to import the data into.", ERROR_NO_IMPORT_TABLE);
if (isset($formElement[FE_IMPORT_TO_TABLE])) { // Import
// Read tmp file with Spreadsheet reader
$tmpFile = Support::extendFilename($statusUpload[FILES_TMP_NAME], UPLOAD_CACHED);
$spreadsheet = \PhpOffice\PhpSpreadsheet\IOFactory::load($tmpFile);
$tableName = $formElement[FE_IMPORT_TO_TABLE];
$regions = explode('|', $formElement[FE_IMPORT_REGION] ?? '');
$columnNames = explode(',', $formElement[FE_IMPORT_TO_COLUMNS]);
$importMode = $formElement[FE_IMPORT_MODE] ?? FE_IMPORT_MODE_APPEND;
foreach ($regions as $region) {
// region: tab, startColumn, startRow, endColumn, endRow
$region = explode(',', $region);
$tab = 1;
if (!empty($region[0])) {
$tab = $region[0];
}
$tmpFile = Support::extendFilename($statusUpload[FILES_TMP_NAME], UPLOAD_CACHED);
try {
if (is_numeric($tab)) {
$worksheet = $spreadsheet->getSheet($tab - 1); // 0-based
} else {
$worksheet = $spreadsheet->getSheetByName($tab);
if ($worksheet === null) {
throw new \PhpOffice\PhpSpreadsheet\Exception(
"No sheet with the name '$tab' could be found."
);
}
}
} catch (\PhpOffice\PhpSpreadsheet\Exception $e) {
throw new UserFormException($e->getMessage());
}
// Read tmp file with Spreadsheet reader
// Set up requested region
$columnStart = '1';
$columnEnd = \PhpOffice\PhpSpreadsheet\Cell\Coordinate::columnIndexFromString($worksheet->getHighestColumn());
$rowStart = 1;
$rowEnd = $worksheet->getHighestRow();
if (!empty($region[1])) { // startColumn
if (!is_numeric($region[1])) $region[1] = \PhpOffice\PhpSpreadsheet\Cell\Coordinate::columnIndexFromString($region[1]);
if ($region[1] >= $columnStart && $region[1] <= $columnEnd) {
$columnStart = $region[1];
}
}
if (!empty($region[3])) { // endColumn
if (!is_numeric($region[3])) $region[3] = \PhpOffice\PhpSpreadsheet\Cell\Coordinate::columnIndexFromString($region[3]);
if ($region[3] >= $columnStart && $region[3] <= $columnEnd) {
$columnEnd = $region[3];
}
}
if (!empty($region[2]) && $region[2] >= $rowStart && $region[2] <= $rowEnd) {
$rowStart = $region[2];
}
if (!empty($region[4]) && $region[4] >= $rowStart && $region[4] <= $rowEnd) {
$rowEnd = $region[4];
}
// Read the specified region
$spreadsheet = \PhpOffice\PhpSpreadsheet\IOFactory::load($tmpFile);
$worksheetData = $spreadsheet->getActiveSheet()->toArray(''); // TODO specified tab
// formatting options can be passed to toArray
//TODO: Only specified region
$columnBegin = 'A';
$columnEnd = \PhpOffice\PhpSpreadsheet\Cell\Coordinate::stringFromColumnIndex(count($worksheetData[0]));
$columnEnd++; // the first non-existing column (important for use in for loop below)
$rangeStr = \PhpOffice\PhpSpreadsheet\Cell\Coordinate::stringFromColumnIndex($columnStart) . $rowStart . ':' .
\PhpOffice\PhpSpreadsheet\Cell\Coordinate::stringFromColumnIndex($columnEnd) . $rowEnd;
$worksheetData = $worksheet->rangeToArray($rangeStr, '', true, false);
$columnDefinitionArr = [];
$columnListArr = [];
for ($column = $columnBegin; $column != $columnEnd; $column++) {
$columnDefinitionArr[] = "`$column` TEXT NOT NULL DEFAULT ''";
$columnListArr[] = "$column";
for ($column = $columnStart; $column <= $columnEnd; ++$column) {
if (!empty($columnNames[$column - $columnStart])) {
$columnName = $columnNames[$column - $columnStart];
} else {
$columnName = \PhpOffice\PhpSpreadsheet\Cell\Coordinate::stringFromColumnIndex($column);
}
$columnDefinitionArr[] = "`$columnName` TEXT NOT NULL DEFAULT ''";
$columnListArr[] = "$columnName";
}
// SQL time!
$createTableSql = "CREATE TABLE IF NOT EXISTS `$tableName` (" .
"`id` INT(11) NOT NULL AUTO_INCREMENT," .
implode(', ', $columnDefinitionArr) . ',' .
......@@ -604,10 +640,15 @@ class Save {
"ENGINE = InnoDB DEFAULT CHARSET = utf8 AUTO_INCREMENT = 0;";
$this->db->sql($createTableSql);
if ($importMode === FE_IMPORT_MODE_REPLACE) {
$this->db->sql("TRUNCATE $tableName");
$importMode = FE_IMPORT_MODE_APPEND;
}
// Import the data
foreach ($worksheetData AS $rowIndex => $row) {
$columnList = implode(',', $columnListArr);
$paramPlaceholders = str_repeat('?,', count($worksheetData[0])-1) . '?';
$paramPlaceholders = str_repeat('?,', count($worksheetData[0]) - 1) . '?';
$insertSql = "INSERT INTO `$tableName` ($columnList) VALUES ($paramPlaceholders)";
$this->db->sql($insertSql, ROW_REGULAR, $row);
}
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment