Я хотел бы скопировать все данные и стиль определенного диапазона в другие ячейки. например, я хочу скопировать из формата A4: I15, а затем вставить именно то, что я скопировал содержимое и стили из A16. Как мне это сделать?. это то, что я хочу скопировать:
Я знаю только скопировать данные, но не стиль и сделать это с помощью этого кода:
$cellValues = $objPHPExcel->getActiveSheet()->rangeToArray('A4:I15'); $objPHPExcel->getActiveSheet()->fromArray($cellValues, null, 'A16');
Мне нужно скопировать стили .. и данные
function copyRows(PHPExcel_Worksheet $sheet,$srcRow,$dstRow,$height,$width) { for ($row = 0; $row < $height; $row++) { for ($col = 0; $col < $width; $col++) { $cell = $sheet->getCellByColumnAndRow($col, $srcRow + $row); $style = $sheet->getStyleByColumnAndRow($col, $srcRow + $row); $dstCell = PHPExcel_Cell::stringFromColumnIndex($col) . (string)($dstRow + $row); $sheet->setCellValue($dstCell, $cell->getValue()); $sheet->duplicateStyle($style, $dstCell); } $h = $sheet->getRowDimension($srcRow + $row)->getRowHeight(); $sheet->getRowDimension($dstRow + $row)->setRowHeight($h); } foreach ($sheet->getMergeCells() as $mergeCell) { $mc = explode(":", $mergeCell); $col_s = preg_replace("/[0-9]*/", "", $mc[0]); $col_e = preg_replace("/[0-9]*/", "", $mc[1]); $row_s = ((int)preg_replace("/[AZ]*/", "", $mc[0])) - $srcRow; $row_e = ((int)preg_replace("/[AZ]*/", "", $mc[1])) - $srcRow; if (0 <= $row_s && $row_s < $height) { $merge = $col_s . (string)($dstRow + $row_s) . ":" . $col_e . (string)($dstRow + $row_e); $sheet->mergeCells($merge); } }} $objPHPExcel = PHPExcel_IOFactory::load("x.xlsx"); $sheet = $objPHPExcel->getActiveSheet(); copyRows($sheet, 1, 50, 48, 11); copyRows($sheet, 2, 7 + 5, 5, 5); copyRows($sheet, 2, 7 + 10, 5, 5);` copyRows($sheet, 2, 7 + 15, 5, 5);
Я принял ответ Прашанта и расширил его для удобства использования и добавил некоторые дополнительные функции. Это был отличный источник для начала. Но у меня отсутствовали некоторые ключевые функции для меня: выбор диапазона (например, A10: B15), а не только индексов. Взятие ячейки назначения, а не просто строка. Установка ширины столбцов назначения
Обратите внимание, что я использую PHPSpreadsheet, преемника PHPExcel. Если вы используете более старую версию, вам просто нужно обновить путь для класса Cell.
<?php /** * Copy range in PHPSpreadsheet/PHPExcel including styles **/ use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet; use PhpOffice\PhpSpreadsheet\Cell\Cell; function copyRange( Worksheet $sheet, $srcRange, $dstCell) { // Validate source range. Examples: A2:A3, A2:AB2, A27:B100 if( !preg_match('/^([AZ]+)(\d+):([AZ]+)(\d+)$/', $srcRange, $srcRangeMatch) ) { // Wrong source range return; } // Validate destination cell. Examples: A2, AB3, A27 if( !preg_match('/^([AZ]+)(\d+)$/', $dstCell, $destCellMatch) ) { // Wrong destination cell return; } $srcColumnStart = $srcRangeMatch[1]; $srcRowStart = $srcRangeMatch[2]; $srcColumnEnd = $srcRangeMatch[3]; $srcRowEnd = $srcRangeMatch[4]; $destColumnStart = $destCellMatch[1]; $destRowStart = $destCellMatch[2]; // For looping purposes we need to convert the indexes instead // Note: We need to subtract 1 since column are 0-based and not 1-based like this method acts. $srcColumnStart = Cell::columnIndexFromString($srcColumnStart) - 1; $srcColumnEnd = Cell::columnIndexFromString($srcColumnEnd) - 1; $destColumnStart = Cell::columnIndexFromString($destColumnStart) - 1; $rowCount = 0; for ($row = $srcRowStart; $row <= $srcRowEnd; $row++) { $colCount = 0; for ($col = $srcColumnStart; $col <= $srcColumnEnd; $col++) { $cell = $sheet->getCellByColumnAndRow($col, $row); $style = $sheet->getStyleByColumnAndRow($col, $row); $dstCell = Cell::stringFromColumnIndex($destColumnStart + $colCount) . (string)($destRowStart + $rowCount); $sheet->setCellValue($dstCell, $cell->getValue()); $sheet->duplicateStyle($style, $dstCell); // Set width of column, but only once per row if ($rowCount === 0) { $w = $sheet->getColumnDimensionByColumn($col)->getWidth(); $sheet->getColumnDimensionByColumn ($destColumnStart + $colCount)->setAutoSize(false); $sheet->getColumnDimensionByColumn ($destColumnStart + $colCount)->setWidth($w); } $colCount++; } $h = $sheet->getRowDimension($row)->getRowHeight(); $sheet->getRowDimension($destRowStart + $rowCount)->setRowHeight($h); $rowCount++; } foreach ($sheet->getMergeCells() as $mergeCell) { $mc = explode(":", $mergeCell); $mergeColSrcStart = Cell::columnIndexFromString(preg_replace("/[0-9]*/", "", $mc[0])) - 1; $mergeColSrcEnd = Cell::columnIndexFromString(preg_replace("/[0-9]*/", "", $mc[1])) - 1; $mergeRowSrcStart = ((int)preg_replace("/[AZ]*/", "", $mc[0])); $mergeRowSrcEnd = ((int)preg_replace("/[AZ]*/", "", $mc[1])); $relativeColStart = $mergeColSrcStart - $srcColumnStart; $relativeColEnd = $mergeColSrcEnd - $srcColumnStart; $relativeRowStart = $mergeRowSrcStart - $srcRowStart; $relativeRowEnd = $mergeRowSrcEnd - $srcRowStart; if (0 <= $mergeRowSrcStart && $mergeRowSrcStart >= $srcRowStart && $mergeRowSrcEnd <= $srcRowEnd) { $targetColStart = Cell::stringFromColumnIndex($destColumnStart + $relativeColStart); $targetColEnd = Cell::stringFromColumnIndex($destColumnStart + $relativeColEnd); $targetRowStart = $destRowStart + $relativeRowStart; $targetRowEnd = $destRowStart + $relativeRowEnd; $merge = (string)$targetColStart . (string)($targetRowStart) . ":" . (string)$targetColEnd . (string)($targetRowEnd); //Merge target cells $sheet->mergeCells($merge); } } } ?>
Пример использования:
copyRange($sheet, 'A4:B8', 'E1'); copyRange($sheet, 'A4:B8', 'A10'); copyRange($sheet, 'A4:B8', 'C17');
Примечание. Я не пробовал это с помощью одной ячейки. Но теоретически он должен работать с A1: A1
Пожалуйста, позвольте мне, если я допустил какую-либо ошибку, или не стесняйтесь редактировать ответ.