Единственный способ сделать это эффективно - это использовать символьный формат CSV или XML (XLSX), потому что они могут быть записаны в вывод строка за строкой , так что вы может каждый раз иметь в памяти только одну строку. Формат двоичный на основе XLS должен быть сначала заполнен полностью в памяти, прежде чем он может быть записан на выход, и это, конечно, перегружает память в случае большого количества записей.
Я бы порекомендовал использовать для этого CSV, поскольку он может быть более эффективным, чем XML, плюс у вас есть преимущество в том, что любой приличный сервер базы данных имеет возможности экспорта для этого, так что вам не нужно программировать / включает что-нибудь новое в Java. Я не знаю, какую БД вы используете, но если бы это было, например, MySQL, то вы могли бы использовать LOAD DATA INFILE
для этого.