使用 PHPSpreadsheet 将多个链接添加到一个单元格
Adding multiple links to one cell using PHPSpreadsheet
我正在尝试导出网络表单收集的一些数据,并将其与每个网络表单包含的一个或多个文件相匹配。为了向后兼容,我选择的格式是 .xls 而不是 .xlsx。
我在这里和一般的互联网上了解到,如果我们使用形状或 images/thumbnails 添加超链接,那么多个链接是可能的,但我似乎无法使其与 PHPSpreadsheet 一起使用和 xls 文件。
到目前为止,我已经设法设置了指向单个单元格的超链接,但我似乎无法在绘图上使用它。
单元格的工作代码:
$coordinates = $sheet->getCellByColumnAndRow($column,$row)->getCoordinate(); // get coordinate like "A1", "B5" etc.
$sheet->setCellValueByColumnAndRow($column,$row,$cellValue); // set link text
$sheet->getStyle($coordinates)->getFont()->setUnderline('single'); // set underline like links have
$sheet->getStyle($coordinates)->getFont()->getColor()->setRGB('#0000FF'); // set default link color
$sheet->getCellByColumnAndRow($column,$row)->getHyperlink()->setUrl('http://www.test.com'); // setting url or local link
效果很好,但在我的电子表格中,如果单个用户发送了多个文件,我希望在一个单元格中有多个链接。
尝试使其适用于绘图:
// create a new drawing object
$drawing = new Drawing();
// set properties
$drawing->setName('Testname');
$drawing->setDescription('Test description');
$drawing->setPath($url); // put your path and image here
$drawing->setCoordinates($coordinates);
$drawing->setOffsetX($width);
$drawing->setHeight($height);
//$drawing->getHyperlink()->setUrl('http://www.test.com'); // error: Call to a member function setUrl() on null
//$drawing->getHyperlink()->setTooltip('tooltip works?'); // error: Call to a member function setTooltip() on null
// Connect drawn image to the spreadsheet
$drawing->setWorksheet($sheet);
图像效果很好,我可以将多个图像放在一个单元格中,但是当我尝试向每个图像添加超链接时,PHPSpreadsheet 失败了。有没有其他方法,也许是形状或其他我没有想到的东西可能会起作用?
如果使用标准 PHPSpreadsheet 无法在一个单元格内向多个形状/图像添加超链接,那么有没有办法强制一个或多个 excel 函数进入一个单元格,以某种方式实现相同的目的?
我找到了解决方法。我回答了我自己的问题以供将来参考,并希望对其他人有所帮助。 :)
解决方案是为我需要的每个额外 link 添加一个新行,并在不是 link 列的列中垂直合并所有其他单元格。这使得看似在一个单元格内创建 2 个或更多单元格而不影响其他列成为可能。例如。文件单元格需要 3 links 的一个结果将占用电子表格中的 3 行,但与该结果对应的所有其他列将单独垂直合并,使其看起来像一个文件的一行包含 3 个单元格的单元格。
由于每个单元格只能 link 个,因此需要完成以下操作:
require_once '/vendor/autoload.php';
// set folder to unzip the corresponding files
$filesFolder = 'Files';
// Create new Spreadsheet object
$spreadsheet = new Spreadsheet();
// set active sheet
$sheet = $spreadsheet->getActiveSheet();
// get form results data prepped for my .xls file
list($header, $allRows) = getResults(); // privat function setting 2x arrays with info gathered
// set headers
$sheet->fromArray([$header], NULL, 'A1');
$fileFieldIndex = 3; // the column index of the files
$counter = 2; // Start below the headers
foreach($allRows as $row => $innerArray){
// Add some data
$sheet->fromArray([$innerArray], NULL, 'A'.$counter);
// fetching fileinfo
$aFileInfo = getFileInfo(); // privat function setting 2x array with fileinfo corresponding to this specific result
// loop through and add rows for each extra file link
foreach($aFileInfo as $innerRow => $fileInfo) {
if($innerRow>=1){
// on second or more occurrence of files, add extra row
$counter++; // update counter
// Add one row starting at column 'A'
$sheet->fromArray([$innerArray], NULL, 'A'.$counter);
// set link text
$sheet->setCellValueByColumnAndRow($fileFieldIndex,$counter,$fileInfo['filename']);
// get coordinates (using only numbers to get the letter/number combination)
$coordinates = $sheet->getCellByColumnAndRow($fileFieldIndex,$counter)->getCoordinate();
// separate letter-column and number-row
preg_match_all('/(\d)|(\w)/', $coordinates, $matches);
$letterColumnFiles = implode($matches[2]);
// loop through columns
// Get the highest column letter referenced in the worksheet
$highestColumn = $sheet->getHighestColumn();
$prevRow = ($counter-1);
// stop when you reach the highest column
for ($col = 'A'; $col != $highestColumn; ++$col) {
if($col != $letterColumnFiles){
// merge cell with cell above if not the column with the files
$topCell = $col.$prevRow;
$sheet->getStyle($topCell)->getAlignment()->setVertical('top');
$sheet->mergeCells("$topCell:$col$counter");
}
}
// merge highest column too, we wouldn't want to forget this one
$sheet->getStyle($highestColumn.$prevRow)->getAlignment()->setVertical('top');
$sheet->mergeCells("$highestColumn$prevRow:$highestColumn$counter");
}
// get coordinate like "A1", "B5" etc. needed for getStyle
$coordinates = $sheet->getCellByColumnAndRow($fileFieldIndex,$counter)->getCoordinate();
// set underline like links have
$sheet->getStyle($coordinates)->getFont()->setUnderline('single');
// set default link color
$sheet->getStyle($coordinates)->getFont()->getColor()->setRGB('#0000FF');
// setting local link to specified local folder
$sheet->getCellByColumnAndRow($fileFieldIndex,$counter)->getHyperlink()->setUrl($filesFolder.'\'.$fileInfo['filename']);
}
}
我正在尝试导出网络表单收集的一些数据,并将其与每个网络表单包含的一个或多个文件相匹配。为了向后兼容,我选择的格式是 .xls 而不是 .xlsx。
我在这里和一般的互联网上了解到,如果我们使用形状或 images/thumbnails 添加超链接,那么多个链接是可能的,但我似乎无法使其与 PHPSpreadsheet 一起使用和 xls 文件。
到目前为止,我已经设法设置了指向单个单元格的超链接,但我似乎无法在绘图上使用它。
单元格的工作代码:
$coordinates = $sheet->getCellByColumnAndRow($column,$row)->getCoordinate(); // get coordinate like "A1", "B5" etc.
$sheet->setCellValueByColumnAndRow($column,$row,$cellValue); // set link text
$sheet->getStyle($coordinates)->getFont()->setUnderline('single'); // set underline like links have
$sheet->getStyle($coordinates)->getFont()->getColor()->setRGB('#0000FF'); // set default link color
$sheet->getCellByColumnAndRow($column,$row)->getHyperlink()->setUrl('http://www.test.com'); // setting url or local link
效果很好,但在我的电子表格中,如果单个用户发送了多个文件,我希望在一个单元格中有多个链接。
尝试使其适用于绘图:
// create a new drawing object
$drawing = new Drawing();
// set properties
$drawing->setName('Testname');
$drawing->setDescription('Test description');
$drawing->setPath($url); // put your path and image here
$drawing->setCoordinates($coordinates);
$drawing->setOffsetX($width);
$drawing->setHeight($height);
//$drawing->getHyperlink()->setUrl('http://www.test.com'); // error: Call to a member function setUrl() on null
//$drawing->getHyperlink()->setTooltip('tooltip works?'); // error: Call to a member function setTooltip() on null
// Connect drawn image to the spreadsheet
$drawing->setWorksheet($sheet);
图像效果很好,我可以将多个图像放在一个单元格中,但是当我尝试向每个图像添加超链接时,PHPSpreadsheet 失败了。有没有其他方法,也许是形状或其他我没有想到的东西可能会起作用?
如果使用标准 PHPSpreadsheet 无法在一个单元格内向多个形状/图像添加超链接,那么有没有办法强制一个或多个 excel 函数进入一个单元格,以某种方式实现相同的目的?
我找到了解决方法。我回答了我自己的问题以供将来参考,并希望对其他人有所帮助。 :)
解决方案是为我需要的每个额外 link 添加一个新行,并在不是 link 列的列中垂直合并所有其他单元格。这使得看似在一个单元格内创建 2 个或更多单元格而不影响其他列成为可能。例如。文件单元格需要 3 links 的一个结果将占用电子表格中的 3 行,但与该结果对应的所有其他列将单独垂直合并,使其看起来像一个文件的一行包含 3 个单元格的单元格。
由于每个单元格只能 link 个,因此需要完成以下操作:
require_once '/vendor/autoload.php';
// set folder to unzip the corresponding files
$filesFolder = 'Files';
// Create new Spreadsheet object
$spreadsheet = new Spreadsheet();
// set active sheet
$sheet = $spreadsheet->getActiveSheet();
// get form results data prepped for my .xls file
list($header, $allRows) = getResults(); // privat function setting 2x arrays with info gathered
// set headers
$sheet->fromArray([$header], NULL, 'A1');
$fileFieldIndex = 3; // the column index of the files
$counter = 2; // Start below the headers
foreach($allRows as $row => $innerArray){
// Add some data
$sheet->fromArray([$innerArray], NULL, 'A'.$counter);
// fetching fileinfo
$aFileInfo = getFileInfo(); // privat function setting 2x array with fileinfo corresponding to this specific result
// loop through and add rows for each extra file link
foreach($aFileInfo as $innerRow => $fileInfo) {
if($innerRow>=1){
// on second or more occurrence of files, add extra row
$counter++; // update counter
// Add one row starting at column 'A'
$sheet->fromArray([$innerArray], NULL, 'A'.$counter);
// set link text
$sheet->setCellValueByColumnAndRow($fileFieldIndex,$counter,$fileInfo['filename']);
// get coordinates (using only numbers to get the letter/number combination)
$coordinates = $sheet->getCellByColumnAndRow($fileFieldIndex,$counter)->getCoordinate();
// separate letter-column and number-row
preg_match_all('/(\d)|(\w)/', $coordinates, $matches);
$letterColumnFiles = implode($matches[2]);
// loop through columns
// Get the highest column letter referenced in the worksheet
$highestColumn = $sheet->getHighestColumn();
$prevRow = ($counter-1);
// stop when you reach the highest column
for ($col = 'A'; $col != $highestColumn; ++$col) {
if($col != $letterColumnFiles){
// merge cell with cell above if not the column with the files
$topCell = $col.$prevRow;
$sheet->getStyle($topCell)->getAlignment()->setVertical('top');
$sheet->mergeCells("$topCell:$col$counter");
}
}
// merge highest column too, we wouldn't want to forget this one
$sheet->getStyle($highestColumn.$prevRow)->getAlignment()->setVertical('top');
$sheet->mergeCells("$highestColumn$prevRow:$highestColumn$counter");
}
// get coordinate like "A1", "B5" etc. needed for getStyle
$coordinates = $sheet->getCellByColumnAndRow($fileFieldIndex,$counter)->getCoordinate();
// set underline like links have
$sheet->getStyle($coordinates)->getFont()->setUnderline('single');
// set default link color
$sheet->getStyle($coordinates)->getFont()->getColor()->setRGB('#0000FF');
// setting local link to specified local folder
$sheet->getCellByColumnAndRow($fileFieldIndex,$counter)->getHyperlink()->setUrl($filesFolder.'\'.$fileInfo['filename']);
}
}