styleOption = $styleOption;
if(!is_null($columns)){
$tmpColumns = [];
foreach($columns as $col){
if(str_contains($col, "-")){
$tmpColumns = array_merge($tmpColumns, ConverterHelpers::RangeToColumnArray($col));
}
else{
array_push($tmpColumns, $col);
}
}
$this->columns = $tmpColumns;
}
$this->scale = $scale;
$this->worksheet = $worksheet;
$this->html = '';
}
//statics
public static function fromSpreadsheet(Spreadsheet $spreadsheet, int $styleOption = 0, string|null $worksheetName = null, array|null $columns = null, float $scale = 1.0): HtmlConverter{
$worksheet = $spreadsheet->getSheetByName($worksheetName);
if (is_null($worksheet)){
throw new SheetNotFoudException();
}
return self::fromWorksheet($worksheet, $styleOption, $columns, $scale);
}
public static function fromWorksheet(Worksheet $worksheet, int $styleOption = 0, array|null $columns = null, float $scale = 1.0): HtmlConverter{
$instance = new self($worksheet, $styleOption, $columns, $scale);
return $instance;
}
public static function fromFilepath(string $filePath, int $styleOption = 0, string|null $worksheetName = null, array|null $columns = null, float $scale = 1.0): HtmlConverter{
$spreadsheet = HtmlConverter::getSpreadsheetFromFilepath($filePath);
return self::fromSpreadsheet($spreadsheet, $styleOption, $worksheetName, $columns, $scale);
}
//static helpers
private static function getSpreadsheetFromFilepath(string $filePath): Spreadsheet{
// init spreadsheet
$inputFileType = IOFactory::identify($filePath);
/** Create a new Reader of the type that has been identified **/
$reader = IOFactory::createReader($inputFileType);
/** Load $inputFileName to a Spreadsheet Object **/
return $reader->load($filePath);
}
//methods
public function getHtml(): string{
if(!(is_null($this->html) || $this->html == '')){
return $this->html;
}
// Get the highest row and column numbers referenced in the worksheet
$tblWidth = $this->getTableWidth();
//Get first data row
$row = $this->getFirstDataRowIndex();
$highestRow = $this->worksheet->getHighestDataRow();
ob_start();
?>
columns as $col): ?>
styleOption & StyleOptions::COLUMN_WIDTH_PROPORTIONAL) && ($this->styleOption & StyleOptions::WITH_COLUMN_WIDTH)){
$colWidth = 'width: '.($this->getColumnWidthInt($col) / $tblWidth * 100).'%;';
}
else if ($this->styleOption & StyleOptions::WITH_COLUMN_WIDTH){
$colWidth = 'width: '.$this->getColumnWidthInt($col).'px;';
}
?>
columns as $col): ?>
|
getCellValue($this->worksheet->getCell($col . $row)) ?>
|
columns);): ?>
columns[$i];
$cell = $this->worksheet->getCell($col . $row);
$colspan = $this->getColSpan($cell);
$value = $this->getCellValue($cell);
if(is_null($value))
$value = '
';
$tag = '';
$closeTag = '';
$font = $cell->getStyle()->getFont();
if ($font->getBold()){
$tag .= '';
$closeTag = '' . $closeTag;
}
else if ($font->getItalic()){
$tag .= '';
$closeTag = '' . $closeTag;
}
else if ($font->getSubscript()){
$tag .= '';
$closeTag = '' . $closeTag;
}
else if ($font->getSuperscript()){
$tag .= '';
$closeTag = '' . $closeTag;
}
?>
hasHyperlink()): ?>
|
html = ob_get_clean();
return $this->html;
}
//private methods
private function getColumnWidthInt(string $colName): float{
$width = $this->worksheet->getColumnDimension($colName)->getWidth('px');
if($width < 0){
$width = $this->worksheet->getDefaultColumnDimension()->getWidth('px');
}
if($this->worksheet->getColumnDimension($colName)->getCollapsed()){
$width = 0;
}
$colScale = 1;
if($this->scale > 1.0){
$colScale = $this->scale * 0.95;
}
return $width * $colScale;
}
private function getTableWidth(): float|int{
$colWidth = 0;
foreach ($this->columns as $col){
$colWidth += $this->getColumnWidthInt($col);
}
return $colWidth;
}
private function getFirstDataRowIndex(): int{
$highestRow = $this->worksheet->getHighestDataRow(); // e.g. 10
$minCol = min($this->columns);
$maxCol = max($this->columns);
$row = -1;
$value = null;
do {
++$row;
$array = $this->worksheet->rangeToArray($minCol.$row.':'.$maxCol.$row);
$valString = implode($array[$row]);
$value = trim($valString);
} while ($row <= $highestRow && is_null($value));
++$row;
return $row;
}
private function getCellValue(Cell $cell): string{
if($cell->isFormula()){
return trim($cell->getOldCalculatedValue());
}
return trim($cell->getFormattedValue());
}
private function getRowHeight(int $rowNumber): float{
$height = $this->worksheet->getRowDimension($rowNumber)->getRowHeight('px');
if($height < 0){
$height = $this->worksheet->getDefaultRowDimension()->getRowHeight('px');
if($height < 0){
$height = $this->worksheet->getRowDimension($rowNumber)->setRowHeight(10, 'pt')->getRowHeight('px');
}
}
if($this->worksheet->getRowDimension($rowNumber)->getZeroHeight()){
$height = 0;
}
return $height * $this->scale;
}
private function getColSpan(Cell $cell): int{
if ($cell->isInMergeRange()){
$mergeRange = explode(':', $cell->getMergeRange());
$mergeRange[1] = substr($mergeRange[1], 0, strlen($mergeRange[1]) - strlen(filter_var($mergeRange[1], FILTER_SANITIZE_NUMBER_INT)));
$mergeRange[0] = substr($mergeRange[0], 0, strlen($mergeRange[0]) - strlen(filter_var($mergeRange[0], FILTER_SANITIZE_NUMBER_INT)));
$lastCell = array_search($mergeRange[1], $this->columns);
$lastNotInCells = false;
if ($lastCell === false){
$lastNotInCells = true;
$lastCell = count($this->columns);
for($i = count($this->columns) - 1; $i >= 0; $i--){
if ((strlen($this->columns[$i]) === strlen($mergeRange[1]) && strcmp($this->columns[$i], $mergeRange[1]) <= 0) || (strlen($this->columns[$i]) < strlen($mergeRange[1]))){
$lastCell = $i;
if (strcmp($this->columns[$i], $mergeRange[1]) < 0)
$lastCell++;
break;
}
if( $i > count($this->columns))
$i = count($this->columns);
}
}
$firstCell = array_search($mergeRange[0], $this->columns);
if ($firstCell === false){
$firstCell = 0;
for($i = 0; $i < count($this->columns); $i++){
if ((strlen($this->columns[$i]) === strlen($mergeRange[0]) && strcmp($this->columns[$i], $mergeRange[0]) >= 0) || (strlen($this->columns[$i]) > strlen($mergeRange[0]))){
$firstCell = $i;
if (strcmp($this->columns[$i], $mergeRange[0]) > 0)
$firstCell--;
break;
}
}
if( $i < 0)
$i = 0;
}
if($lastCell <= $firstCell){
return 1;
}
if(!$lastNotInCells)
$lastCell+=1;
return $lastCell - $firstCell;
}
return 1;
}
private function getBackground(Cell $cell): string{
if ($cell->getStyle()->getFill()->getFillType() == null || $cell->getStyle()->getFill()->getFillType() === Fill::FILL_NONE){
return 'transparent';
}
else if ($cell->getStyle()->getFill()->getFillType() === Fill::FILL_SOLID) {
return '#'. $cell->getStyle()->getFill()->getStartColor()->getRGB();
}
return 'linear-gradient('
. $cell->getStyle()->getFill()->getRotation()
.'deg, #'
. $cell->getStyle()->getFill()->getStartColor()->getRGB()
.' 0%, #'
. $cell->getStyle()->getFill()->getEndColor()->getRGB()
.' 100%)';
}
private function getBorder(Cell $cell): string{
$styles = [
Border::BORDER_MEDIUM => 'solid 3px',
Border::BORDER_NONE => 'none',
Border::BORDER_THIN => 'solid 1px',
Border::BORDER_THICK => 'solid 5px',
];
if ($cell->isInMergeRange()){
$borders = $cell->getStyle()->getBorders();
$result = 'border-left: '. $styles[$borders->getLeft()->getBorderStyle()] .' #'. $borders->getLeft()->getColor()->getRGB() .'; /*'.$borders->getLeft()->getBorderStyle().'*/'//. $borders->getRight();
.'border-bottom: '. $styles[$borders->getBottom()->getBorderStyle()] .' #'. $borders->getBottom()->getColor()->getRGB() .'; /*'.$borders->getBottom()->getBorderStyle().'*/'//. $borders->getRight();
.'border-top: '. $styles[$borders->getTop()->getBorderStyle()] .' #'. $borders->getTop()->getColor()->getRGB() .'; /*'.$borders->getTop()->getBorderStyle().'*/';//. $borders->getRight();
$mergeRange = explode(':', $cell->getMergeRange());
$endcell = $this->worksheet->getCell($mergeRange[1]);
$endBorders = $endcell->getStyle()->getBorders();
$result .= 'border-right: '. $styles[$endBorders->getRight()->getBorderStyle()] .' #'. $endBorders->getRight()->getColor()->getRGB() .'; /*'.$borders->getRight()->getBorderStyle().'*/';//. $borders->getRight();
return $result;
}
$borders = $cell->getStyle()->getBorders();
return 'border-right: '. $styles[$borders->getRight()->getBorderStyle()] .' #'. $borders->getRight()->getColor()->getRGB() .'; /*'.$borders->getRight()->getBorderStyle().'*/'//. $borders->getRight();
.'border-left: '. $styles[$borders->getLeft()->getBorderStyle()] .' #'. $borders->getLeft()->getColor()->getRGB() .'; /*'.$borders->getLeft()->getBorderStyle().'*/'//. $borders->getRight();
.'border-bottom: '. $styles[$borders->getBottom()->getBorderStyle()] .' #'. $borders->getBottom()->getColor()->getRGB() .'; /*'.$borders->getBottom()->getBorderStyle().'*/'//. $borders->getRight();
.'border-top: '. $styles[$borders->getTop()->getBorderStyle()] .' #'. $borders->getTop()->getColor()->getRGB() .'; /*'.$borders->getTop()->getBorderStyle().'*/';//. $borders->getRight();
}
private function getAlignment(Cell $cell): string{
$alignment = $cell->getStyle()->getAlignment()->getHorizontal();
if ($alignment === Alignment::HORIZONTAL_GENERAL){
$alignment = Alignment::HORIZONTAL_LEFT;
}
return Alignment::HORIZONTAL_ALIGNMENT_FOR_HTML[$alignment];
}
private function getFontSizePt(Cell $cell): float{
return $cell->getStyle()->getFont()->getSize() * $this->scale;
}
private function getTextDecoration(Cell $cell): string{
if ($cell->getStyle()->getFont()->getUnderline() === Font::UNDERLINE_SINGLE){
return 'underline solid';
}
else{
return 'none';
}
}
}
class StyleOptions{
const WITH_COLUMN_WIDTH = 0b001;
const COLUMN_WIDTH_PROPORTIONAL = 0b010;
const TABLE_SIZE_FIXED = 0b100;
}