Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ public function __construct(int $ref_id, ?int $table_id = null)

/**
* @throws ilException
* @throws \PhpOffice\PhpSpreadsheet\Exception
* @throws \ILIAS\Excel\ExcelException
* @throws ilDateTimeException
*/
public function import(string $file, bool $simulate = false): array
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@

declare(strict_types=1);

use PhpOffice\PhpSpreadsheet\Cell\DataType;
use ILIAS\Excel\CellType;

class ilDclTextRecordFieldModel extends ilDclBaseRecordFieldModel
{
Expand Down Expand Up @@ -50,7 +50,7 @@ public function fillExcelExport(ilExcel $worksheet, int &$row, int &$col): void
$col += 2;
}
} else {
$worksheet->setCell($row, $col, $value, DataType::TYPE_STRING);
$worksheet->setCell($row, $col, $value, CellType::STRING);
$col++;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,16 @@

declare(strict_types=1);

use PhpOffice\PhpSpreadsheet\Cell\DataType;
use ILIAS\Excel\CellType;

class ilDclTextSelectionRecordFieldModel extends ilDclSelectionRecordFieldModel
{
/**
* @throws \PhpOffice\PhpSpreadsheet\Exception
* @throws \ILIAS\Excel\ExcelException
*/
public function fillExcelExport(ilExcel $worksheet, int &$row, int &$col): void
{
$worksheet->setCell($row, $col, $this->getExportValue(), DataType::TYPE_STRING);
$worksheet->setCell($row, $col, $this->getExportValue(), CellType::STRING);
$col++;
}
}
68 changes: 45 additions & 23 deletions components/ILIAS/Excel/classes/class.ilExcel.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@
use PhpOffice\PhpSpreadsheet\Style\Border;
use PhpOffice\PhpSpreadsheet\Cell\DataType;
use ILIAS\FileUpload\MimeType;
use ILIAS\Excel\CellType;
use ILIAS\Excel\ExcelException;

/*
* Wrapper for Microsoft Excel Import/Export (based on PHPSpreadsheet, formerPHPExcel which is deprecated)
Expand Down Expand Up @@ -63,7 +65,7 @@ class ilExcel
protected string $type;

/**
* @throws \PhpOffice\PhpSpreadsheet\Exception
* @throws ExcelException
*/
public function __construct()
{
Expand All @@ -72,7 +74,24 @@ public function __construct()
$this->lng = $DIC->language();
$this->setFormat(self::FORMAT_XML);
$this->workbook = new Spreadsheet();
$this->workbook->removeSheetByIndex(0);
$this->wrapped(fn() => $this->workbook->removeSheetByIndex(0));
}

/**
* Runs a call to the library and translates its exceptions, so they do not leave this wrapper.
*
* @template T
* @param callable(): T $call
* @return T
* @throws ExcelException
*/
private function wrapped(callable $call): mixed
{
try {
return $call();
} catch (\PhpOffice\PhpSpreadsheet\Exception $e) {
throw new ExcelException($e->getMessage(), $e->getCode(), $e);
}
}

//
Expand All @@ -81,10 +100,12 @@ public function __construct()

/**
* Loads a spreadsheet from file
*
* @throws ExcelException
*/
public function loadFromFile(string $filename): void
{
$this->workbook = IOFactory::load($filename);
$this->workbook = $this->wrapped(fn(): Spreadsheet => IOFactory::load($filename));
}

//
Expand Down Expand Up @@ -117,7 +138,7 @@ public function setFormat(string $a_format): void
/**
* Add sheet
*
* @throws \PhpOffice\PhpSpreadsheet\Exception
* @throws ExcelException
*/
public function addSheet(
string $a_name,
Expand All @@ -133,8 +154,7 @@ public function addSheet(
// see https://github.com/PHPOffice/PHPExcel/issues/79
$a_name = ilStr::shortenTextExtended($a_name, 31);

$sheet = new Worksheet($this->workbook, $a_name);
$this->workbook->addSheet($sheet);
$this->wrapped(fn() => $this->workbook->addSheet(new Worksheet($this->workbook, $a_name)));
$new_index = $this->workbook->getSheetCount() - 1;

if ($a_activate) {
Expand All @@ -145,11 +165,11 @@ public function addSheet(
}

/**
* @throws \PhpOffice\PhpSpreadsheet\Exception
* @throws ExcelException
*/
public function setActiveSheet(int $a_index): void
{
$this->workbook->setActiveSheetIndex($a_index);
$this->wrapped(fn() => $this->workbook->setActiveSheetIndex($a_index));
}


Expand Down Expand Up @@ -283,15 +303,18 @@ public function setCellByCoordinates($a_coords, $a_value): void
* @param int $a_row
* @param int $col
* @param mixed $value
* @param ?string $datatype Explicit data type, see DataType::TYPE_*
* @param CellType|string|null $datatype Explicit data type; strings are deprecated, use {@see CellType}
*/
public function setCell(
int $a_row,
int $col,
$value,
?string $datatype = null
CellType|string|null $datatype = null
): void {
$coordinate = $this->getCoordByColumnAndRow($col, $a_row);
if ($datatype instanceof CellType) {
$datatype = $datatype->value;
}

if ($datatype === DataType::TYPE_STRING) {
$this->workbook->getActiveSheet()->setCellValueExplicit(
Expand Down Expand Up @@ -437,7 +460,7 @@ protected function prepareStorage(string $a_file_name): string

/**
* Send workbook to client
* @throws \PhpOffice\PhpSpreadsheet\Writer\Exception
* @throws ExcelException
*/
public function sendToClient(string $a_file_name): void
{
Expand All @@ -456,33 +479,30 @@ public function sendToClient(string $a_file_name): void
}
$tmp_name = ilFileUtils::ilTempnam();

$writer = IOFactory::createWriter($this->workbook, $this->format);
$writer->save($tmp_name);
$this->wrapped(fn() => IOFactory::createWriter($this->workbook, $this->format)->save($tmp_name));

ilFileDelivery::deliverFileAttached($tmp_name, $a_file_name, $a_mime_type, true);
}

/**
* Save workbook to file
*
* @throws \PhpOffice\PhpSpreadsheet\Writer\Exception
* @throws ExcelException
*/
public function writeToFile(string $a_file): void
{
$a_file = $this->prepareStorage($a_file);

$writer = IOFactory::createWriter($this->workbook, $this->format);
$writer->save($a_file);
$this->wrapped(fn() => IOFactory::createWriter($this->workbook, $this->format)->save($a_file));
}

/**
* @throws \PhpOffice\PhpSpreadsheet\Writer\Exception
* @throws ExcelException
*/
public function writeToTmpFile(): string
{
$writer = IOFactory::createWriter($this->workbook, $this->format);
$filename = ilFileUtils::ilTempnam();
$writer->save($filename);
$this->wrapped(fn() => IOFactory::createWriter($this->workbook, $this->format)->save($filename));

return $filename;
}
Expand Down Expand Up @@ -560,15 +580,17 @@ public function getCoordByColumnAndRow(
}

/**
* @throws \PhpOffice\PhpSpreadsheet\Exception
* @throws ExcelException
*/
public function addLink(
int $a_row,
int $a_column,
string $a_path
): void {
$coordinate = $this->getCoordByColumnAndRow($a_column, $a_row);
$this->workbook->getActiveSheet()->getCell($coordinate)->getHyperlink()->setUrl($a_path);
$this->wrapped(
fn() => $this->workbook->getActiveSheet()->getCell($coordinate)->getHyperlink()->setUrl($a_path)
);
}

/**
Expand All @@ -582,11 +604,11 @@ public function columnIndexAdjustment(int $column): int

/**
* @param string $coordinatesRange A coordinates range string like 'A1:B5'
* @throws \PhpOffice\PhpSpreadsheet\Exception
* @throws ExcelException
*/
public function mergeCells(string $coordinatesRange): void
{
$this->workbook->getActiveSheet()->mergeCells($coordinatesRange);
$this->wrapped(fn() => $this->workbook->getActiveSheet()->mergeCells($coordinatesRange));
}

private function cleanupNonCharachters(string $string): string
Expand Down
32 changes: 32 additions & 0 deletions components/ILIAS/Excel/src/CellType.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?php

/**
* This file is part of ILIAS, a powerful learning management system
* published by ILIAS open source e-Learning e.V.
*
* ILIAS is licensed with the GPL-3.0,
* see https://www.gnu.org/licenses/gpl-3.0.en.html
* You should have received a copy of said license along with the
* source code, too.
*
* If this is not the case or you just want to try ILIAS, you'll find
* us at:
* https://www.ilias.de
* https://github.com/ILIAS-eLearning
*
*********************************************************************/

declare(strict_types=1);

namespace ILIAS\Excel;

/**
* Explicit data type of a cell, see {@see \ilExcel::setCell()}.
*/
enum CellType: string
{
case STRING = 's';
case NUMERIC = 'n';
case BOOL = 'b';
case FORMULA = 'f';
}
28 changes: 28 additions & 0 deletions components/ILIAS/Excel/src/ExcelException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?php

/**
* This file is part of ILIAS, a powerful learning management system
* published by ILIAS open source e-Learning e.V.
*
* ILIAS is licensed with the GPL-3.0,
* see https://www.gnu.org/licenses/gpl-3.0.en.html
* You should have received a copy of said license along with the
* source code, too.
*
* If this is not the case or you just want to try ILIAS, you'll find
* us at:
* https://www.ilias.de
* https://github.com/ILIAS-eLearning
*
*********************************************************************/

declare(strict_types=1);

namespace ILIAS\Excel;

/**
* Thrown by {@see \ilExcel} when the spreadsheet cannot be created, read or written.
*/
class ExcelException extends \RuntimeException
{
}
Original file line number Diff line number Diff line change
Expand Up @@ -63,4 +63,26 @@ public function testCoordByColumnAndRow(): void
$excel->getCoordByColumnAndRow(2, 2)
);
}

public function testExceptionsOfTheLibraryAreTranslated(): void
{
$excel = new ilExcel();
$excel->addSheet('first');

try {
$excel->setActiveSheet(5);
$this->fail('No exception thrown for a missing sheet.');
} catch (\ILIAS\Excel\ExcelException $e) {
$this->assertInstanceOf(\PhpOffice\PhpSpreadsheet\Exception::class, $e->getPrevious());
}
}

public function testExplicitStringDataTypeKeepsNumericText(): void
{
$excel = new ilExcel();
$excel->addSheet('first');
$excel->setCell(1, 0, '007', \ILIAS\Excel\CellType::STRING);

$this->assertSame('007', $excel->getCell(1, 0));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ public function isStateless(): bool
/**
* run the job
* @throws \ILIAS\BackgroundTasks\Exceptions\InvalidArgumentException
* @throws \PhpOffice\PhpSpreadsheet\Exception
* @throws \ILIAS\Excel\ExcelException
* @throws ilDatabaseException
* @throws ilExerciseException
* @throws ilObjectNotFoundException
Expand Down Expand Up @@ -186,7 +186,7 @@ public function getExpectedTimeOfTaskInSeconds(): int

/**
* Set the Excel column titles.
* @throws \PhpOffice\PhpSpreadsheet\Exception
* @throws \ILIAS\Excel\ExcelException
*/
protected function addColumnTitles(): void
{
Expand Down Expand Up @@ -282,7 +282,7 @@ protected function isExcelNeeded(int $a_ass_type, bool $a_has_fbk): bool

/**
* Add criteria data to the excel.
* @throws \PhpOffice\PhpSpreadsheet\Exception
* @throws \ILIAS\Excel\ExcelException
*/
protected function addCriteriaToExcel(
int $feedback_giver,
Expand Down Expand Up @@ -442,7 +442,7 @@ public function addLink(
* write assignment data to excel file
* @todo Refactoring needed, long method...
* @param int $assignment_id
* @throws \PhpOffice\PhpSpreadsheet\Exception
* @throws \ILIAS\Excel\ExcelException
* @throws ilDatabaseException
* @throws ilExerciseException
* @throws ilObjectNotFoundException
Expand Down Expand Up @@ -483,7 +483,7 @@ protected function collectAssignmentData(int $assignment_id): void
}

if ($this->isExcelNeeded($assignment_type, $ass_has_feedback)) {
// PhpSpreadsheet object
// spreadsheet
$this->excel = new ilExcel();

//Excel sheet title
Expand Down
2 changes: 1 addition & 1 deletion components/ILIAS/Exercise/classes/class.ilObjExercise.php
Original file line number Diff line number Diff line change
Expand Up @@ -614,7 +614,7 @@ public function updateAllUsersStatus(): void

/**
* Exports grades as excel
* @throws \PhpOffice\PhpSpreadsheet\Exception
* @throws \ILIAS\Excel\ExcelException
* @throws ilExcUnknownAssignmentTypeException
*/
public function exportGradesExcel(): void
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -425,7 +425,7 @@ public function exportCumulatedResults(
/**
* Export details (excel only)
* @param ilSurveyEvaluationResults|array $a_results
* @throws \PhpOffice\PhpSpreadsheet\Exception
* @throws \ILIAS\Excel\ExcelException
*/
protected function exportResultsDetailsExcel(
ilExcel $a_excel,
Expand Down
Loading
Loading