I wouldn't normally answer my own question but given that Google are closing off the v3 Sheets API in March 2020 I suspect others may come across this problem.
As I have mentioned in comments against the original question there is no existing means in the v4 API of accessing Cell Formats. Therefore there is no option to loop through one range and apply formats to another.
My workaround solution is to copy / paste the preceding row (the default PASTE_NORMAL will copy all values, formulas, formats, and merges https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets/request#pastetype) and then overwrite the newly pasted row with the required values. This gives me the required values with the existing formatting in the new row:-
$sheetId = null;
$worksheetSheets = $this->spreadsheetService->spreadsheets->get($this->spreadsheetId)->sheets;
foreach($worksheetSheets as $sheet){
$sheetTitle = $sheet->properties['title'];
if ($sheetTitle === $this->worksheetTitle){
$sheetId = $sheet->properties['sheetId'];
break;
}
}
$copyRange = new Google_Service_Sheets_GridRange();
$copyRange->setSheetId($sheetId);
$copyRange->setStartRowIndex($nextRow - 2);
$copyRange->setEndRowIndex($nextRow - 1);
$copyRange->setStartColumnIndex(0);
$copyRange->setEndColumnIndex(400);
$pasteRange = new Google_Service_Sheets_GridRange();
$pasteRange->setSheetId($sheetId);
$pasteRange->setStartRowIndex($nextRow - 1);
$pasteRange->setEndRowIndex($nextRow);
$pasteRange->setStartColumnIndex(0);
$pasteRange->setEndColumnIndex(400);
$copypasteRequest = new Google_Service_Sheets_CopyPasteRequest();
$copypasteRequest->setSource($copyRange);
$copypasteRequest->setDestination($pasteRange);
//$copypasteRequest->pasteType(CopyPasteType.PASTE_NORMAL);
$request = new Google_Service_Sheets_Request();
$request-> setCopyPaste($copypasteRequest);
$batchUpdateRequest = new Google_Service_Sheets_BatchUpdateSpreadsheetRequest();
$batchUpdateRequest->setRequests($request);
// Need to check if sheet has an existing empty row to paste into
$finalRowRange = $this->worksheet['range'];
$finalRowStartPosition = strpos($this->worksheet['range'],':') + 2;
$finalRow = intval(substr($finalRowRange,$finalRowStartPosition));
if($finalRow <= $pasteRange['startRowIndex']){ // startRowIndex is a zero based array range, i.e. 348 actually corresponds to row 349 on sheet.
$appendDimensionRequest = new Google_Service_Sheets_AppendDimensionRequest();
$appendDimensionRequest->setSheetId($sheetId);
$appendDimensionRequest->setDimension("ROWS");
$appendDimensionRequest->setLength(1);
$appendRequest = new Google_Service_Sheets_Request();
$appendRequest->setAppendDimension($appendDimensionRequest);
$appendEmptyRowBatchUpdateRequest = new Google_Service_Sheets_BatchUpdateSpreadsheetRequest();
$appendEmptyRowBatchUpdateRequest->setRequests($appendRequest);
$this->spreadsheetService->spreadsheets->batchUpdate($this->spreadsheetId, $appendEmptyRowBatchUpdateRequest);
}
$this->spreadsheetService->spreadsheets->batchUpdate($this->spreadsheetId, $batchUpdateRequest);
// The actual data values insert
$this->spreadsheetService->spreadsheets_values->update(
$this->spreadsheetId,
$updateRange,
$valueRange,
$conf
);
I hope this may be of some use to someone in future.