My solution is technically working, i.e. the file gets downloaded. The problem is that the user does not have an immediate response that the download is going on.
Some investigation showed that without a Content-Length header, internet explorer does not show the save-as dialog immediately; with or without servlet. So, I'm back on trying to show a loading indicator. I can start the loading indicator when the user clicks on the a4j:htmlCommandLink. However, I don't know how to stop it, because with the start of the download, the JSF cycle gets terminated.
Maybe I could start an a4j:poll, which checks on the server if a download-finished flag is set. A bit complicated, though...