Keeping the file structure, like git-archive
git archive takes file paths as arguments, so you could do something like:
git diff --name-status commit1 commit2 | awk '{ if ($1 != "D") print $2 }' | xargs git archive -o output.zip HEAD
UPDATE
The following will work if your file names include spaces:
git diff --name-status commit1 commit2 | awk '{ if ($1 != "D") printf("\"%s\"\n", substr($0,3)) }' | xargs git archive -o output.zip HEAD --
Note: the content of the files included in the archive is what it is at HEAD. To use content from some other commit, just change HEAD at the end of this command to whatever you want it to be.