$sIn = 'in.xlsx';
$sOut = 'final.zip';
$oZip = new ZipArchive();
$oZip->open($sOut, ZIPARCHIVE::CREATE);
$oZip->setPassword('PASS');
$oZip->addFromString($sIn, file_get_contents($sIn));
$oZip->setEncryptionName($sIn, ZipArchive::EM_AES_256);
$oZip->close();
Т.е. нужно однократно вызвать setPassword, а потом, для каждого файла addFromString и setEncryptionName.
Но на которых хостингах и этот вариант не работает, тогда остаться только:
$sIn = 'in.xlsx';
$sOut = 'final.zip';
echo system('zip -P pass '.$sOut . ' ' . $sIn);